본문 바로가기

8. OpenCV | CV

7/31(월) IT K-DT(101일차) / 27.OCR~28.테서렉트

 

1. OCR(Optical Character Recognition)

광학문자인식. 이미지나 문서에서 텍스트를 자동으로 인식하고 컴퓨터가 이해할 수 있는 텍스트 데이터로 변환하는 프로세스. 사진, 스캔, 스마트폰 카메라로 찍은 이미지 등 다양한 형식의 입력에서 문자를 식별하고 추출하여 편리한 텍스트 데이터로 변환할 수 있음.

 

2. 테서렉트(Tesseract)

오픈 소스 기반의 광학 문자 인식(OCR) 엔진. 처음에는 Hewlett-Packard 사에서 개발되었으며, 현재는 Google이 주도하고 관리하고 있음. 다양한 언어의 인쇄된 텍스트를 이미지나 스캔한 문서에서 자동으로 감지하고 추출하여 컴퓨터가 이해할 수 있는 텍스트 데이터로 변환하는 데 사용하는 라이브러리. 다양한 플랫폼에서 동작하며, 텍스트 인식의 정확도와 성능을 높이기 위해 머신러닝과 딥러닝 기술을 활용함. 

 

링크: https://github.com/UB-Mannheim/tesseract/wiki

 

Home

Tesseract Open Source OCR Engine (main repository) - UB-Mannheim/tesseract

github.com

 

설치:
링크에서 tesseract-ocr-w64-setup-5.3.1.20230401.exe (64 bit)를 다운로드 (2023-07-31기준)
Choose Components에서 Additional script data(download) 트리를 내림

→ Hangul script, Hangul vertical script 체크
Additional Language data(download) 트리를 내림 Korean 체크
→ C:\Program Files\Tesseract-OCR에 설치
 환경설정 지정(환경변수 설정)
     (윈도우 탐색기내PC속성고급시스템설정환경변수시스템변수에서 Path를 클릭 후 편집

       →새로만들기 후 위의 경로 붙여넣기로 추가)

 

 

import pytesseract
import cv2

img = cv2.imread('./hello.png')
dst = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
text = pytesseract.image_to_string(dst, lang='kor+eng') # 이미지를 영어, 한글의 문자로 인식
print(text)

 

 

임의의 명함을 확인하여 OCR 라이브러리를 이용해 출력하는 예제

 

import cv2
import pytesseract
import numpy as np

'''
첫번째 y좌표 : 사각형의 왼쪽 상단 꼭지점
두번째 y좌표 : 사각형의 왼쪽 하단 꼭지점
세번째 y좌표 : 사각형의 오른쪽 상단 꼭지점
네번째 y좌표 : 사각형의 오른쪽 하단 꼭지점
'''

def reorderPts(pts):  # '사각형의 x와 y의 좌표를 다시 재조정해주는 함수' 생성.
    idx = np.lexsort((pts[:, 1], pts[:, 0]))  # y좌표 기준으로 우선정렬 후 x좌표 정렬.
    # lexsort(): 배열을 정렬하는 함수.
    pts = pts[idx]
    if pts[0, 1] > pts[1, 1]: # 만약 첫번째 y좌표가 두번째 y좌표보다 크다면
        pts[[0, 1]] = pts[[1, 0]] # 두 점의 위치를 바꿔줌
    if pts[2, 1] < pts[3, 1]: # 만약 세번째 y좌표가 네번째 y좌표보다 작다면
        pts[[2, 3]] = pts[[3, 2]] # 두 점의 위치를 바꿔줌
    print(pts)
    return pts

 

src = cv2.imread('./namecard.jpg') # 명함을 불러들임
dw, dh = 700, 400 # 불러들인 명함의 width와 height를 재정의. (700 * 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: # 윤곽의 면적이 1000보다 작으면 무시.
        continue
    approx = cv2.approxPolyDP(pts, cv2.arcLength(pts, True) * 0.02, True) # 윤곽의 근사화.
    print(approx)
    
    '''
    출력값
    [[[903 199]]
     [[179 200]]
     [[159 593]]
     [[938 581]]]
    '''
    
    if not cv2.isContourConvex(approx) or len(approx) != 4:  
        continue # 근사화된 윤곽이 볼록 다각형이 아니거나 꼭지점이 4가 아니라면 무시.
    cv2.polylines(cpy, [approx], True, (0, 255, 0), 2)     # line 지정으로 윤곽의 시각적 확인.
    print(approx.reshape(4, 2).astype(np.float32))
    
    '''
    출력값
    [[903. 199.]
     [179. 200.]
     [159. 593.]
     [938. 581.]]
    '''
    
    srcQuad = reorderPts(approx.reshape(4, 2).astype(np.float32))  
    # reorderPts함수 사용. reshape를 통해 꼭지점을 재조정.

 

cv2.imshow('src', src)
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='kor+eng'))
cv2.imshow('dst', dst)
cv2.waitKey()