[ch07] 이진 영상 처리 - 실전 코딩 : 명함 인식 프로그램

빨주노·2021년 8월 28일
0

명함 인식 프로그램

  • 영상에서 명함을 검출하고, 명함 안의 텍스트를 인식하는 프로그램
  • 가정 : 명함은 흰색이고, 충분히 크게 촬영되었고, 각진 사각형 모양이다.

명함 검출

  • Otsu 자동 이진화
  • 외곽선 검출 → 근사화 → 사각형 검출
  • 명함의 네 모서리 점을 직사각형 네 모서리로 매핑
    • 좌측 상단 모서리점부터 반시계방향으로 검출 및 매핑
  • 일반적인 명함의 가로:세로 비율 = 9:4

명함 텍스트 인식

  • Tesseract 라이브러리 사용
  • 한글과 영문 인식

Tesseract

  • 광학 문자 인식(OCR) 라이브러리
  • 1985년 ~ 1994년 휴렛 팩커드(Hewlett-Packard)에서 개발 → 2005년 오픈 소스 → 2006년부터 구글(google)에서 관리
  • 2018년 4.0이 발표되면서 LSTM(Long Short-Term Memory) 기반 OCR 엔진 및 모델이 추가
  • 100개 이상의 언어 데이터 제공
  • Apache License v2.0

설치 방법은 생략

OpenCV/numpy 사용하기

  • pytesseract는 numpy.ndarray를 지원
  • pytesseract.image_to_string() 함수 사용
  • 영상 데이터를 그레이스케일 또는 RGB 색 순서로 변경하여 지정
img = cv2.imread('digits.jpg')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print(pytesseract.image_to_string(img_gray))

실습 코드

def reorderPts(pts): # 꼭지점 순서 정렬
    idx = np.lexsort((pts[:, 1], pts[:, 0]))  # 칼럼0 -> 칼럼1 순으로 정렬한 인덱스를 반환
    pts = pts[idx]  # x좌표로 정렬
    
    if pts[0, 1] > pts[1, 1]:
        pts[[0, 1]] = pts[[1, 0]] # 스와핑

    if pts[2, 1] < pts[3, 1]:
        pts[[2, 3]] = pts[[3, 2]] # 스와핑

    return pts

# 영상 불러오기
filename = 'namecard2.jpg'
if len(sys.argv) > 1:
    filename = sys.argv[1]

src = cv2.imread(filename)

# 출력 영상 설정
dw, dh = 720, 400
srcQuad = np.array([[0, 0], [0, 0], [0, 0], [0, 0]], np.float32)
dstQuad = np.array([[0, 0], [0, dh], [dw, dh], [dw, 0]], np.float32)
dst = np.zeros((dh, dw), np.uint8)

# 입력 영상 전처리
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
_, src_bin = cv2.threshold(src_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

# 외곽선 검출 및 명함 검출
contours, _ = cv2.findContours(src_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

cpy = src.copy()
for pts in contours:
    # 너무 작은 객체는 무시
    if cv2.contourArea(pts) < 1000:
        continue

    # 외곽선 근사화
    approx = cv2.approxPolyDP(pts, cv2.arcLength(pts, True)*0.02, True)

    # 컨벡스가 아니고, 사각형이 아니면 무시
    if not cv2.isContourConvex(approx) or len(approx) != 4:
        continue

    cv2.polylines(cpy, [approx], True, (0, 255, 0), 2, cv2.LINE_AA)
    srcQuad = reorderPts(approx.reshape(4, 2).astype(np.float32))

pers = cv2.getPerspectiveTransform(srcQuad, dstQuad)
dst = cv2.warpPerspective(src, pers, (dw, dh))

dst_gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)
print(pytesseract.image_to_string(dst_gray, lang='Hangul+eng'))
profile
딥 하게 딥러닝 하는중

0개의 댓글