OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝/ 영상의 기하학적 변환

어파인 변환

  • 영상의 기하학적 변환(geometric transform)은 영상을 구성하는 픽셀의 배치 구조를 변경함으로써 전체 영상의 모양을 바꾸는 작업. 
  • 입력 영상에서 (x, y) 좌표의 픽셀을 결과 영상의 (x', y') 좌표로 변환하는 방법은 다음과 같이 고유의 함수 형태로 나타낼 수 있다.

\begin{cases} x' = f_{1}(x, y) \\ y' = f_{2}(x, y) \end{cases}

어파인 변환

  • 영상의 기하학적 변환 중에서 어파인 변환(affine transformation)은 영상을 평행 이동시키거나 회전, 크기 변환 등을 통해 만들 수 있는 변환을 통칭한다.
    • 또는 영상을 한쪽 방향으로 밀어서 만든 것 같은 전단 변환도 어파인 변환에 포함된다.
    • 영상에 어파인 변환을 적용할 경우 직선은 그대로 직선으로 나타나고, 직선 간의 길이 비율과 평행 관계가 그대로 유지된다.

  • 어파인 변환은 모두 여섯 개의 파라미터를 이용한 수식으로 정의할 수 있다.

\begin{cases} x' = f_{1}(x, y) = ax + by + c \\ y' = f_{2}(x, y) = dx + ey + f \end{cases}

  • 위 수식은 행렬을 이용해서 다음과 같은 수식으로 표현할 수도 있다.

\left( \begin{array}{rr} x' \\ y'  \end{array} \right) = \left( \begin{array}{rr} a & b \\ d & e  \end{array} \right) \left( \begin{array}{rr} x \\ y  \end{array} \right) + \left( \begin{array}{rr} c \\ f  \end{array} \right)

  • 즉 입력 영상의 좌표를 나타내는 행렬 \left( \begin{array}{rr} x \\ y  \end{array} \right)  앞에 2×2 행렬 \left( \begin{array}{rr} a & b \\ d & e  \end{array} \right) 을 곱하고 그 뒤에 2×1 행렬 \left( \begin{array}{rr} c \\ f  \end{array} \right) 를 더하는 형태로 어파인 변환을 표현한다.
  • 수학적 편의를 위해 입력 영상의 좌표 (x, y) 에 가상의 좌표 1을 하나 추가하여 (x, y, 1) 형태로 바꾸면, 행렬 수식을 다음과 같은 하나의 행렬 곱셈 형태로 바꿀 수 있다.

\left( \begin{array}{rr} x' \\ y'  \end{array} \right) = \left( \begin{array}{rrr} a & b & c \\ d & e & f \end{array} \right) \left( \begin{array}{rrr} x \\ y \\ 1 \end{array} \right)

  • 위 수식에서 여섯 개의 파라미터로 구성된 2×3 행렬 \left( \begin{array}{rrr} a & b & c \\ d & e & f \end{array} \right) 를 어파인 변환 행렬 (affine transform matrix)이라고 한다. 즉 어파인 변환은 2×3 실수형 행렬 하나로 표현할 수 있는 것이다.
  • 입력 영상과 어파인 변환 결과 영상으로부터 어파인 변환 행렬을 구하기 위해서는 최소 세 점의 이동 관계를 알아야 한다.
    • 점 하나의 이동 관계로부터 x좌표와 y좌표에 대한 변환 수식 두 개를 얻을 수 있으므로, 점 세 개의 이동 관계로부터 총 여섯 개의 방정식을 구할 수 있다.
    • 그러므로 점 세 개의 이동 관계를 알고 있다면 여섯 개의 원소로 정의되는 어파인 변환 행렬을 구할 수 있다.
  • 아래 그림은 점 세 개의 이동 관계에 의해 결정되는 어파인 변환을 보여준다.
    • 어파인 변환에 의해 직사각형 영상은 평행사변형 형태로 변환될 수 있기 때문에 입력 영상의 좌측 하단 모서리 점이 이동하는 위치는 자동으로 결정된다.
    • 그러므로 어파인 변환은 점 세 개의 이동 관계만으로 정의할 수 있다.

  • OpenCV는 어파인 변환 행렬을 구하는 함수와 어파인 변환 행렬을 이용하여 실제 영상을 어파인 변환하는 함수를 모두 제공한다.
    • 어파인 변환 행렬을 구하는 함수 이름은 getAffineTransform()으로, 입력 영상에서 세 점의 좌표와 이점들이 이동한 결과 영상의 좌표 세 개를 입력 받아 2×3 어파인 변환 행렬을 계산한다.
    • 2×3 어파인 변환 행렬을 가지고 있을 때 영상을 어파인 변환한 결과 영상을 생성하려면 warpAffine() 함수를 사용한다. wrapAffine() 함수는 src 영상을 어파인 변환하여 dst 영상을 생성한다.
Mat src = imread("tekapo.bmp");

if (src.empty())
{
cerr << "Image load failed!" << endl;
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);

이동 변환

  • 영상의 이동 변환(translation transformation)은 영상을 가로 또는 세로 방향으로 일정 크기만큼 이동 시키는 연산을 의미하며, 시프트(shift) 연산이라고도 한다.

  • 입력 영상의 모든 좌표를 x 방향으로 a 만큼, y 방향으로 b 만큼 이동하는 변환을 수식으로 나타내면 다음과 같다.

\begin{cases} x' = x + a \\ y' = y + b \end{cases}

  • 이 수식에서 (x, y) 는 입력 영상의 픽셀 좌표이고, (x', y') 는 결과 영상의 픽셀 좌표이다. 앞 수식을 행렬을 이용하면 다음과 같이 하나의 식으로 표현할 수 있다.

\left[ \begin{array}{rr} x' \\ y'  \end{array} \right] = \left[ \begin{array}{rr} 1 & 0 \\ 0 & 1 \end{array} \right] \left[ \begin{array}{rr} x \\ y \end{array} \right] + \left[ \begin{array}{rr} a \\ b \end{array} \right]

  • 앞 수식에서 입력 영상의 좌표를 나타내는 행렬 \left[ \begin{array}{rr} x \\ y \end{array} \right] 앞의 2×2 행렬과 그 뒤에 더해지는 2×1 행렬을 합쳐서 하나의 2×3 행렬을 구성하면 이동 변환을 나타내는 어파인 변환 행렬을 만들 수 있다.
    • 즉 영상을 x 방향으로 a 만큼, y 방향으로 b 만큼 이동하는 어파인 변환 행렬 M은 다음과 같다.

M = \left[ \begin{array}{rrr} 1 & 0 & a \\ 0 & 1 & b \end{array} \right]

  • 그러므로 OpenCV에서 영상을 이동 변환하려면 앞과 같은 형태의 2×3 실수 행렬 M을 만들고 이를 wrapAffine() 함수 인자로 전달해야 한다.
Mat src = imread("tekapo.bmp");

if (src.empty())
{
cerr << "Image load failed!" << endl;
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);

전단 변환

  • 전단 변환(shear transformation)은 직사각형 형태의 영상을 한쪽 방향으로 밀어서 평행사변형 모양으로 변형되는 변환이며 층밀림 변환이라고도 한다.
    • 전단 변환은 가로 방향 또는 세로 방향으로 각각 정의할 수 있다.

  • y 좌표가 증가함에 따라 영상을 가로 방향으로 조금씩 밀어서 만드는 전단 변환 수식은 다음과 같다.

\begin{cases} x' = x + m_{x}y \\ y' = y \end{cases} 또는 \left[ \begin{array}{rr} x' \\ y'  \end{array} \right] = \left[ \begin{array}{rr} 1 & m_{x} \\ 0 & 1 \end{array} \right] \left[ \begin{array}{rr} x \\ y \end{array} \right] + \left[ \begin{array}{rr} 0 \\ 0 \end{array} \right]

  • x 좌표가 증가함에 따라 영상을 세로 방향으로 조금씩 밀어서 만드는 전단 변환 수식은 다음과 같다.

\begin{cases} x' = x \\ y' = m_{y}x + y \end{cases} 또는 \left[ \begin{array}{rr} x' \\ y'  \end{array} \right] = \left[ \begin{array}{rr} 1 & 0 \\ m_{y} & 1 \end{array} \right] \left[ \begin{array}{rr} x \\ y \end{array} \right] + \left[ \begin{array}{rr} 0 \\ 0 \end{array} \right]

  • 앞의 두 수식에서 m_{x} m_{y} 는 영상으로 각각 가로 방향과 세로 방향으로 밀림 정도는 나타내는 시룻이다. 결국 전단 변환을 나타내는 2×3 어파인 변환 행렬 M은 다음과 같이 나타낼 수 있다.

M = \left[ \begin{array}{rrr} 1 & m_{x} & 0 \\ 0 & 1 & 0 \end{array} \right] 또는 M = \left[ \begin{array}{rrr} 1 & 0 & 0 \\ m_{y} & 1 & 0 \end{array} \right]

Mat src = imread("tekapo.bmp");

if (src.empty())
{
cerr << "Image load failed!" << endl;
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);

크기 변환

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

  • 원본 영상의 가로 픽셀 크기가 w 이고 결과 영상의 가로 크기가 w' 이기 때문에 가로 방향으로의 크기 변환 비율 s_{x} s_{x} = w' / w 수식으로 계산할 수 있다. 마찬가지로 y 방향으로의 크기 변환 비율 s_{y} s_{y} = h' / h 수식으로 계산된다.
    • 입력 영상 좌표 (x, y) 로부터 크기 변환 결과 영상의 좌표 (x', y') 를 계산하는 수식은 다음과 같다.

\begin{cases} x' = s_{x}x \\ y' = s_{y}y \end{cases} 또는 \left[ \begin{array}{rr} x' \\ y'  \end{array} \right] = \left[ \begin{array}{rr} s_{x} & 0 \\ 0 & s_{y} \end{array} \right] \left[ \begin{array}{rr} x \\ y \end{array} \right] + \left[ \begin{array}{rr} 0 \\ 0 \end{array} \right]

  • 위 수식에서 s_{x} 또는 s_{y} 가 1보다 크면 영상이 확대되고 1보다 작으면 축소 된다.
  • 영상의 크기 변환을 나타내는 어파인 변환 행렬 M은 다음과 같다.

M = \left[ \begin{array}{rrr} s_{x} & 0 & 0 \\ 0 & s_{y} & 0 \end{array} \right]

  • 그러므로 앞과 같은 어파인 변환 행렬을 생성하고 wrapAffine() 함수를 이용하면 영상의 크기 변환을 수행할 수 있다.
  • 그러나 영상의 크기를 변경하는 작업은 실제 영상 처리 시스템에서 매우 빈번하게 사용되기 때문에 OpenCV는 보다 간단하게 크기를 변경할 수 있는 resize() 함수를 제공한다.
  • resize() 함수는 src 입력 영상을 dsize 크기로 확대 또는 축소한 dst 영상을 생성한다.
    • 영상의 크기는 dsize 인자를 통해 명시적으로 지정할 수도 있고, 또는 가로 방향 및 세로 방향으로의 크기 변환 비율은 fx와 fy 값을 통해 결정되도록 할 수도 있다.
    • 만약 결과 영상의 크기를 픽셀 단위로 지정하여 크기 변환을 수행하려면 dsize에 0이 아닌 값을 지정하고, fx와 fy는 0으로 설정한다.
    • 만약 입력 영상의 크기를 기준으로 크기 변환 비율을 지정하여 영상을 확대 또는 축소 하려면 dsize 인자에는 Size()를 지정하고 fx와 fy에는 0이 아닌 양의 실수를 지정한다.
    • 이 경우 결과 영상의 크기는 다음과 같이 설정된다.

\begin{cases} dst.rows = round(src.rows \times fx) \\ dst.cols = round(src.cols \times fy) \end{cases}

  • resize() 함수의 여섯 번쨰 인자 interpolation에는 보간법 알고리즘을 나타내는 InterpolationFlags 열거형 상수를 지정한다. 
    • 보간법은 결과 영상의 픽셀 값을 결정하기 위해 입력 영상 주변 픽셀 값을 이용하는 방식을 의미한다.
    • INTER_NEAREST 방법은 가장 빠르게 동장하지만 결과 영상 화질이 좋지 않다.
    • INTER_LINEAR 방법읍 연산 속도가 빠르고 화질도 충분히 좋은 편이라서 널리 사용되고 있고, resize() 함수에서 기본값으로 지정되어 있다.
    • INTER_LINEAR 보다 더 좋은 화질을 원한다면 INTER_CUBIC 또는 INTER_LANCZOS4 상수를 사용하는 것이 좋다.
    • 영사을 축소하는 경우 INTER_AREA 방법을 사용하면 무아레(moire) 현상이 적게 발생하며 화질 면에서 유리하다.
InterpolationFlags 열거형 상수 설명
INTER_NEAREST 최근방 이웃 보간법
INTER_LINEAR 양선형 보간법
INTER_CUBIC 3차 보간법
INTER_AREA 픽셀 영역 리샘플링
INTER_LANCZOS4 8×8 이웃 픽셀을 사용하는 란초스(Lanczos 보간법)
Mat src = imread("tekapo.bmp");

if (src.empty())
{
cerr << "Image load failed!" << endl;
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)));

회전 변환

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

  • 영상의 회전 변환에 의해 입력 영상의 점 (x, y) 가 이동하는 점의 좌표 (x', y') 는 다음과 같이 삼각함수를 이용하여 구할 수 있다.

\begin{cases} x' = cos \theta \cdot x + sin \theta \cdot y \\ y' = -sin \theta \cdot x + cos \theta \cdot y \end{cases} 또는 \left[ \begin{array}{rr} x' \\ y'  \end{array} \right] = \left[ \begin{array}{rr} cos \theta & sin \theta \\ - sin \theta & cos \theta \end{array} \right] \left[ \begin{array}{rr} x \\ y \end{array} \right] + \left[ \begin{array}{rr} 0 \\ 0 \end{array} \right]

  • 영상을 반시계 방향으로 \theta 만큼 회전하는 어파인 변환 행렬 M은 다음과 같이 정의된다.

M = \left[ \begin{array}{rrr} cos \theta & sin \theta & 0 \\ - sin \theta & cos \theta & 0 \end{array} \right]

  • 그러므로 cos() 함수와 sin() 함수를 이용하여 앞과 같은 행렬을 생성하고 warpAffine() 함수를 사용하면 영상을 회전시킬 수 있다. 
  • 다만 영상을 회전하는 경우가 많기 떄문에 OpenCV에서는 영상의 회전을 위한 어파인 변환 행렬을 생성하는 getRotationMatrix2D() 함수를 제공한다.
    • 이 함수를 이용하면 영상을 원점이 아닌 특정 좌표를 기준으로 회전시키거나 필요한 경우 크기 변환까지 함께 수행하는 어파인 변환 행렬을 쉽게 만들 수 있다.
  • getRotationMatrix2D() 함수는 center 점을 기준으로 반시계 방향으로 angle 각도만큼 회전한 후, scale 크기만큼 확대 또는 축소하는 2×3 어파인 변환 행렬을 반환한다.
    • 만약 영상을 시계 방향으로 회전하는 어파인 변환 행렬을 구하고 싶다면 angle 인자에 음수를 지정한다.
    • getRotationMatrix2D() 함수가 반환하는 어파인 변환 행렬은 다음과 같이 계산된다.

\left[ \begin{array}{rrr} \alpha & \beta & (1-\alpha) \cdot center.x - \beta \cdot center.y \\ - \beta & \alpha & \beta \cdot center.x + (1 - \alpha) \cdot center.y \end{array} \right]

  • 이 수식에서 \alpha = scale \cdot cos(angle) 이고, \beta = scale \cdot sin(angle) 를 의미한다.
Mat src = imread("tekapo.bmp");

if (src.empty())
{
cerr << "Image load failed!" << endl;
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);

대칭 변환

  • 대칭 변환은 입력 영상과 같은 크기의 결과 영상을 생성하며, 입력 영상의 픽셀과 결과 영상의 픽셀이 일대일로 대응되므로 보간법이 필요하지 않다.
  • 영상의 좌우 대칭 변환에 의한 좌표 변환 수식은 다음과 같다.

\begin{cases} x' = w - 1 - x \\ y' = y \end{cases}

  • 이 수식에서 (x, y) 는 입력 영상의 픽셀 좌표이고, (x', y') 는 결과 영상의 픽셀 좌표이며, w 는 입력 영상의 가로 크기이다. 앞 수식을 행렬 형태로 바꿔 쓰면 다음과 같다.

\left[ \begin{array}{rr} x' \\ y'  \end{array} \right] = \left[ \begin{array}{rr} -1 & 0 \\ 0 & -1 \end{array} \right] \left[ \begin{array}{rr} x \\ y \end{array} \right] + \left[ \begin{array}{rr} w-1 \\ 0 \end{array} \right]

  • 앞의 수식을 정리해서 보면 결국 좌우 대칭은 영상을 x 축 방향으로 -1배 크기 변환한 후 x 축 방향으로 w-1 만큼 이동 변환한 것과 같다. 그러므로 좌우 대칭 변환도 어파인 변환의 일종이다.
  • 영상의 상하 대칭 변환도 비슷한 방식으로 생각할 수 있으며 수식으로 정리하면 다음과 같다.

\begin{cases} x' = x \\ y' = h - 1 - y \end{cases} 또는 \left[ \begin{array}{rr} x' \\ y'  \end{array} \right] = \left[ \begin{array}{rr} 1 & 0 \\ 0 & -1 \end{array} \right] \left[ \begin{array}{rr} x \\ y \end{array} \right] + \left[ \begin{array}{rr} 0 \\ h - 1 \end{array} \right]

  • OpenCV는 영상의 대칭 변환을 수행하는 flip() 함수를 제공한다. flip() 함수는 영상을 가로 방향, 세로 방향, 또는 가로와 세로 양 방향에 대해 대칭 변환한 영상을 생성한다.
    • flip() 함수의 대칭 방법은 flipCode의 인자 부호에 따라 결정된다. 일반적으로 영상을 좌우로 대칭 변환하려면 flipCode에 1을 지정하고, 상하 대칭 변환을 하려면 0을 지정한다. 상하 대칭과 좌우 대칭을 모두 수행하려면 -1을 지정한다.
    • 참고로 상하 대칭과 좌우 대칭을 모두 수행한 결과는 입력 영상을 180도 회전한 것과 같다.
  • (예제는 flip() 함수를 사용하는 것이라 생략)

투시 변환

  • 영상의 기하학적 변환 중에는 어파인 변환보다 자유도가 높은 투시 변환(perspective transform)이 있다. 투시 변환은 직사각형 형태의 영상을 임의의 볼록 사각형 형태로 변경할 수 있는 변환이다.
    • 투시 변환에 의해 원본 영상에 있던 직선은 결과 영상에서 그대로 직선성이 유도되지만, 두 직선의 평행 관계는 깨어질 수 있다.
  • 아래 그림은 점 네 개의 이동 관계에 의해 결정되는 투시 변환을 나타낸다.
    • 투시 변환은 직선의 평행 관계가 유지되지 않기 때문에 결과 영상의 형태가 임의의 사각형으로 나타나게 된다. 
    • 점 하나의 이동 관계로부터 x 좌표에 대한 방정식 하나와 y 좌표에 대한 방정식 하나를 얻을 수 있으므로, 점 네 개의 이동 관계로부터 여덟 개의 방정식을 얻을 수 있다.
    • 이 여덟 개의 방정식으로부터 투시 변환을 표현하는 파라미터 정보를 계산할 수 있다.

  • 투시변환은 보통 3×3 크기의 실수 행렬로 표현한다.
    • 투시 변환은 여덟 개의 파라미터로 표현할 수 있지만, 좌표 계산의 편의상 아홉 개의 원소를 갖는 3×3 행렬을 사용한다.
    • 투시 변환을 표현하는 행렬을 M_{p} 라고 하면, 입력 영상의 픽셀 좌표 (x, y) 가 행렬 M_{p} 에 의해 이동하는 결과 영상 픽셀 좌표 (x', y') 는 다음과 같이 계산된다.

\left( \begin{array}{rrr} wx' \\ wy' \\w \end{array} \right) = M_{p} \left( \begin{array}{rrr} x \\ y \\ 1 \end{array} \right) = \left( \begin{array}{rrr} p_{11} & p_{12} & p_{13} \\ p_{21} & p_{22} & p_{23} \\ p_{31} & p_{32} & p_{33} \end{array} \right) \left( \begin{array}{rrr} x \\ y \\ 1 \end{array} \right)

  • 앞의 행렬 수식에서 입력 좌표와 출력 좌표를 (x, y, 1), (wx', wy', w) 형태로 표현한 것을 동차 좌표계(homogeneous coordinates)라고 하며, 좌표 계산의 편의를 위해 사용하는 방식이다.
    • 여기서 w 는 결과 영상의 좌표를 표현할 때 사용되는 비례 상수이며 w = p_{31}x + p_{32}y + p_{33} 형태로 계산된다. 
    • 그러므로 x y 는 다음과 같이 구할 수 있다.

x' = { p_{11}x + p_{12}y + p_{13} \over p_{31}x + p_{32}y + p_{33} },  y' = { p_{21}x + p_{22}y + p_{23} \over p_{31}x + p_{32}y + p_{33} }

  • OpenCV는 투시 변환 행렬을 구하는 함수와 투시 변환 행렬을 이용하여 실제 영상을 투시 변환하는 함수를 모두 제공한다.
    • 투시 변환 행렬을 구하는 함수 이름은 getPerspectiveTransform()으로 입력 영상에서 네 점의 좌표와 이 점들이 이동한 결과 영상의 좌표 네 개를 입력 받아 3×3 투시 변환 행렬을 계산한다.
    • 3×3 투시 변환 행렬을 가지고 있을 때, 영상을 투시 변환한 결과 영상을 생성하려면 warpPerspective() 함수를 사용한다. 이 함수는 투시 변환 행렬 M을 이용하여 src 영상으로부터 dst 영사을 생성한다. 이때 전달되는 투시 변환 행렬 M은 CV_32FC1 또는 CV_64FC1 타입이어야 하고 크기는 3×3 이어야 한다.
Mat src;
Point2f srcQuad[4], dstQuad[4];

void on_mouse(int event, int x, int y, int flags,void* userdata);

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

namedWindow("src");
setMouseCallback("src", on_mouse);

imshow("src");
waitKey(0);

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(0, 0);
dstQuad[2] = Point2f(0, 0);
dstQuad[3] = Point2f(0, 0);

Mat pers = getPerspectiveTransform(srcQuad, dstQuad);

Mat dst;
warpPerspective(src, dst, pers, Size(w, h));

imshow("dst", dst);
}
}
}
}
  • 만일 3×3 투시 변환 행렬을 가지고 있을 때, 일부 점들이 투시 변환에 의해 어느 위치로 이동할 것인지 알고 싶다면 perspectiveTransform() 함수를 사용할 수 있다.
[ssba]

The author

지성을 추구하는 사람/ suyeongpark@abyne.com

댓글 남기기

This site uses Akismet to reduce spam. Learn how your comment data is processed.