matlab 通过矩阵变换使图像旋转平移_【图像处理】OpenCV系列十六 --- 仿射变换warpAffine...

上一节我们学习了如何对一幅图像进行放大与缩小(resize函数)以及对插值算的原理进行了分析,相信大家对图像如何进行放大与缩小已经有了清晰的理解,那么我们这节学习OpenCV中比较重要的内容,即仿射变换(warpAffine),仿射变换可以实现对稍微倾斜的图片进行矫正哦!!那么接下来我们就正式进入仿射变换的学习吧!

一、原理

仿射变换的功能是从二维坐标到二维坐标之间的线性变换,且保持二维图形的“平直性”和“平行性”。仿射变换可以通过一系列的原子变换的复合来实现,包括平移,缩放,翻转,旋转和剪切。

这类变换可以用一个3*3的矩阵M来表示,其最后一行为(0,0,1)。该变换矩阵将原坐标为(x,y)变换为新坐标(x',y')

3c8e218575ac2b034b5a5ca7f5f3cd81.png

仿射变换

典型的仿射变换

1、平移

将每一点移到到(x+t , y+t),变换矩阵为

38211a7efd765ffa35bf20925d4a8d57.png

平移

2、缩放变换

将每一点的横坐标放大或缩小s_x倍,纵坐标放大(缩小)到s_y倍,变换矩阵为

2f8940cc23c0ec4d845df9d0cd4991b3.png

缩放变换

3、旋转变换原点

目标图形围绕原点顺时针旋转Θ 弧度,变换矩阵为

9a04417f5b5b6e5485f6a2708e4ba5d6.png

旋转变换原点

4、旋转变换

目标图形以(x , y )为轴心顺时针旋转θ弧度,变换矩阵为

30340f77ef34270d731651b3b22584f6.png

旋转变换

二、OpenCV中warpAffine()相关函数详解

(一)warpAffine()函数

1、函数原型

void warpAffine(InputArray src,  OutputArray dst, InputArray M,  Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar());

2、函数功能

对图像进行仿射变换,当函数的参数flags设置为 WARP_INVERSE_MAP时,函数使用下面的矩阵进行仿射变换:

2418dbb02fba1e619c70a48f9eca8445.png

仿射变换

否则,函数将首先使用逆仿射变换的转置,然后用上面的公式代替M,并且该函数不支持就地操作。

3、参数详解

  • 第一个参数,InputArray src,原图像;
  • 第二个参数,OutputArray dst,目标图像,并且该图像与原图像的尺寸和类型都是一样的;
  • 第三个参数,InputArray M,2 x 3的变换矩阵;
  • 第四个参数,Size dsize,目标图像的大小;
  • 第五个参数,int flags = INTER_LINEAR,插值算法的标识符,默认为线性插值(INTER_LINEAR),如果插值算法为WARP_INVERSE_MAP,则函数使用下面的上面的公式[放射变换]进行图像转换;
  • 第六个参数,int borderMode = BORDER_CONSTANT,边界像素的模式,默认值为BORDER_CONSTANT;
  • 第七个参数,const Scalar& borderValue = Scalar(),边界取值,默认值为Scalar()。

4、实例

#include #include #include #include using namespace std;using namespace cv;//全局变量String src_windowName = "原图像";String warp_windowName = "仿射变换";String warp_rotate_windowName = "仿射旋转变换";String rotate_windowName = "图像旋转";int main(){ Point2f srcTri[3]; Point2f dstTri[3]; Mat rot_mat(2, 3, CV_32FC1); Mat warp_mat(2, 3, CV_32FC1); Mat srcImage, warp_dstImage,  warp_rotate_dstImage, rotate_dstImage; //加载图像 srcImage = imread("lena.png"); //判断文件是否加载成功 if (srcImage.empty()) { cout << "图像加载失败!" << endl; return -1; } else cout << "图像加载成功!" << endl << endl; //创建仿射变换目标图像与原图像尺寸类型相同 warp_dstImage = Mat::zeros(srcImage.rows,  srcImage.cols, srcImage.type()); //设置三个点来计算仿射变换 srcTri[0] = Point2f(0, 0); srcTri[1] = Point2f(srcImage.cols - 1, 0); srcTri[2] = Point2f(0, srcImage.rows - 1); dstTri[0] = Point2f(srcImage.cols*0.0,  srcImage.rows*0.33); dstTri[1] = Point2f(srcImage.cols*0.85,  srcImage.rows*0.25); dstTri[2] = Point2f(srcImage.cols*0.15,  srcImage.rows*0.7); //计算仿射变换矩阵 warp_mat = getAffineTransform(srcTri, dstTri); //对加载图形进行仿射变换操作 warpAffine(srcImage, warp_dstImage,  warp_mat, warp_dstImage.size()); //计算图像中点顺时针旋转90度,缩放因子为0.6的旋转矩阵 Point center = Point(warp_dstImage.cols / 2,  warp_dstImage.rows / 2); double angle = -90.0; double scale = 0.6; //计算旋转矩阵 rot_mat = getRotationMatrix2D(center, angle, scale); //旋转已扭曲图像 warpAffine(warp_dstImage, warp_rotate_dstImage,  rot_mat, warp_dstImage.size()); //将原图像旋转 warpAffine(srcImage, rotate_dstImage,  rot_mat, srcImage.size()); //显示变换结果 namedWindow(src_windowName, WINDOW_AUTOSIZE); imshow(src_windowName, srcImage); namedWindow(warp_windowName, WINDOW_AUTOSIZE); imshow(warp_windowName, warp_dstImage); namedWindow(warp_rotate_windowName, WINDOW_AUTOSIZE); imshow(warp_rotate_windowName, warp_rotate_dstImage); namedWindow(rotate_windowName, WINDOW_AUTOSIZE); imshow(rotate_windowName, rotate_dstImage); waitKey(0); return 0;}

实验结果

ef5c42625de8f6cd539b1f7877827d64.png

原图

a7060f748056385cfa06e58d75ac3070.png

仿射变换、仿射旋转变换、图像旋转90度

(二)getAffineTransform()函数

1、函数原型

Mat getAffineTransform(const Point2f src[],  const Point2f dst[]);

2、函数功能

从三对相对应的点计算图像的仿射变换。

3、参数详解

  • 第一个参数,const Point2f src[],坐标系中,原图像中三角形的坐标;
  • 第二个参数,const Point2f dst[],坐标系中,目标图像中相应的(相对于原图像)三角型的坐标;
  • 返回值为Mat类型的图像。

(三)getRotationMatrix2D()函数

1、函数原型

Mat getRotationMatrix2D(Point2f center, double angle, double scale);

2、函数功能

计算二维图像旋转的放射变换。

3、参数详解

  • 第一个参数,Point2f center,原图像的旋转中心坐标;
  • 第二个参数,double angle,旋转的角度,假定坐标原点为左上角,角度为正值的话,按逆时针的方向进行旋转,角度为负值的话,按顺时针的角度进行旋转;
  • 第三个参数,double scale,图像的缩放因子;
  • 返回值为Mat类型的图像。

三、综合实例

使用findTransformECC()函数实现图像对齐ECC算法

437f93674c014e170d7214d383703981.png
cdb6cb74a5412dd470fa9044d877ad55.png
fd5ef62097af133de1bc96435cfcc7de.png
78be9c701e459b3c6781e7e2280cec39.png
faee0064474e3651ddcf0959b928accf.png
84577b1fe58d763e07720cf61848c546.png
938d0dd5b02997a0ebc0e24ab9cf5b15.png
2ad0de43d1131fdc2199182994053809.png
1446df1e6d3e647728baf2bd135d31a8.png
29dd479808c9c33badfbe15c040d11ff.png
39aab420ae41bdbf56845aa327d76f19.png
3db7853ca9a10a088443ac43b3456379.png
2c0edc6197e3fc6ad3712240a9462962.png
9730e652b392b36ff30350e766455b03.png
4f2837773ddef09231c0ab70e3df6203.png
87bebeb6acbd6386305358b329c9b3d8.png

实验结果

2586f19221ee753cdcdf1a0f947c16f7.png

实验结果

好了,今天的学习到这里就结束了,希望大家可以认真学习学习每一节知识,加油,相信大家可以的!喜欢的朋友也可以给我点个赞哦!!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值