仿射变换的作用是将图像做旋转、拉伸。
仿射变换是通过一个中间矩阵来使源图像像素的位置变换到指定的目标图像的像素的位置,原理类似于上文的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 }