仿射變換的作用是將圖像做旋轉、拉伸。
仿射變換是通過一個中間矩陣來使源圖像像素的位置變換到指定的目標圖像的像素的位置,原理類似於上文的remapping。
所以仿射變換也是矩陣的一種運用。
於是仿射變換一般分成兩步:第一、尋找變換的中間矩陣;第二、進行變換。
要找到變換的中間矩陣,一般使用三個點來尋找它,因為用三角形我們可以表現出變換的尺度和角度。在OpenCV中,我們使用getAffineTransform。
進行變換時,我們使用warpAffine函數。
Mat getAffineTransform(InputArray src, InputArray dst)
src和dst使用Point2f是數組(大小為3)即可。
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
這里的M就是上面getAffineTransform得到的返回值。
dsize是輸出的尺寸,取dst的尺寸就行。
另外,可以使用getRotationMatrix2D來得到M。
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
center為旋轉之后的圖像的中心
angle為旋轉的角度,正為逆時針,負為順時針。
scale為縮放的因子,比如可以為0.5
OpenCV當中的例子:
1 /** 2 * @function Geometric_Transforms_Demo.cpp 3 * @brief Demo code for Geometric Transforms 4 * @author OpenCV team 5 */ 6 7 #include "opencv2/highgui/highgui.hpp" 8 #include "opencv2/imgproc/imgproc.hpp" 9 #include <iostream> 10 #include <stdio.h> 11 12 using namespace cv; 13 using namespace std; 14 15 /// Global variables 16 const char* source_window = "Source image"; 17 const char* warp_window = "Warp"; 18 const char* warp_rotate_window = "Warp + Rotate"; 19 20 /** 21 * @function main 22 */ 23 int main( int, char** argv ) 24 { 25 Point2f srcTri[3]; 26 Point2f dstTri[3]; 27 28 Mat rot_mat( 2, 3, CV_32FC1 ); 29 Mat warp_mat( 2, 3, CV_32FC1 ); 30 Mat src, warp_dst, warp_rotate_dst; 31 32 /// Load the image 33 src = imread( argv[1], 1 ); 34 35 /// Set the dst image the same type and size as src 36 warp_dst = Mat::zeros( src.rows, src.cols, src.type() ); 37 38 /// Set your 3 points to calculate the Affine Transform 39 srcTri[0] = Point2f( 0,0 ); 40 srcTri[1] = Point2f( src.cols - 1.f, 0 ); 41 srcTri[2] = Point2f( 0, src.rows - 1.f ); 42 43 dstTri[0] = Point2f( src.cols*0.0f, src.rows*0.33f ); 44 dstTri[1] = Point2f( src.cols*0.85f, src.rows*0.25f ); 45 dstTri[2] = Point2f( src.cols*0.15f, src.rows*0.7f ); 46 47 /// Get the Affine Transform 48 warp_mat = getAffineTransform( srcTri, dstTri ); 49 50 /// Apply the Affine Transform just found to the src image 51 warpAffine( src, warp_dst, warp_mat, warp_dst.size() ); 52 53 /** Rotating the image after Warp */ 54 55 /// Compute a rotation matrix with respect to the center of the image 56 Point center = Point( warp_dst.cols/2, warp_dst.rows/2 ); 57 double angle = -50.0; 58 double scale = 0.6; 59 60 /// Get the rotation matrix with the specifications above 61 rot_mat = getRotationMatrix2D( center, angle, scale ); 62 63 /// Rotate the warped image 64 warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() ); 65 66 67 /// Show what you got 68 namedWindow( source_window, WINDOW_AUTOSIZE ); 69 imshow( source_window, src ); 70 71 namedWindow( warp_window, WINDOW_AUTOSIZE ); 72 imshow( warp_window, warp_dst ); 73 74 namedWindow( warp_rotate_window, WINDOW_AUTOSIZE ); 75 imshow( warp_rotate_window, warp_rotate_dst ); 76 77 /// Wait until user exits the program 78 waitKey(0); 79 80 return 0; 81 }