이미지 위에 임의의 4점을 선택하면 그 구역 내 이미지를 원근 변환하는 코드를 작성해보았다. homograpyTransformation 함수를 통해 4점을 입력받으면 calPoint 함수로 상하좌우를 지정해주기 때문에 전처럼 "좌상 → 좌하 → 우상 → 우하" 순으로 점을 찍지 않아도 되며, 변형 후 각 점의 좌표와 원근 변환한 이미지 크기도 같이 계산해준다.
img = cv2.imread('athletic-field-1867053_1920.jpg')
count = 0
blue, green, red, yellow = (255, 0, 0), (0, 255, 0), (0, 0, 255), (0, 255, 255)
point_array = []
def calPoint(ary):
total = np.sum(ary, axis=1)
differ = np.diff(ary, axis=1)
left_top = ary[np.argmin(total)]
left_bottom = ary[np.argmax(differ)]
right_top = ary[np.argmin(differ)]
right_bottom = ary[np.argmax(total)]
src = [left_top, left_bottom, right_top, right_bottom]
src = np.float32(src)
width1 = abs(left_top[0] - right_top[0])
width2 = abs(left_bottom[0] - right_bottom[0])
width = max(width1, width2)
height1 = abs(left_top[1] - left_bottom[1])
height2 = abs(right_top[1] - right_bottom[1])
height = max(height1, height2)
dst = np.float32([[0, 0], [0, height -1], [width -1, 0], [width -1, height -1]])
return (src, dst, width, height)
def homograpyTransformation(event, x, y, flags, param):
global count, point_array
if event == cv2.EVENT_LBUTTONDOWN:
count = count + 1
point_array.append([x, y])
elif event == cv2.EVENT_LBUTTONUP:
if count == 1:
cv2.circle(img, (x, y), 5, blue, -1)
cv2.imshow('Original', img)
elif count == 2:
cv2.circle(img, (x, y), 5, green, -1)
cv2.imshow('Original', img)
elif count == 3:
cv2.circle(img, (x, y), 5, red, -1)
cv2.imshow('Original', img)
elif count == 4:
count = 0
cv2.circle(img, (x, y), 5, yellow, -1)
cv2.imshow('Original', img)
src, dst, width, height = calPoint(point_array)
M = cv2.getPerspectiveTransform(src, dst)
transformImage = cv2.warpPerspective(img, M, (width, height))
cv2.imshow('Transform', transformImage)
cv2.imwrite('Perspective_Transformation.jpg', transformImage)
cv2.namedWindow('Original')
cv2.setMouseCallback('Original', homograpyTransformation, param = img)
while True:
cv2.imshow('Original', img)
if cv2.waitKey(0) & 0xFF:
transformImage = cv2.imread('Perspective_Transformation.jpg')
b, g, r = cv2.split(transformImage)
transformImage = cv2.merge([r, g, b])
plt.imshow(transformImage)
break
cv2.destroyAllWindows()
728x90
반응형
'데이터 분석 & 시각화 > OpenCV' 카테고리의 다른 글
[OpenCV Practice 10 - 2] 이미지 필터링 (Image Filtering & Blurring) (0) | 2020.09.05 |
---|---|
[OpenCV Practice 10 - 1] 이미지 필터링 (Image Filtering & Blurring) (1) | 2020.09.05 |
[OpenCV Practice 09 - 2] 이미지 변형 (Rotation, Affine, Perspective) (2) | 2020.08.29 |
[OpenCV Practice 09 - 1] 이미지 변형 (Scaling, Translation) (0) | 2020.08.29 |
[OpenCV Programming] 디스크립터 2 (0) | 2020.08.28 |
최근댓글