8장 영상의 기하학적 변환
8.1 어파인 변환
영상의 평행 이동, 확대 및 축소, 회전 등의 조합으로 만들 수 있는 기하학적 변환
8.1.1 어파인 변환
영상의 기하학적 변환은 영상을 구성하는 픽셀의 배치 구조를 변경함으로써 전체 영상의 모양을 바꾸는 작업
픽셀 값은 그대로 유지하면서 위치를 변경하는 작업
void affine_transform()
{
Mat src = imread("tekapo.bmp");
if (src.empty())
{
return;
}
Point2f srcPts[3], dstPts[3];
srcPts[0] = Point2f(0, 0);
srcPts[1] = Point2f(src.cols - 1, 0);
srcPts[2] = Point2f(src.cols - 1, src.rows - 1);
dstPts[0] = Point2f(50, 50);
dstPts[1] = Point2f(src.cols - 100, 100);
dstPts[2] = Point2f(src.cols - 50, src.rows - 50);
Mat M = getAffineTransform(srcPts, dstPts);
Mat dst;
warpAffine(src, dst, M, Size());
imshow("src", src);
imshow("dst", dst);
waitKey();
destroyAllWindows();
}
8.1.2 이동 변환
영상을 가로 또는 세로 방향으로 일정 크기만큼 이동시키는 연산을 의미하며 시프트 연산이라고도 함
void affine_translation()
{
Mat src = imread("tekapo.bmp");
if (src.empty())
{
return;
}
Mat M = Mat_<double>({ 2,3 }, { 1,0,150,0,1,100 });
Mat dst;
warpAffine(src, dst, M, Size());
imshow("src", src);
imshow("dst", dst);
waitKey();
destroyAllWindows();
}
8.1.3 전단 변환
직사각형 형태의 영상을 한쪽 방향으로 밀어서 평행사변형 모양으로 변형되는 변환이며 층밀림 변환이라고도 함
void affine_shear()
{
Mat src = imread("tekapo.bmp");
if (src.empty())
{
return;
}
double mx = 0.3;
Mat M = Mat_<double>({ 2,3 }, { 1,mx,0,0,1,0 });
Mat dst;
warpAffine(src, dst, M, Size(cvRound(src.cols + src.rows * mx), src.rows));
imshow("src", src);
imshow("dst", dst);
waitKey();
destroyAllWindows();
}
8.1.4 크기 변환
영상의 전체적인 크기를 확대 또는 축소하는 변환
void affine_scale()
{
Mat src = imread("rose.bmp");
if (src.empty())
{
return;
}
Mat dst1, dst2, dst3, dst4;
resize(src, dst1, Size(), 4, 4, INTER_NEAREST);
resize(src, dst2, Size(1920, 1280));
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();
}
dst1 영상 : 최근방 이웃 보간법을 사용한 결과로 픽셀 자체가 커진 것처럼 보이고 장미꽃 경계선이 매우 거친 느낌
dst2 영상 : 양선형 보간법을 사용한 확대 결과이며 최근방 이웃 보간법에 비해 경계면이 부드럽게 확대되어 화칠이 좋아짐
dst3 영상 : 3차 보간법을 사용하여 미세하게 좋아보이지만 연산 속도 면에서는 느림
dst4 영상 : 란초스 보간법을 사용하여 미세하게 좋아보이지만 연산 속도 면에서는 느림
8.1.5 회전 변환
특정 좌표를 기준으로 영상을 원하는 각도만큼 회전하는 변환
void affine_rotation()
{
Mat src = imread("tekapo.bmp");
if (src.empty())
{
return;
}
Point2f cp(src.cols / 2.f, src.rows / 2.f);
Mat M = getRotationMatrix2D(cp, 20, 1);
Mat dst;
warpAffine(src, dst, M, Size());
imshow("src", src);
imshow("dst", dst);
waitKey();
destroyAllWindows();
}
8.1.6 대칭 변환
입력 영상과 같은 크기의 결과 영상을 생성, 입력 영상의 픽셀과 결과 영상의 픽셀이 일대일로 대응되므로 보간법이 필요하지 않음
void affine_flip()
{
Mat src = imread("eastsea.bmp");
if (src.empty())
{
return;
}
imshow("src", src);
Mat dst;
int flipCode[] = { 1, 0, -1 };
for (int i = 0; i < 3; i++)
{
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();
}
8.2 투시 변환
직사각형 형태의 영상을 임의의 블록 사각형 형태로 변경할 수 있는 변환
원본 영상에 있던 직선은 결과 영상에서 그대로 직선성이 유지되지만, 두 직선의 평행 관계는 깨어질 수 있음
Mat src;
Point2f srcQuad[4], dstQuad[4];
void on_mouse_(int event, int x, int y, int flags, void* userdata);
int main()
{
src = imread("card.bmp");
if (src.empty())
{
return -1;
}
namedWindow("src");
setMouseCallback("src", on_mouse_);
imshow("src", src);
waitKey();
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)
{
srcQuad[cnt++] = Point2f(x, y);
circle(src, Point(x, y), 5, Scalar(0, 0, 255), -1);
imshow("src", src);
if (cnt == 4)
{
int w = 200, h = 300;
dstQuad[0] = Point2f(0, 0);
dstQuad[1] = Point2f(w - 1, 0);
dstQuad[2] = Point2f(w - 1, h - 1);
dstQuad[3] = Point2f(0, h - 1);
Mat pers = getPerspectiveTransform(srcQuad, dstQuad);
Mat dst;
warpPerspective(src, dst, pers, Size(w, h));
imshow("dst", dst);
}
}
}
}
#OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝 - 13 (0) | 2022.07.06 |
---|---|
#OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝 - 12 (0) | 2022.06.22 |
#OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝 - 10 (0) | 2022.06.14 |
#OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝 - 9 (0) | 2022.06.13 |
#OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝 - 8 (0) | 2022.06.03 |