目录
1.1、warpAffine(src, dst, M, dst_sz, flags, borderMode, Scalar&borderMode)
1.2、Mat M = getRotationMatrix2D(center, angle, scale)
1.3、Mat M1 = getAffineTransform(srcPoints, dstPoints)
1、用到的重要函数介绍
1.1、warpAffine(src, dst, M, dst_sz, flags, borderMode, Scalar&borderMode)
这个函数的作用是根据M将图像进行仿射,重要的是前4个参数,最关键的是M的求取。
参数名 | 说明 |
src | 输入图像 |
dst | 输出图像 |
M | 仿射矩阵,后面会给出计算方法 |
dst_sz | 输出图像的大小 |
flags | 变换后的要用到的插值方式 |
borderMode | 像素外推方法 |
Scalar&borderMode | 边界上多余的部分颜色范围 |
1.2、Mat M = getRotationMatrix2D(center, angle, scale)
这个函数是求出M的一种方式,主要可以实现旋转和缩放。
参数名 | 说明 |
center | 旋转的中心,一般是图像的中心位置 |
angle | 旋转角度(顺时针) |
scale | 缩放比例,如0.5是将图像缩小为原来的1/2 |
1.3、Mat M1 = getAffineTransform(srcPoints, dstPoints)
这个函数可以得到平移、旋转、缩放、投射等一系列操作,实际上是通过前后四个点的位置变化来控制。个人感觉,在平移和缩放上不如1.2介绍的getRotationMatrix2D()好用。
参数名 | 说明 |
srcPoints | 输入的4个点位 |
dstPoints | 想要仿射变换变成的4个位置 |
2、基于VS的实现
2.1、旋转与缩放
Mat src = imread("C:/Users/含笑韭泉/Desktop/图片2.png",2);
Mat dst;
Size dst_sz(src.cols, src.rows);
//旋转和缩放
Point center(static_cast<float>(src.cols / 2.), static_cast<float>(src.rows / 2.)); //static_cast<float>()强制类型转换,一定要确保数据类型正确
double angle = 15; //旋转角度
double scale = 0.5; //缩放比例
Mat M = getRotationMatrix2D(center, angle, scale); //获得旋转的仿射矩阵
warpAffine(src, dst, M, dst_sz, 1,0,(255, 255, 255)); //仿射变换:一般用前4个参数就行了, 最有一个参数是边界颜色,flags:内插方法,borderMode:像素外推方法
namedWindow("image show");
imshow("image show",dst);
waitKey();
以上代码是在主函数内部的,使用了命名空间。这段代码实现了图片的15度角顺时针旋转和0.5倍缩放,效果如下:
左边是原图,右边是旋转+缩放的效果。
2.2、平移和翻转
//平移和翻转
int m, n;
m = 400;//左右移动
n = -200;//上下移动
Point2f srcPoints[3], dstPoints[3];
srcPoints[0] = Point2f(0, 0);//左上/原点
srcPoints[1] = Point2f(0, src.rows);//左下角
srcPoints[2] = Point2f(src.cols, 0);//右上角
//----------------------------------------------------//
//平移使用以下3行:
//dstPoints[0] = Point2f(0 + m, 0 + n);
//dstPoints[1] = Point2f(0 + m, src.rows + n);
//dstPoints[2] = Point2f(src.cols + m, 0 + n);
//翻转使用以下3行:
dstPoints[0] = Point2f(0 + src.cols, 0);
dstPoints[1] = Point2f(0 + src.cols, src.rows);
dstPoints[2] = Point2f(src.cols - src.cols, 0);
//----------------------------------------------------//
Mat M1 = getAffineTransform(srcPoints, dstPoints);
warpAffine(src, dst, M1, dst_sz, 1, 0, (255, 255, 255));
namedWindow("image show2");
imshow("image show2", dst);
waitKey();
使用这个函数首先要对OpenCV坐标系有了解,起码像我这样matlab转过来的还是有点不适应。上面的代码注释了一部分,运行只会出现左右翻转的图片(这个需要构思好,或者打个草稿),我这边就直接将平移和翻转效果一起放上来了。其中,平移就是将代码中的特别标注的部分交换一下。如下:
左边是平移400,-200后的位置,右边是左右翻转后的位置。
2.3、其他投影
//投影(透视视角)变换
Point2f srcPoints1[4], dstPoints1[4];
srcPoints1[0] = Point2f(0, 0);//左上/原点
srcPoints1[1] = Point2f(0, src.rows);//左下角
srcPoints1[2] = Point2f(src.cols, 0);//右上角
srcPoints1[3] = Point2f(src.cols, src.rows);//右下角
//前4点到后4点变换
dstPoints1[0] = Point2f(0 + 200, 0 + 200);
dstPoints1[1] = Point2f(0 + 100, src.rows);
dstPoints1[2] = Point2f(src.cols, 0 + 100);
dstPoints1[3] = Point2f(src.cols, src.rows);
//获取设计好的仿射矩阵
Mat M2 = getAffineTransform(srcPoints1, dstPoints1);
warpAffine(src, dst, M2, dst_sz, 1, 0, (255, 255, 255));
namedWindow("image show3");
imshow("image show3", dst);
waitKey();
这个获取仿射矩阵M的方式与上一节一样,我感觉这种就像矩形包含在多边形里面一样,这个也是需要预先设计好。效果如下:
3、总结
主要是通过仿射变换函数warpAffine来进行图像的平移、旋转、缩放、翻转和其他变换,需要用到getRotationMatrix2D函数和getAffineTransform函数来获得所需要的仿射变换矩阵。