logo

신분증 스캔

파일 불러오기 및 전처리

# 이미지 파일 불러오기
image = cv.imread('id_card.png')

# 오츠의 이진화
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
_, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)

신분증 스캔 1: 파일 불러오기 및 전처리 이미지 1

신분증 스캔 1: 파일 불러오기 및 전처리 이미지 2

가장 큰 사각형 찾기

contours, _ = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
biggest_rect = None
for contour in contours:
    epsilon = 0.02 * cv.arcLength(contour, True)
    approx = cv.approxPolyDP(contour, epsilon, True)
    if len(approx) == 4:
        if biggest_rect is None or cv.contourArea(approx) > cv.contourArea(biggest_rect):
            biggest_rect = approx

투시 변환

def order_points(points):
    points = points.reshape(4, 2).astype(np.float32)
    sums = points.sum(axis=1)
    diffs = np.diff(points, axis=1).ravel()
    return np.float32([
        points[np.argmin(sums)],   # 왼쪽 위
        points[np.argmin(diffs)],  # 오른쪽 위
        points[np.argmax(sums)],   # 오른쪽 아래
        points[np.argmax(diffs)],  # 왼쪽 아래
    ])

pts1 = order_points(biggest_rect)
pts2 = np.float32([[0, 0], [400, 0], [400, 200], [0, 200]])
matrix = cv.getPerspectiveTransform(pts1, pts2)
result = cv.warpPerspective(image, matrix, (400, 200))  # 투시 변환

신분증 스캔 3: 투시 변환 이미지 1

Previous
모양 감지