해당 포스트는 "열혈강의 영상처리 프로그래밍" 책의 내용을 요약한 것이다.



※ 영상의 평행 이동

영상의 평행 이동은 입력 영상을 가로, 세로 방향으로 주어진 값만큼 이동하는 것이다. 예를 들어, 입력 영상이 오른쪽으로 10픽셀 이동한 영상을 구한다면, 결과 영상의 입장에서는 자신의 위치에서 왼쪽으로 10필셀 위치에 있는 픽셀 값을 입력 영상으로부터 읽어오면 된다.

위 그림은 입력 영상을 오른쪽으로 p 픽셀만큼, 아래쪽으로 q 픽셀만큼 이동한 영상이다. 위 그림에서 눈의 좌표를 (x,y) 라고 하고 결과 영상의 눈 좌표를 (x', y')라고 하면 다음과 같은 식이 성립한다.


(x', y') = (x, y) + (p, q) = (x+p, y+q)


위 식은 다음과 같이 바꿀 수 있다.


(x, y) = (x', y') - (p, q) = (x'-p, y'-q)


다음은 위 식을 코드로 표현했다.

imageOut.GetAt(x, y) = imageIn.GetAt(x-p, y-q);

만약, 입력 영상의 픽셀 값을 읽을 때 소수점 위치도 처리하고자 한다면 앞에서 배운 픽셀 값 보간함수를 사용하면 된다. 다음 코드는 쌍선형 보간을 사용한 평행 이동을 구현한 내용이다.

imageOut.GetAt(x, y) = imageIn.BiLinearIntp(x-p, y-p);



※ 영상의 회전 이동

영상의 회전 변환에 대한 관계식은 2차원 평면에서 회전 변환을 나타내는 행렬을 통하여 얻을 수 있다.

위 식에 회전 변환을 나타내는 역행렬을 곱해서 (x, y) 에 대한 식으로 정리하면 다음과 같다.

위 식을 이용한 회전 변환 코드는 다음과 같다.

double cR = cos(theta);
double sR = cos(theta);
double srcX = cR * x + sR * y;
double srcY = -sR * x + cR * y;
imageOut.GetAt(x,y) = imageIn.BiLinearIntp(srcX, srcY);



※ 영상의 확대 및 축소 변환

위 그림과 같이 확대/축소할 배율 s에 대하여 입력 영상의 모든 픽셀은 원점으로부터의 거리가 s배 만큼 늘어나게 된다. 이러한 확대/축소가 적요된 결과 영상이 다음과 같이 표현된다.


(x', y') = s * (x, y) = (s * x, s * y)


이 식을 (x, y)에 대한 식으로 정리하면 다음과 같다.


(x, y) = (x' / s,  y' / s)


위 수식을 이용하면 다음과 같은 코드로 영상의 확대/축소를 구현할 수 있다.

double invS = 1.0/s;
imageOut.GetAt(x, y) = imageIn.BilLinearIntp(invS * x, invS * y); 

invS를 미리 구한 이유는 매 좌표마다 나눗셈 연산을 하면 성능이 저하되기에 곱셈 연산을 하기 위해서 미리 정의했다. 배율이 가로 세로 방향으로 위와 같이 같을 수도 있지만 다를 수도 있다. 이 때의 코드는 다음과 같다.

double invSX = 1.0/sx;
double invSY = 1.0/sy;
imageOut.GetAt(x, y) = imageIn.BiLinearIntp(invSX * x, invSY * y); 


+ Recent posts