透視變換(單應性?)能提供更大的靈活性,但是一個透視投影並不是線性變換,因此所采用的映射矩陣是3*3,且控點變為4個,其他方面與仿射變換完全類似,下面的例程是針對密集變換,稀疏圖像變換則采用cvPerspectiveTransform函數來處理。
------------------------------------------------------------------------------------------------
WarpPerspective
對圖像進行透視變換
void cvWarpPerspective( const CvArr* src, CvArr* dst,const CvMat* map_matrix,
int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,
CvScalar fillval=cvScalarAll(0) );
src
輸入圖像.
dst
輸出圖像.
map_matrix
3×3 變換矩陣
flags
插值方法和以下開關選項的組合:
· CV_WARP_FILL_OUTLIERS- 填充所有縮小圖像的象素。如果部分象素落在輸入圖像的邊界外,那么它們的值設定為 fillval.
· CV_WARP_INVERSE_MAP- 指定 matrix 是輸出圖像到輸入圖像的反變換,因此可以直接用來做象素插值。否則, 函數從 map_matrix 得到反變換。
fillval
用來填充邊界外面的值
函數 cvWarpPerspective 利用下面指定矩陣變換輸入圖像:
- 如果沒有指定 CV_WARP_INVERSE_MAP ,
- 否則,
要變換稀疏矩陣,使用 cxcore 中的函數 cvTransform 。
-----------------------------
GetPerspectiveTransform
由四對點計算透射變換
CvMat* cvGetPerspectiveTransform( const CvPoint2D32f*src, const CvPoint2D32f* dst,
CvMat*map_matrix );
#define cvWarpPerspectiveQMatrixcvGetPerspectiveTransform
src
輸入圖像的四邊形頂點坐標。
dst
輸出圖像的相應的四邊形頂點坐標。
map_matrix
指向3×3輸出矩陣的指針。
函數cvGetPerspectiveTransform計算滿足以下關系的透射變換矩陣:
這里,dst(i)= (x'i,y'i),src(i)= (xi,yi),i = 0..3.
------------------------------------------------------------------------------------------------
/*code*/
- #include <highgui.h>
- #include <cv.h>
- int main(int argc, char** argv)
- {
- CvPoint2D32f srcTri[4], dstTri[4]; //二維坐標下的點,類型為浮點
- //CvMat* rot_mat = cvCreateMat( 2, 3, CV_32FC1 ); //多通道矩陣
- CvMat* warp_mat = cvCreateMat( 3, 3, CV_32FC1 );
- IplImage *src, *dst;
- if( argc == 2 && ( ( src = cvLoadImage( argv[1], 1 ) ) != 0 ) )
- {
- dst = cvCloneImage( src ); //制作圖像的完整拷貝
- dst ->origin = src ->origin;
- /*
- int origin; /* 0 - 頂—左結構,
- 1 - 底—左結構 (Windows bitmaps 風格)
- */
- 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;
- srcTri[3].x = src -> width - 1; //bot right
- srcTri[3].y = src -> height - 1;
- //改變目標圖像大小
- dstTri[0].x = src -> width * 0.05;
- dstTri[0].y = src -> height * 0.33;
- dstTri[1].x = src -> width * 0.9;
- dstTri[1].y = src -> height * 0.25;
- dstTri[2].x = src -> width * 0.2;
- dstTri[2].y = src -> height * 0.7;
- dstTri[3].x = src -> width * 0.8;
- dstTri[3].y = src -> height * 0.9;
- cvGetPerspectiveTransform( srcTri, dstTri, warp_mat ); //由三對點計算仿射變換
- cvWarpPerspective( src, dst, warp_mat ); //對圖像做仿射變換
- //輸出
- cvNamedWindow( "Perspective Warp", 1 );
- cvShowImage( "Perspective Warp", dst ); //最終是輸出dst
- cvWaitKey();
- }
- cvReleaseImage( &dst );
- cvReleaseMat( &warp_mat );
- return 0;
- }