반응형
● 목적:
- 이 과제에서는 자동차 번호판을 정상의 형태로 변형하여 보여준다.
● 기타:
- 주요한 과정에 대하여 opencv, numpy 등 package 함수를 사용해도 무방합니다.
- 필요한 경우 각 단계에서 *적절한* 최적화 가 필요합니다. 여러분의 최적화 노력을 PPT에 간략하게 설명하기 바랍니다.
- 기타 세부적인 사항은 합리적으로 가정하시기 바랍니다.
- 영상에 대하여 적절한 해상도를 선택하세요. 고해상도일수록 처리 속도가 느려집니다.
- 이 프로그램은 여러분이 최적화한 파라미터값으로 진행되는 것을 원칙으로 합니다.
● 과제의 내용
1. 아래 그림과 같이 첨부된 자동차 번호판 이미지(영상 A)를 정상의 상태(영상 B)로 변환하여 디스플레이하는 프로그램을 작성하라.
A. 프로그램에서 주요 단계를 차례대로 보여 줄 것.
2. 아래 단계에 대한 결과를 PPT에 포함할 것.
A. 실제 자동차 번호판의 비율을 측정하고 이 비율을 이용하여 적절한 크기의 Template 를 만든다. Template 의 적절한 크기(가로 세로 픽셀 수)를 정한다. Template 는 실제 영상일 필요는 없고 가상적인 직사각형이다.
B. 자동차 번호판영상과 template 에서 네 개의 매칭 포인트 쌍을 구하라.
C. 자동차 번호판 → template 로 변환하는 투영행렬은 무엇인가?
D. 이 투영행렬은 전방향, 역방향 중 어떤 매핑인가?
과제내용
Code
# mouse_handler.py
import cv2
import numpy as np
img_path = 'car_number.jpg'
ori_img = cv2.imread(img_path)
src = [] # 왼쪽위, 오른쪽위, 오른쪽아래, 왼쪽아래 순으로 각 점의 좌표
# mouse callback handler
def mouse_handler(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONUP: # 마우스가 좌클릭을 했을때 (4번의 클릭으로 좌표 얻기)
img = ori_img.copy()
src.append([x, y])
for xx, yy in src: # 클릭한 곳에 점 그리기
cv2.circle(img, center=(xx, yy), radius=5, color=(0, 255, 0), thickness=-1)
cv2.imshow('Original Image - Car', img)
# perspective transform
if len(src) == 4:
src_np = np.array(src, dtype=np.float32)
print("original points : \n", src_np)
cv2.namedWindow('Original Image - Car')
cv2.setMouseCallback('Original Image - Car', mouse_handler) # 마우스 이벤트 전달
cv2.imshow('Original Image - Car', ori_img)
if cv2.waitKey(0) == 32:
cv2.destroyAllWindows()
# car.py
import cv2
import numpy as np
import keyboard
img_path = 'car_number.jpg'
ori_img = cv2.imread(img_path)
src = [] # 왼쪽위, 오른쪽위, 오른쪽아래, 왼쪽아래 순으로 각 점의 좌표
src.append([126, 218])
src.append([343, 266])
src.append([340, 345])
src.append([121, 283])
# 32비트로 바꿔줌
src_np = np.array(src, dtype=np.float32)
# width ,height 길이 계산
width = max(np.linalg.norm(src_np[0] - src_np[1]), np.linalg.norm(src_np[2] - src_np[3]))
height = max(np.linalg.norm(src_np[0] - src_np[3]), np.linalg.norm(src_np[1] - src_np[2]))
# width, height 비율
width_ratio = (width / height)
height_ratio = 1
# 비율 * 300 으로 픽셀 크기 맞춤
dst_np = np.array([[0, 0],
[int(width_ratio * 300), 0],
[int(width_ratio * 300), int(height_ratio * 300)],
[0, int(height_ratio * 300)]
], dtype=np.float32)
M = cv2.getPerspectiveTransform(src=src_np, dst=dst_np)
result = cv2.warpPerspective(ori_img, M=M, dsize=(int(width_ratio * 300), height_ratio * 300))
#print("Perspective Transformation :\n", M)
cv2.imshow('img', ori_img)
print("스페이스바를 누르면 번호판의 4개 매칭점이 구해집니다.")
if cv2.waitKey(0) == ord(' '):
for xx, yy in src:
cv2.circle(ori_img, center=(xx, yy), radius=5, color=(0, 255, 0), thickness=-1, lineType=cv2.LINE_AA)
cv2.imshow('img', ori_img)
print("original points : \n", src_np)
if cv2.waitKey(0) == ord(' '):
cv2.imshow('result', result)
print("\ndestination points : \n", dst_np)
if cv2.waitKey(0) == ord(' '):
cv2.destroyAllWindows()
점수 10/10
❤와 댓글은 큰 힘이 됩니다. 감사합니다 :-)
반응형
'Schoolwork > 컴퓨터그래픽스 및 비젼' 카테고리의 다른 글
[Python] 09주차 과제 - 영역 검출을 위한 영상 전처리 (명함 인식) (5) | 2020.09.05 |
---|---|
[Python] 07주차 과제 - 번호 인식을 위한 전처리(이진화) (0) | 2020.09.05 |
[Python] 05주차 과제 - Canny Edge 검출 (9) | 2020.09.05 |
[Python] 04주차 과제 - 웹캠영상에서 얼굴 검출 (0) | 2020.09.05 |
[Python] 03주차 과제 - 히스토그램 역투영과 오츄의 이진화를 이용한 얼굴 검출 (0) | 2020.09.05 |