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

[컴퓨터 비전 & 머신러닝] 어파인 변환 2

728x90

2023.05.09 - [러닝머신] - [컴퓨터 비전 & 머신러닝] 어파인 변환 1

 

[컴퓨터 비전 & 머신러닝] 어파인 변환 1

어파인 변환은 영상의 평행 이동, 확대 및 축소, 회전 등의 조합으로 만들 수 있는 기하학적 변환을 나타낸다. 어파인 변환은 모두 여섯 개의 파라미터(a, b, c, d, e, f)를 시용한 수식으로 정의할

zenstudy.tistory.com

 

1에 이어서 더 많은 기하학적 변환을 알아보겠다

 

크기 변환은 영상의 전체적인 크기를 확대 또는 축소하는 변환이다. 

크기변환 resize 함수는 보간법 알고리즘이 필요하다

InterpolationFlags 열거형 상수 설명
INTER_NEAREST 최근방 이웃 보간법
가장 빠르게 동작하지만 결과 영상 화질이 좋지 못함
INTER_LINEAR 양선형 보간법
연산 속도가 빠르고 화질도 충분히 좋은 편
INTER_CUBIC 3차 보간법
양선형 보간법보다 화질 좋음
INTER_AREA 픽셀 영역 리샘플링
무아레 현상이 적게 발생하며 화질면에서 유리
INTER_LANCZ0S4 8x8 이웃 픽셀을 사용하는 란초스 보간법
void affine_scale()
{
	Mat src = imread("rose.bmp");

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

	Mat dst1, dst2, dst3, dst4;
	//src영상을 x방향으로 4배, y방향으로 4배 확대하여 dst1 영상 생성 => 1920x1280, 최근방 이웃 보간법
	resize(src, dst1, Size(), 4, 4, INTER_NEAREST);
	//양선형 보간법
	resize(src, dst2, Size(1920, 1280));
	//3차 회선 보간법
	resize(src, dst3, Size(1920, 1280), 0, 0, INTER_CUBIC);
	//란초스 보간법
	resize(src, dst4, Size(1920, 1280), 0, 0, INTER_LANCZOS4);

	imshow("src", src);
	imshow("dst1", dst1(Rect(400, 500, 400, 400)));
	imshow("dst2", dst2(Rect(400, 500, 400, 400)));
	imshow("dst3", dst3(Rect(400, 500, 400, 400)));
	imshow("dst4", dst4(Rect(400, 500, 400, 400)));

	waitKey();
	destroyAllWindows();
}


회전 변환은 특정 좌표를 기준으로 영상을 원하는 각도만큼 회전하는 변환이다.

 

void affine_rotation()
{
	Mat src = imread("tekapo.bmp");

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

	//영상의 중심 좌표를 가리키는 변수 cp선언
	Point2f cp(src.cols / 2.f, src.rows / 2.f);
	//cp 좌표를 기준으로 반시계 방향으로 20도 회전하는 변환 행렬 M 생성
	Mat M = getRotationMatrix2D(cp, 20, 1);

	Mat dst;
	warpAffine(src, dst, M, Size());

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

	waitKey();
	destroyAllWindows();
}

영상을 90도 단위로 회전하고 싶을 경우에는 rotate() 함수를 사용할 수 있다

rotate(src, dst, ROTATE_90_CLOCKWISE) //시계방향으로 90도 회전

대칭 변환은 영상의 좌우를 서로 바꾸거나, 또는 상하를 뒤집는 형태의 변환이다

 

void affine_flip()
{
	Mat src = imread("eastsea.bmp");

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

	imshow("src", src);

	Mat dst;
	//flip() 함수에 전달한 filpCode 세 개를 정수형 배열에 저장
	int flipCode[] = { 1, 0, -1 };
	for (int i = 0; i < 3; i++) {
		//flipCode 배열에 저장된 정수 값을 이용하여 대칭 변환 수행
		flip(src, dst, flipCode[i]);

		String desc = format("flipCode: %d", flipCode[i]);
		putText(dst, desc, Point(10, 30), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(255, 0, 0), 1, LINE_AA);

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

	destroyAllWindows();
}

flipCode 가 1인 경우는 영상의 좌우가 바뀌었고, 0인 경우는 상하가 바뀌었다

-1인 경우는 좌우와 상하가 모두 바뀌었다

 

728x90