어파인변환
직사각형을 평생사변형으로 변환시킨다. 즉 서로의 대변에 평행함을 유지한 상태에서 직사각형을 짓누르는 형태의 변환이다.
물체의 특징이 유지되는 변환이다.
어파인변환은 밀집 어파인 변환, 희소 어파인 변환 두가지가 있다.
밀집 어파인 변환
입력과 출력형식은 영상이고 이때 픽셀은 주어진 영상의 밀집된 표현으로 간주된다 --> 이게 뭔말??!
void cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* map_matrix, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) ); |
src, dst는 배열 또는 영상이며, 1또는 3채널을 가질수있다. 어떠한 타입이어도 상관없지만 두영상의 크기와 데이터타입은 같아야한다.
map_matrix : 어파인변환을 표현하는 2×3크기의 행렬이다.
flags : 보관방법을 지정하며, 논리합을 이용하여 여러 플래그를 지정할수 있다.
- CV_WARP_FILL_OUTLIERS : 빈자리를 함수의 마지막인자인 fillval에 설정된 값으로 채운다.
- CV_WARP_INVERSE_MAP : src로부터 dst로 변환하는 것이 아니라, 반대로 dst로부터 src영상을 생성한다.
※ cvWarpAffine()함수는 많은 오버헤드를 가지고 있기때문에 이대신 cvGetQuadrangleSubPix()함수를 사용하는 것이 유리하다.
이 함수는 오버헤드가 더 적고 8비트 입력영상과 32비트실수형 출력영상을 함께 사용할수 있다.
void
cvGetQuadrangleSubPix(
const CvArr* src, CvArr* dst, const CvMat* map_matrix ); |
src에 있는 모든점들은 2×3크기의 map_matrix행렬로 표현되는 어파인 변환으로 변환하여 dst점들을 구한다.
곱셉연산들을 위해 점들의 좌표를 동차좌표계로 바꾸는 작업은 자동으로 수행된다.
어파인 매핑행렬 계산
OpenCV는 map_matrix행렬을 생성하는 두가지 방법이 있다
방법1) cvGetAffineTransform()함수를 이용하여 어파린 변환의 입력과 결과 영상 두장을 가지고 있을때 사용하는 방법
=> 변환행렬을 근사화하여 구할수 있다.
CvMat*
cvGetAffineTransform(
const CvPoint2D32f * src, const CvPoint2D32f * dst, CvMat * map_matrix ); |
src와 dst는 2차원 (x, y)좌표 3개를 갖고 잇는 배열이고, map_matrix는 이점들에 의해 계산되는 어파인 변환행렬이다.
src와 dst는 각각 평행사변형의 세 꼭지점 좌표를 저장하고 있는 배열이다.
방법2) cv2DRotationMatrix()함수를 사용하는방법으로 특정좌표를 기준으로 영상을 회전하는 변환을 나타내는 변환행렬을 구할수 있다. 선택적으로 크기 조절도 가능하다.
CvMat*
cv2DRotationMatrix(
CvPoint2D32f center, double angle, double scale, CvMat* map_matrix ); |
center : 회전의 중심
angle : 회전할 각도
scale : 크기 변환을 위한 스케일값
map_matrix : 해당변환을 나타내는 결과행렬 (2×3크기의 실수형 행렬이어야한다)
예제) 어파인 행렬 변환
#include <cv.h> #include <highgui.h>
int main(int argc, char** argv) { CvPoint2D32f srcTri[3], dstTri[3]; CvMat* rot_mat=cvCreateMat(2, 3, CV_32FC1); CvMat* warp_mat=cvCreateMat(2, 3, CV_32FC1); IplImage* src, *dst;
if(argc==2 && ((src=cvLoadImage(argv[1], 1))!=0)) { dst=cvCloneImage(src); dst->origin=src->origin; cvZero(dst);
srcTri[0].x=0; srcTri[0].y=0; srcTri[1].x=src->width-1; srcTri[1].y=0; srcTri[2].x=0; srcTri[2].y=src->height-1;
dstTri[0].x=src->width*0.0; //결과 영상의 좌상단 dstTri[0].y=src->height*0.33; dstTri[1].x=src->width*0.85; //결과 영상의 우상단 dstTri[1].y=src->height*0.25; dstTri[2].x=src->width*0.15; //결과 영상의 좌하단 dstTri[2].y=src->height*0.7;
cvGetAffineTransform(srcTri, dstTri, warp_mat); cvWarpAffine(src, dst, warp_mat); cvCopy(dst, src);
//회전행렬 계산 CvPoint2D32f center=cvPoint2D32f(src->width/2, src->height/2); //중심점 double angle=-50.0; double scale=0.6; cv2DRotationMatrix(center, angle, scale, rot_mat);
//변환수행 cvWarpAffine(src, dst, rot_mat); cvNamedWindow("Affine_Transform", 1); cvShowImage("Affine_Transform", dst); cvWaitKey();
cvReleaseImage(&dst); cvReleaseMat(&rot_mat); cvReleaseMat(&warp_mat); cvDestroyWindow("Affine_Transform"); } return 0; } |
ㅎ
희소 어파인 변환
변환하고자 하는 점들의 목록을 가지고 있는 경우
개별적인 점들의 매핑의 경우에 희소 어파인 변환을 사용한다.
void cvTransform(
const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec=NULL) ); |
투시변환
직사각형을 사다리꼴 형태로 바꿀수있다. 평행사변형은 사다리꼴에 포함되기때문에 어파인변환은 투시변환의 부분집합이된다.
'Developer > OpenCV' 카테고리의 다른 글
기본행렬, 필수행렬 (0) | 2013.02.03 |
---|---|
스테레오 영상 (0) | 2013.02.01 |
보정함수 (0) | 2013.01.30 |
보정객체(체스판) 찾기 (0) | 2013.01.30 |
회전행렬과 이동백터 (1) | 2013.01.29 |