기하학적 변환은 픽셀 변환이 아닌, 픽셀의 배치 구조를 변환 시키는 작업으로 전처리, 영상 정합(image registration) 왜곡제거등에 사용된다

하기는 기하학적 변환의 종류로 이동변환과 전단변환이 있다.

 

TC1 : 이동변환(translation transform)

어파인변환행렬은 이동변환을 표현한다.

이동변환

 

TC2: 전단 변환(shear_transform)

가로방향전단변환

 

 

세로방향전단변환

 

#include <iostream>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;
#define TC 1

void translation_transform(Mat src, Mat &dst) {
	/*이동변환 표현*/
	for (int y = 0; y < src.rows; ++y) {
		for (int x = 0; x < src.cols; ++x) {
			int x_ = x + 200;  // 가로 200
			int y_ = y + 100;  // 세로 100   offset 줘서 원점으로 만듦.
			if (x_ < 0 || y_ < 0 || x_ >= dst.cols || y_ >= dst.rows)continue; // width, heigh  범위 넘어가는 경우를 방지.
			dst.at<uchar>(y_, x_) = src.at<uchar>(y, x);

		}
	}
}

void shear_transform(Mat src, Mat& dst) {
	// 영상의 전단 변환(shear transformation):  직사각형 형태의 영상을 한쪽 방향으로 밀어서 평행사변형 모양으로 변환시킴. (==층밀림 변환).
	// 가로 방향 또는 세로 방향으로 따로 정의  됨.
	double m = 0.5;
	for (int y = 0; y < src.rows; y++) {
		for (int x = 0; x < src.cols; x++) {

			//x축 방향, 가로방향으로 전단변환
			//int nx = int(x + (m * y)); // 출력영상 좌표 설정.  원 x좌표에 0.5 를 곱한 y좌표 ㅍ값을 더함.
			//int ny = y;

			//y축방향, 세로방향으로 전단 변환
			int nx = x;
			int ny = int(y + (m * x));
			dst.at<uchar>(ny, nx) = src.at<uchar>(y, x);   
 		} 
	}
}
int main()
{
	
	Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);

	if (src.empty()) {
		cerr << "Image laod failed!" << endl;
		return -1;
	}

#if TC == 1
	Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC1); // src와 동일한 행렬(0으로 채워짐),
	translation_transform(src, dst);

#elif TC == 2
	//x축 방향, 가로방향으로 전단변환
	//Mat dst(src.rows, src.cols * 3 / 2, src.type(), Scalar(0));  // 특이사항: 가로크기를 입력영상의 1.5 배로 설정.

    //y축방향, 세로방향으로 전단 변환
	Mat dst(src.rows * 3 / 2, src.cols, src.type(), Scalar(0)); //특이사항: 세로크기를 입력영상의 1.5 배로 설정.
	shear_transform(src, dst);
#endif
	
	imshow("src", src);
	imshow("dst", dst);
	waitKey();
}

+ Recent posts