* 어파인(아핀) 변환

영상을 구성하는 픽셀의 배치 구조를 변경함으로써 평행 이동, 확대 및 축소, 회전 등 전체 영상의 모양을 바꾸는 기하학적 변환

 

* 어파인 변환 행렬

어파인 변환은 입력 영상의 좌표 (x, y)가 결과 영상의 좌표 (x', y')로 이동할때 총 여섯 개(a, b, c, d, e, f)의 파리미터를 이용한 수식으로 정의할 수 있다.

x' = f(x, y) = ax + by + c

y' = f(x, y) = dx + ey + f

위의 수식은 행렬을 이용해서 하나의 수식으로 표현 가능하다.

어파인 변환의 행렬 형태
하나의 행렬 곱셈 형태로 변환.가운데 2x3 행렬은 어파인 변환 행렬이라고 불린다.

여섯개의 원소로 정의되는 어파인 행렬을 구하기 위해서는 각 원소에 대응되는 방정식들을 구해야한다. 점 하나로부터 x 좌표와 y 좌표에 대한 변환 수식 두개를 얻을 수 있으므로 최소 점 세개에 대한 이동관계(방정식)을 알아야한다.

 

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

Mat getAffineTransform( InputArray src, InputArray dst );

 

src : 입력 영상에서 세 점의 좌표. 크기가 3인 Point2f 배열이나 vector<Point2f>

dst : 결과 영상에서 세 점의 좌표. 크기가 3인 Point2f 배열이나 vector<Point2f>

반환값 : src에 저장된 세 점을 dst 좌표의 점으로 옮기는 2x3 어파인 변환 행렬. CV_64FC1

 

- getAffineTransform 함수로 생성한 2 x 3 어파인 변환 행렬로 어파인 변환한 영상을 생성하려면 warpAffine 함수를 사용해야 한다.

 

* 어파인 변환

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

 

M : 2 x 3 어파인 변환 행렬. CV_32FC1 또는 CV_64FC1 타입이어야 한다.

dsize : 결과 영상 크기. Size()를 전달하면 입력 영상과 같은 크기의 결과 영상을 생성한다.

flags : 보간법 알고리즘. OR 연산자를 이용해 WARP_INVERSE_MAP 플래그를 지정하면 역방향으로 변환을 수행한다.

borderMode : 가장자리 픽셀 확장 방식. BORDER_TRANSPARENT를 지정하면 입력 영상의 픽셀 값이 복사되지 않는 영역은 dst 픽셀 값을 그대로 유지한다.

borderValue : borderMode가 BORDER_CONSTANT 일 때 사용할 상수 값. 기본값은 검은색.

 

- src를 어파인 변환시 어디로 이동하는지 dst에 반환하는 함수

void transform(InputArray src, OutputArray dst, InputArray m);

src : 입력 행렬 또는 vector<Point2f>. 점의 좌표를 다채널로 표현한다. ex) { Point2f(100, 20), Point2f(200, 50) };

dst : 출력 행렬 또는 vector<Point2f>. src를 어파인 변환한 위치가 담긴다.

m : 어파인 변환 행렬. 2 x 2 또는 2 x 3 실수형 행렬.

 

* 이동 변환

시프트 연산이라고도 불리며 영상을 가로 또는 세로 방향으로 일정 크기 만큼 이동 시키는 변환

 

- 입력영상의 모든 좌표를 x 방향으로 a 만큼 y 방향으로 b 만큼 이동시킨 결과좌표를 (x', y')라 할때 수식은 다음과 같다.

x' = x + a

y' = y + b 

이 수식을 행렬로 바꾸면 하나의 식으로 표현 가능하다.

수식을 행렬의 형태로 변환

이때 가운데 2x2 행렬과 뒤에 더해지는 2x1 행렬을 합치면 어파인 변환 행렬을 만들 수 있다.

이동 변환의 어파인 변환 행렬

- 해당 어파인 변환 행렬을 생성해주는 함수는 별도로 지원하고 있지 않으며

Mat M = Mat_<double>( { 2, 3 }, { 1, 0 , a, 0, 1, b} );

로 생성해서 warpAffine 함수의 매개변수로 넘겨주면 된다.

 

* 전단변환

층밀림 변환이라고도 불리며 직사각형 형태의 영상을 한쪽 방향으로 밀어서 평행사변형 모양으로 변형시키는 변환이다.

- 변환하고자 하는 픽셀이 원점(0, 0)에서 멀수록 이동거리가 길어지며 원점은 이동하지 않는다. 

- y 좌표가 증가하면 영상이 가로 방향으로 전단 변환하고

- x 좌표가 증가하면 영상이 세로 방향으로 전단 변환한다.

 

y 좌표의 증가(가로 방향 전단 변환)에 따라 m 만큼 밀릴때 전단 변환 수식과 행렬은 다음과 같다.

x' = x + m*y

y' = y

 

x 좌표의 증가(세로 방향 전단 변환)에 따라 m 만큼 밀릴때 전단 변환 수식과 행렬은 다음과 같다.

x' = x

y' = m*x + y

 

 

'공부 > OpenCV' 카테고리의 다른 글

레이블링  (0) 2019.08.16
영상의 필터링  (0) 2019.07.19
영상의 연산  (0) 2019.07.19
OpenCV (Open Computer Vision)  (0) 2019.05.29

+ Recent posts