OpenCV | 투시 변환

박나연·2021년 4월 9일
0

OpenCV

목록 보기
25/40
post-custom-banner

투시변환

영상의 기하학적 변환 중 어파인 변환보다 자유도가 높은 투시변환이 있다. 투시변환은 직사각형 형태이 영상을 임의의 볼록 사각형 형태로 변경할 수 있는 변환이다.

OpenCV에서는 투시변환 행렬을 구하는 함수와, 투시변환 행렬을 이용하여 실제 영상을 투시 변환하는 함수를 제공한다.

getPerspectiveTransform()

Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], 
int solveMethod = DECOMP_LU);

src : 입력영상에서 네 점의 좌표
dst : 결과영상에서 네 점의 좌표
solveMethod : 계산 방법 지정
반환값 : 3x3크기의 투시 변환 행렬

warpPerspective()

void warpPerspective(InputArray src, OutputArray dst, 
InputArray M, Size dsize,
int flags = INTER_LINEAR,
int borderMode = BORDER_CONSTANT,
const Scalar& borderValue = Scalar());

src : 입력영상
dst : 결과영상
M : 3x3 투시 변환 행렬
dsize : 결과 영상의 크기
flags : 보간법 알고리즘
borderMode : 가장자리 픽셀 확장 방식
borderValue : borderMode가 BORDER_CONSTANT일 때 상수값

#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;

Mat src;
Point2f srcQuad[4], dstQuad[4];

void on_mouse(int event, int x, int y, int flags, void* userdata);

int main() {
	src = imread("card.bmp");

	if (src.empty()) {
		cerr << "Image load failed!" << endl;
		return -1;
	}
	namedWindow("src");
	setMouseCallback("src", on_mouse);

	imshow("src", src);
	waitKey();

	return 0;
}

void on_mouse(int event, int x, int y, int flags, void*) {
	static int cnt = 0;

	if (event == EVENT_LBUTTONDOWN) {
		if (cnt < 4) {
			srcQuad[cnt++] = Point2f(x, y); // 클릭한 좌표를 src배열에 저장

			circle(src, Point(x, y), 5, Scalar(0, 0, 255), -1); //빨간색 원
			imshow("src", src);

			if (cnt == 4) {
				int w = 200, h = 300;
				dstQuad[0] = Point2f(0, 0); // 결과 영상 좌표
				dstQuad[1] = Point2f(w-1, 0);
				dstQuad[2] = Point2f(w-1, h-1);
				dstQuad[3] = Point2f(0, h-1);

				Mat pers = getPerspectiveTransform(srcQuad, dstQuad);

				Mat dst;
				warpPerspective(src, dst, pers, Size(w, h));

				imshow("dst", dst);
			}
		}
	}
}

profile
Data Science / Computer Vision
post-custom-banner

0개의 댓글