영상의 기하학적 변환(Geometric transformation)

  • 영상을 구성하는 픽셀의 배치 구조를 변경함으로써 전체 영상의 모양을 바꾸는 작업
  • 픽셀의 값은 그대로 유지가 되는데 픽셀이 있는 위치를 변경 시키는 작업
  • 전처리 작업, 영상 정합(image registaration), 왜곡 제거
    • 영상의 크기를 시스템이 원하는 특정 크기로 조절
    • 문자 인식 시스템에서 입력되는 영상 수평 맞추기
    • 2장의 영상의 크기와 모양이 다를 경우 그 안에서 같은 객체 찾기
    • 카메라 렌즈에 의해 발생하는 왜곡 제거
  • 기하학적 변환의 종류

image

이동 변환(translation transform, shfit)

  • 가로 또는 세로 방향으로 영상을 특정 크기만큼 이동시키는 변환
  • x축과 y축 방향으로의 이동 변위를 지정

image

  • 그레이스케일 영상을 (100, 100) 이동 변환
    • 이중 for 루프를 이용하여 직접 구현
#include <iostream>
#include "opencv2/opencv.hpp"

using namespace std;
using namespace cv;

int main()
{
	Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);

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

	// Mat dst = Mat::zeros(src.size(), CV_8UC1);
	Mat dst = Mat::zeros(src.rows, src.cols, CV_8UC1);

	for (int y = 0; y < src.rows; y++) {
		for (int x = 0; x < src.cols; x++) {
			int x_ = x + 200;
			int y_ = y + 100;
			if (x_ < 0 || x_ >= dst.cols) continue;
			if (y_ < 0 || y_ >= dst.rows) continue;
			dst.at<uchar>(y_, x_) = src.at<uchar>(y, x);
		}
	}
	imshow("src", src);
	imshow("dst", dst);
	waitKey();
}

image

영상의 전단 변환(shear transformation)

  • 직사각형 형태의 영상을 한쪽 방향으로 밀어서 평행사변형 모양으로 변형되는 변환으로 층밀림 변환이라고 부름
  • 가로 방향 또는 세로 방향으로 따로 정의됨

image

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

using namespace std;
using namespace cv;

int main()
{
	Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);

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

	Mat dst(src.rows * 3 / 2, src.cols, src.type(), Scalar(0)); // 모든 픽셀의 초기 값을 0을 갖도록 설정함
	// 크기를 입력 영상의 세로 크기의 1.5배, 가로 크기는 동일하게 함

	double m = 0.5;
	for (int y = 0; y < src.rows; y++) {
		for (int x = 0; x < src.cols; x++) {
			int nx = x;
			int ny = int(y + m*x);
			dst.at<uchar>(ny, nx) = src.at<uchar>(y, x);
		}
	}

	imshow("src", src);
	imshow("dst", dst);

	waitKey();
}

image