什么是仿射变换:
一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移).
仿射变换可以实现什么功能:
旋转
平移
缩放操作
怎样得到一个仿射变换:
放射变换代表的是两幅图之间的关系。
通过原图和目标图像三个点之间的对应关系,可以求出一个2 X 3的矩阵。
我们通常使用2 x 3矩阵来表示仿射变换。
怎样去旋转一个图像:
- 确定旋转图像的中心点
- 旋转的角度. 在OpenCV中正角度是逆时针的
- 可选择:缩放因子
- rot_mat = getRotationMatrix2D( center, angle, scale );求出旋转矩阵
- warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() );把旋转通过仿射变换对应到目标图像上。
代码:
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include <iostream> #include <stdio.h> using namespace cv; using namespace std; /// 全局变量 char* source_window = "Source image"; char* warp_window = "Warp"; char* warp_rotate_window = "Warp + Rotate"; /** @function main */ int main( int argc, char** argv ) { Point2f srcTri[3]; Point2f dstTri[3]; Mat rot_mat( 2, 3, CV_32FC1 ); Mat warp_mat( 2, 3, CV_32FC1 ); Mat src, warp_dst, warp_rotate_dst; /// 加载源图像 src = imread( "1.jpg", 1 ); /// 设置目标图像的大小和类型与源图像一致 warp_dst = Mat::zeros( src.rows, src.cols, src.type() ); /// 设置源图像和目标图像上的三组点以计算仿射变换 srcTri[0] = Point2f( 0,0 ); srcTri[1] = Point2f( src.cols - 1, 0 ); srcTri[2] = Point2f( 0, src.rows - 1 ); dstTri[0] = Point2f( src.cols*0.0, src.rows*0.33 ); dstTri[1] = Point2f( src.cols*0.85, src.rows*0.25 ); dstTri[2] = Point2f( src.cols*0.15, src.rows*0.7 ); /// 求得仿射变换 得到一个矩阵 2 x 3的矩阵 warp_mat = getAffineTransform( srcTri, dstTri ); /// 对源图像应用上面求得的仿射变换 warpAffine( src, warp_dst, warp_mat, warp_dst.size() ); /*src: 输入源图像 warp_dst: 输出图像 warp_mat: 仿射变换矩阵 warp_dst.size(): 输出图像的尺寸*/ /** 对图像扭曲后再旋转 */ /// 计算绕图像中点顺时针旋转50度缩放因子为0.6的旋转矩阵 Point center = Point( warp_dst.cols/2, warp_dst.rows/2 ); double angle = -50.0; double scale = 0.6; /// 通过上面的旋转细节信息求得旋转矩阵 rot_mat = getRotationMatrix2D( center, angle, scale ); /// 旋转已扭曲图像 warpAffine( warp_dst, warp_rotate_dst, rot_mat, warp_dst.size() ); /// 显示结果 namedWindow( source_window, CV_WINDOW_AUTOSIZE ); imshow( source_window, src ); namedWindow( warp_window, CV_WINDOW_AUTOSIZE ); imshow( warp_window, warp_dst ); namedWindow( warp_rotate_window, CV_WINDOW_AUTOSIZE ); imshow( warp_rotate_window, warp_rotate_dst ); /// 等待用户按任意按键退出程序 waitKey(0); return 0; }
————————————————
版权声明:本文为CSDN博主「南山二毛」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_16481211/article/details/79634506

