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

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

Tesseract ⇒[깃허브]

  • 광학 문자 인식(OCR) 라이브러리
  • 1985~1994년 사이에 휴렛 팩커드에서 개발 ⇒ 2005년 오프소스 ⇒ 2006년부터 구글에서 관리
  • 2018에 4.0으로 업데이트 되면서 LSTM기반 OCR엔진 및 모델이 추가
  • 총 116개의 언어가 제공
  • Apache 라이선스

reorderPts 함수

삐뚤어진 명함 사진을 정렬해주는 함수

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

실습

  • 코드
    • 임포트
      import sys
      import numpy as np
      import cv2
      import pytesseract
    • reorderPts 함수
      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 = 'namecard1.jpg'
      # if len(sys.argv) > 1:
      #     filename = sys.argv[1]
      
      src = cv2.imread('namecard3.jpg')
      # src = cv2.resize(src, (640, 480))
      if src is None:
          print('Image load failed!')
          sys.exit()
    • 출력 영상 설정 및 입력영상 전처리
      # 출력 영상 설정
      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)
      th, 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)
      
      for pts in contours:
          # 너무 작은 객체는 제외
          if cv2.contourArea(pts) < 10:
              continue
      
          # 외곽선 근사화
          approx = cv2.approxPolyDP(pts, cv2.arcLength(pts, True)*0.02, True)
      
          # 컨벡스가 아니면 제외
          if not cv2.isContourConvex(approx) or len(approx) != 4:
              continue
      
          cv2.polylines(src, [approx], True, (0, 255, 0), 2, cv2.LINE_AA)
          srcQuad = reorderPts(approx.reshape(4, 2).astype(np.float32))
      
          pers = cv2.getPerspectiveTransform(srcQuad, dstQuad)
          # cv2.INTER_CUBIC => 화질을 좀 더 좋게..
          dst = cv2.warpPerspective(src, pers, (dw, dh), flags=cv2.INTER_CUBIC)
      
          dst_rgb = cv2.cvtColor(dst, cv2.COLOR_BGR2RGB)
          print(pytesseract.image_to_string(dst_rgb, lang='Hangul+eng'))
    • 출력
      cv2.imshow('src', src)
      cv2.imshow('src_gray', src_gray)
      cv2.imshow('src_bin', src_bin)
      cv2.imshow('dst', dst)
      cv2.waitKey()
      cv2.destroyAllWindows()
  • 결과



0개의 댓글