기하학적 변환은 픽셀 변환이 아닌, 픽셀의 배치 구조를 변환 시키는 작업으로 전처리, 영상 정합(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();
}
'프로그래머스 > OPENCV' 카테고리의 다른 글
회전변환과 기하학적 변환의 조합 [다시] (0) | 2022.12.05 |
---|---|
영상의 크기 변환 (scale transform == resize) 과 보간법 [ 다시] (0) | 2022.12.05 |
1주차 과제) 히스토그램 개선해서 명암비가 좋은 결과 이미지 만들기 (0) | 2022.12.03 |
잡음제거 필터 (GaussianBlur vs BilateralFilter) (0) | 2022.12.02 |
블러링 (0) | 2022.12.02 |