투시 변환 - Perspective transform
어파인 변환보다 자유도가 높은 것이 투시변환이다.
직사각형보다 자유도가 높은 사다리꼴, 임의의 사각형으로 표현할 수 있다.
투시변환을 표현하는 행렬은 3X3 행렬이며, 이 중 하나는 비례상수 역할을 하기 때문에 실제 미지수는 8개가 된다.
투시 변환은 8개 미지수를 계산하기 위해 식 8개가 필요하며, 점 4개가 어떻게 이동했는지 알고 있어야 한다.
✔︎ 투시 변환 행렬 구하기 - cv2.getPerspectiveTransform
retval = cv2.getPerspectiveTransform(src, dst, solveMethod=None)
- src: 4개의 원본 좌표점. numpy.ndarray. shape=(4, 2)
e.g) np.array([[x1 , y1 ], [x2 , y2 ], [x3 , y3 ], [x4 , y4 ]], np.float32) - dst: 4개의 결과 좌표점. numpy.ndarray. shape=(4, 2)
- retval: 3x3 투시 변환 행렬
점 4개의 이동 전, 이동 후 좌표를 입력하면 투시 변환 행렬을 반환하는 함수를 제공한다.
✔︎ 영상의 투시 변환 함수 - cv2.warpPerspective
dst = cv2.warpPerspective(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)
- src: 입력 영상
- M: 3x3 투시 변환 행렬. 실수형.
- dsize: 결과 영상 크기. (w, h) 튜플. (0, 0)이면 src와 같은 크기로 설정
- dst: 출력 영상
- flags: 보간법. 기본값은 cv2.INTER_LINEAR
- borderMode: 가장자리 픽셀 확장 방식. 기본값은 cv2.BORDER_CONSTANT
- borderValue: cv2.BORDER_CONSTANT일 때 사용할 상수 값. 기본값은 0.
💬 실습 - 투시 변환 예제
import sys
import numpy as np
import cv2
src = cv2.imread('card2.png')
if src is None:
print('Image load failed!')
sys.exit()
print(src.shape)
w, h = 1080, 802
srcQuad = np.array([[118, 282], [871, 57], [1001, 490], [247, 700]], np.float32)
dstQuad = np.array([[0, 0], [w-1, 0], [w-1, h-1], [0, h-1]], np.float32)
pers = cv2.getPerspectiveTransform(srcQuad, dstQuad)
dst = cv2.warpPerspective(src, pers, (w, h))
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
⬇︎
'OpenCV' 카테고리의 다른 글
[OpenCV with Python] 영상의 특징 추출 : 영상의 미분과 소벨 필터 (0) | 2022.02.04 |
---|---|
[OpenCV with Python] 영상 기하학적 변환 : 리매핑(remapping) - cv2.remap (0) | 2022.02.02 |
[OpenCV with Python] 영상 기하학적 변환 : 어파인 변환 (0) | 2022.02.02 |
[OpenCV with Python] 영상 기하학적 변환 : 영상의 회전 - cv2.getRotationMatrix2D (0) | 2022.02.02 |
[OpenCV with Python] 영상 기하학적 변환 : 이미지 피라미드 (0) | 2022.02.02 |