3강 OpenCV 명함 검출 및 인식-1

양말신은도비·2022년 7월 2일
1

명함 검출과 인식

일반적인 명함의 조건

  • 흰색 배경에 검정색 글씨이다.
  • 충분히 크게 촬영된다.
  • 각진 사각형 모양이다.

예제 이미지.

namecard1

namecard1

namecard2

namecard2

namecard3

namecard3

순서대로 namecard1, namecard2, namecard3이다.

1과 2의 차이는 2가 좀 더 밝다는 것이다.

명함 검출 및 인식 진행 과정

  1. 사진 입력
  2. 사진 이진화
  3. 외곽선 검출 & 다각형 근사화
  4. 투영변환
  5. OCR

이진화란?

영상의 픽셀 값을 0 또는 1(255)로 만드는 연상

  • 그레이스케일 영상의 이진화 ⇒ T = 임계값, threshold
    g(x,y)={0if f(x,y)T255if f(x,y)>Tg(x,y) = \begin{cases} 0\qquad if \ f(x,y) \leq T \\ 255 \quad if \ f(x,y) > T \end{cases}

  • 이진화 함수

    cv2.threshold(src, thresh, maxval, type, dst=None) -> retval, dst(2개의 return)
    • src: 입력 영상. (다채널, 8비트 또는 32비트 실수형)
    • thresh: 임계값
    • maxval: THRESH_BINARY 또는 THRESH_BINARY_INV 방법을
      사용할 때의 최댓값 지정
    • type: 임계값에 의한 변환 함수 지정 또는 자동 임계값 설정 방법
      지정 (cv.ThresholdTypes)
    • retval: 사용된 임계값
    • dst: (출력) 입계값 영상 (src와 동일 크기, 동일 타입)
  • 임계값 결정

  • 자동 임계값 결정 ⇒ Otsu!!
    • 입력 영상이 배경(background)과 객체(object) 두 개로 구성되어 있다고
      가정 → bimodal histogram
    • 두 픽셀 분포의 분산의 합이 최소가 되는 임계값을 선택
      (Minimize within-class variance)
    • 효과적인 수식 전개와 재귀식을 이용하여 빠르게 임계값을 결정

실습

  • namecard1
    import sys
    import cv2
    
    src = cv2.imread('namecard1.jpg')
    
    if src is None:
        print('image load failed')
        sys.exit()
    
    src = cv2.resize(src, (640, 480))
    # 비율로 지정하기
    #src = cv2.resize(src, (0, 0), fx=0.5, fy=0.5)
    
    # 흑백흑백
    src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    
    # 이진화 => 임계값 함수, 임계값을 지정해줬으니 따로 받을 필요없어서 공백
    _, src_bin = cv2.threshold(src_gray, 130, 255, cv2.THRESH_BINARY)
    
    cv2.imshow('src',src)
    cv2.imshow('src_gray',src_gray)
    cv2.imshow('src_bin',src_bin)
    cv2.waitKey()
    cv2.destroyAllWindows()
  • 결과 원본 원본 그레이스케일 그레이스케일 이진화 이진화
  • namecard2
    import sys
    import cv2
    
    src = cv2.imread('namecard2.jpg')
    
    if src is None:
        print('image load failed')
        sys.exit()
    
    src = cv2.resize(src, (640, 480))
    #src = cv2.resize(src, (0, 0), fx=0.5, fy=0.5)
    
    # 흑백흑백
    src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    
    # 이진화 => 임계값 함수
    _, src_bin = cv2.threshold(src_gray, 130, 255, cv2.THRESH_BINARY)
    
    cv2.imshow('src',src)
    cv2.imshow('src_gray',src_gray)
    cv2.imshow('src_bin',src_bin)
    cv2.waitKey()
    cv2.destroyAllWindows()
  • 결과 https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f38e1a94-a21d-4d13-8ad8-0f387cdb6e90/Untitled.png https://s3-us-west-2.amazonaws.com/secure.notion-static.com/97efa930-f60a-4fba-ad17-17bf469ed028/Untitled.png https://s3-us-west-2.amazonaws.com/secure.notion-static.com/dbe8978f-8548-46e3-918a-65607a380f7f/Untitled.png 아까와 다르게 이진화가 잘 안되는 것을 볼 수 있다.
  • namecard2 ⇒ otsu
    import sys
    import cv2
    
    src = cv2.imread('namecard2.jpg')
    
    if src is None:
        print('image load failed')
        sys.exit()
    
    src = cv2.resize(src, (640, 480))
    #src = cv2.resize(src, (0, 0), fx=0.5, fy=0.5)
    
    # 흑백흑백
    src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    
    # 이진화 => 임계값 함수 => otsu를 쓰니 알아서 하라고 0을 줌.
    _, src_bin = cv2.threshold(src_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    
    cv2.imshow('src',src)
    cv2.imshow('src_gray',src_gray)
    cv2.imshow('src_bin',src_bin)
    cv2.waitKey()
    cv2.destroyAllWindows()
  • 결과 https://s3-us-west-2.amazonaws.com/secure.notion-static.com/063c9d1b-3f81-40cd-935c-e02912bad4df/Untitled.png https://s3-us-west-2.amazonaws.com/secure.notion-static.com/001b2bc6-f0b1-4dfb-bbd4-bf2d29d978d3/Untitled.png https://s3-us-west-2.amazonaws.com/secure.notion-static.com/40a9bbd0-9ebd-42f2-bac8-c5ce0f16d331/Untitled.png
  • namecard3
    import sys
    import cv2
    
    src = cv2.imread('namecard3.jpg')
    
    if src is None:
        print('image load failed')
        sys.exit()
    
    src = cv2.resize(src, (640, 480))
    #src = cv2.resize(src, (0, 0), fx=0.5, fy=0.5)
    
    # 흑백흑백
    src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    
    # 이진화 => 임계값 함수 => otsu를 쓰니 알아서 하라고 0을 줌.
    _, src_bin = cv2.threshold(src_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    
    cv2.imshow('src',src)
    cv2.imshow('src_gray',src_gray)
    cv2.imshow('src_bin',src_bin)
    cv2.waitKey()
    cv2.destroyAllWindows()
  • 결과

0개의 댓글