삐뚤어진 명함 사진을 정렬해주는 함수
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
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()