2021년도 1학기 기계학습기반 영상처리 12주차 출석용 과제물입니다.
핵심기능은 원근투영행렬추출로 번호판 영역 추출입니다.

코드

"""
제   목 : 기계학습기반영상처리 12주차 출석용 과제물
기   능 : 원근투영행렬 추출로 번호판 영역 추출하기
파일이름 : 기계학습기반 영상처리_12주차출석용과제물_201622821_김영진
수정날짜 : 2021-06-06
작 성 자 :소프트웨어미디어융합전공 4학년 201622821 김영진
"""

import numpy as np, cv2

def contain_pts(p, p1, p2):
    return p1[0] <= p[0] < p2[0] and p1[1] <= p[1] < p2[1]

def draw_rect(img):
    rois = [(p - small, small * 2) for p in pts1]
    for (x, y), (w, h) in np.int32(rois):
        roi = img[y:y + h, x:x + w] # 좌표 사각형 범위 가져오기
        val = np.full(roi.shape, 80, np.uint8) # 컬러(3차원) 행렬 생성		
		cv2.add(roi, val, roi) # 관심영역 밝기 증가        
        cv2.rectangle(img, (x, y, w, h), (0, 255, 0), 1)
    cv2.polylines(img, [pts1.astype(int)], True, (0, 255, 0), 1) # pts는 numpy 배열
    cv2.imshow("select rect", img)

def warp(img):
    perspect_mat = cv2.getPerspectiveTransform(pts1, pts2)
    dst = cv2.warpPerspective(img, perspect_mat, (350, 400), cv2.INTER_CUBIC)
    cv2.imshow("License plate", dst)
    cv2.imwrite("images/morph.jpg", dst)

def morrrph():
    image = cv2.imread("images/morph.jpg", cv2.IMREAD_GRAYSCALE)
    if image is None: raise Exception("영상파일 읽기 오류")
    mask = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]).astype("uint8")
    th_img = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)[1]

    dst = cv2.morphologyEx(th_img, cv2.MORPH_CLOSE, mask, 1)
    dst = cv2.morphologyEx(th_img, cv2.MORPH_OPEN, mask)

    cv2.imshow("morph", dst)

def onMouse(event, x, y, flags, param):
    global check
    if event == cv2.EVENT_LBUTTONDOWN:
        for i, p in enumerate(pts1):
            p1, p2 = p - small, p + small  # p점에서 우상단, 좌하단 좌표생성
            if contain_pts((x, y), p1, p2): check = i

    if event == cv2.EVENT_LBUTTONUP: check = -1  # 좌표 번호 초기화
    if event == cv2.EVENT_RBUTTONDOWN: morrrph()
    if check >= 0:  # 좌표 사각형 선택 시
        pts1[check] = (x, y)
        draw_rect(np.copy(image))
        warp(np.copy(image))

image = cv2.imread('images/Test.jpg')
if image is None: raise Exception("영상 파일을 읽기 에러")

small = np.array((12, 12))  # 좌표 사각형 크기
check = -1  # 선택 좌표 사각형 번호 초기화
pts1 = np.float32([(100, 100), (300, 100), (300, 300), (100, 300)])
pts2 = np.float32([(0, 0), (400, 0), (400, 350), (0, 350)])  # 목적 영상 4개 좌표

draw_rect(np.copy(image))
cv2.setMouseCallback("select rect", onMouse, 0)
cv2.waitKey(0)

실행결과

원근투영행렬

댓글남기기