본문 바로가기
런닝머신 (ML)

[컴퓨터 비전 & 머신러닝] 투시 변환

728x90

투시 변환은 직사각형 형태의 영상을 임의로 볼록 사각형 형태로 변경할 수 있는 변환이다. 투시 변환에 의해 원본 영상에 있던 직선은 결과 영상에서 그대로 직선성이 유지되지만, 두 직선의 평행 관계는 깨어질 수 있다.

 

예제를 통해 getPerspectiveTransform() 함수와 warpPerspective() 함수를 알아보겠다

Mat src;
Point2f srcPts[4], dstPts[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(0);

	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) {
			//마우스 버튼 누른 곳 배열에 순서대로 저장
			srcPts[cnt++] = Point2f(x, y);

			//왼쪽 버튼 누른 곳에 반지름이 5인 빨간색 원 표시
			circle(src, Point(x, y), 5, Scalar(0, 0, 255), -1);
			imshow("src", src);

			//4개의 점 다 찍었으면 화면에 표시
			if (cnt == 4) {
				int w = 200, h = 300;

				dstPts[0] = Point2f(0, 0);
				dstPts[1] = Point2f(w - 1, 0);
				dstPts[2] = Point2f(w - 1, h - 1);
				dstPts[3] = Point2f(0, h - 1);

				//좌표 4개를 저장한 배열을 입력받아 결과 영상 4개의 좌표에 옮김
				Mat pers = getPerspectiveTransform(srcPts, dstPts);

				Mat dst;
				//영상을 투시 변환한 결과 영상 생성
				warpPerspective(src, dst, pers, Size(w, h));

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

728x90