7. 영상의 기하학적 변환

OpenJR·2022년 4월 11일
0
post-custom-banner

어파인 변환

이동변환

x=x+ay=y+b[xy]=[10a01b][xy1]x'=x+a\\ y'=y+b\\ \begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}1 & 0& a\\0 & 1 & b\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}

전단변환

x=x+my,x=xy=y,y=mx+y[xy]=[1m0010][xy1],[xy]=[100m10][xy1]\begin{aligned}x'=x+my,\qquad &x'=x\\ y'=y,\qquad &y'=mx+y\\ \begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}1 & m& 0\\0 & 1 & 0\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}, \qquad &\begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}1 & 0& 0\\m & 1 & 0\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}\end{aligned}

크기변환

x=Sxxy=Syy[xy]=[Sx000Sy0][xy1]x'=S_xx\\ y'=S_yy\\ \begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}S_x & 0& 0\\0 & S_y & 0\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}
void resize(InputArray src, OutputArray dst, Size dsize,
            double fx = 0, double fy = 0, int interpolation = INTER_LINEAR);

resize(src, dst1, Size(), 2, 2);					// 2배 확대
resize(src, dst2, Size(), 0.5, 0.5, INTER_AREA);	// 2배 축소
resize(src, dst2, Size(1920, 1280), 0, 0);	// 임의 크기로 변경

src, dst: 입력 영상, 출력 영상

dsize: 결과 영상의 크기. size()를 지정하면 fx, fy에 의해 자동 결정됨.

fx, fy: x와 y방향 스케일 비율(scale factor). (dsize 값이 0일 때 유효)

interpolation: 보간법 지정 상수

  • INTER_NEAREST: 최근방 이웃 보간법
  • INTER_LINEAR: 양선형 보간법 (2x2 이웃 픽셀 참조)
  • INTER_CUBIC: 3차회선 보간법 (4x4 이웃 픽셀 참조)
  • INTER_LANCZOS4: Lanczos 보간법 (8x8 이웃 픽셀 참조)
  • INTER_AREA: 영상 축소 시 효과적

대칭변환

void flip(InputArray src, OutputArray dst, int flipCode);

src: 입력 영상

dst: 출력 영상

flipCode: 대칭 방향 지정

  • 양수 (+1): 좌우 대칭
  • 0: 상하 대칭
  • 음수 (-1): 좌우 & 상하 대칭

회전변환

x=cosθx+sinθyy=sinθx+cosθy[xy]=[cosθsinθ0sinθcosθ0][xy1]x'=\cos\theta x+\sin\theta y\\ y'=-\sin\theta x+\cos\theta y\\ \begin{bmatrix}x'\\y'\end{bmatrix}=\begin{bmatrix}\cos\theta & \sin\theta& 0\\-\sin\theta & \cos\theta & 0\end{bmatrix}\begin{bmatrix}x\\y\\1\end{bmatrix}
Mat getRotationMatrix2D(Point2f center, double angle, double scale );

Point2f pt(src.cols / 2.f, src.rows / 2.f);
Mat rot = getRotationMatrix2D(pt, 30.f, 1.0);

center: 회전 중심 좌표

angle: (반시계 방향) 회전 각도(degree). 음수는 시계 방향.

scale: 회전 후 확대 비율

반환값: 2x3 double (CV_64F) 행렬

어파인 변환 행렬 구하기

Mat getAffineTransform(const Point2f src[], const Point2f dst[]);
Mat getAffineTransform(InputArray src, InputArray dst);

src: 3개의 원본 좌표점 (Point2f src[3]; 또는 vector\ src;)

dst: 3개의 결과 좌표점 (Point2f dst[3]; 또는 vector\ dst;)

반환값: 2x3 크기의 변환 행렬 (CV_64F)

어파인 변환

void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize,
                int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT,
                const Scalar& borderValue = Scalar());

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

src: 입력 영상

dst: 출력 영상. src와 같은 타입.

M: 2x3 어파인 변환 행렬. cv_32F 또는 cV_64F.

dsize: 결과 영상의 크기

flags: 보간법 선택

borderMode: 가장자리 픽셀 처리 방식

borderValue: BORDER-CONSTANT 모드 사용 시 사용할 픽셀 값

투시변환

투시변환 행렬 구하기

Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[], int solveMethod = DECOMP_LU);
Mat getPerspectiveTransform(InputArray src, InputArray dst, int solveMethod = DECOMP_LU);

vector<Point2f> src_pts (4);
vector<Point2f> dst_pts (4);
src_pts[0] = Point2f(474, 400);		src_pts[1] = Point2f(710, 400);
src_pts[2] = Point2f(866, 530);		src_pts[3] = Point2f(366, 530);

dst_pts[0] = Point2f(0, 0);			dst_pts[1] = Point2f(w-1, 0);
dst_pts[2] = Point2f(w-1, h-1);		dst_pts[3] = Point2f(0, h-1);

Mat per_mat = getPerspectiveTransform(src_pts, dst_pts);

src: 4개의 원본 좌표점 (Point2f src[4]; 또는 vector\ src;)

dst: 4개의 결과 좌표점 (Point2f dst[4]; 또는 vector\ dst;)

반환값: 3x3 크기의 변환 행렬 (CV_64F)

투시변환

void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize,
                     int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT,
                     const Scalar& borderValue = Scalar());

int w = 540, h = 260;
Mat dst;
warpPerspective(src, dst, per_mat, Size(w, h));

src: 입력 영상

dst: 출력 영상. src와 같은 타입.

M: 3x3 투시 변환 행렬. cv_32F 또는 CV_64F.

dsize: 결과 영상의 크기

flags: 보간법 선택

borderMode: 가장자리 픽셀 처리 방식

borderValue: BORDER-CONSTANT 모드 사용 시 사용할 픽셀 값

profile
Jacob
post-custom-banner

0개의 댓글