C++ opencv图像旋转

1.图像几何变换和图像变换

为了更好的理解图像翻转,图像旋转等,我们首先介绍一下变换相关的概念

图像的变换,从严格意义上来说分为两种

几何变换
图像变换

简述
图像几何变换:

改变图像的大小或形状。
比如图像的平移、旋转、放大、缩小等,这些方法在图像配准中使用较多。

图像变换:

通过数学映射的方法,将空域的图像信息转换到频域、时频域等空间上进行分析。
比如傅里叶变换、小波变换等。
 

区别

(1)性质

图像几何变换是从具有几何结构之集合至其自身或其他此类集合的一种对射。
图像变换将原定义在图像空间的图像以某种形式转换到另外的空间,利用空间的特有性质方便地进行一定的加工,最后再转换回图像空间以得到所需的效果。
(2)包括

图像几何变换包括翻折变换、平移变换、旋转变换等。
图像变换包括傅里叶变换、沃尔什-阿达玛变换等。
(3)原始图像

图像几何变换的原始图像为平面域图像。
图像变换的原始图像为空间域图像。
 

图像几何变换

三类变换 基本变换、仿射变换和透视变换
刚性变换:

只有物体的位置(平移变换)和朝向(旋转变换)发生改变,而形状不变,得到的变换称为刚性变换。

仿射变换:

仿射变换是从一个二维坐标系变换到另一个二维坐标系,属于线性变换。
通过已知3对坐标点可以求得变换矩阵。

透视变换: 旋转

透视变换是从一个二维坐标系变换到一个三维坐标系,属于非线性变换。
通过已知4对坐标点可以求得变换矩阵。


图像的几何变换包含很多变换,其中有一些变换,具体如下

平移(Translation)
缩放(Scale)
旋转(Rotation)
翻转(Flip)
错切(Shear)

而仿射变换和透视变换就是对这些基本变换进行组合实现的

也就是说,仿射变换和透视变换包含所有的基本变换,同时也作为基本变换的某种组合

在opencv中,针对它们已经封装好了对应的API,分别为

仿射变换 - warpAffine
透视变换 - warpPerspective

说回图像旋转

从上文我们知道了一些关键点

图像旋转就是图像几何变换中,基本变换的一种
仿射变换和透视变换包含所有的基本变换
所以我们可以通过仿射变换API——warpAffine实现图像旋转

在opencv中,如果我们想对一个图像进行旋转,要用到两个API

warpAffine
getRotationMatrix2D
 

变换矩阵


介绍完毕后,我们知道图像旋转的关键就是那个变换矩阵
变换矩阵可以由getRotationMatrix2D得到

现在我们来研究一下得到的变换矩阵

由于本变换矩阵是由getRotationMatrix2D得到,是专门对标仿射变换API的
在opencv中规定其为2行3列的矩阵。

在这里插入图片描述
当旋转的角度为Θ,且旋转中心为x,y时,即这个矩阵的通式为

在这里插入图片描述


当旋转中心为左上角时,这时候的变换矩阵为

在这里插入图片描述
像素点位置
最后当我们调用warpAffinie时,经过如下公式的计算,就能得到变换后的像素点位置
我们就能实现图像旋转

在这里插入图片描述

2.仿射相关API

1.warpAffine   仿射变换


        共7个参数
            第1个参数 输入
            第2个参数 输出
            第3个参数 输入的变换矩阵(2行3列)
            第4个参数 输出图像的size
            第5个参数 插值方法
            第6个参数 边界模式(暂且不学习。深入探讨的话,还会涉及很多的东西)
            第7个参数 边界颜色(暂且不学习。深入探讨的话,还会涉及很多的东西)


2.getRotationMatrix2D     计算二维旋转的仿射矩阵

    共3个参数
            第1个参数 图像的旋转中心
            第2个参数 旋转角度
                        (规定坐标原点左上角,正值表示逆时针旋转)
            第3个参数 各向同性比例因子(对图像本身大小的放缩)

3.实例代码

处理方法如下:
在这里插入图片描述
通过如上图,我们可以计算新图像的宽度,高度,旋转中心的通式

  • 新宽度nw = wcosΘ + hsinΘ
  • 新宽度nh = wsinΘ + hcosΘ
  • 新旋转中心x +=( nw/2 - w/2)
  • 新旋转中心y +=( nh/2 - h/2)
void QuickDemo::rotate_demo(Mat& image) {

	Mat dst, M;//M为变换矩阵

	int w = image.cols;
	int h = image.rows;
	M = getRotationMatrix2D(Point2f(w / 2, h / 2), 45, 1.0);

	//C++的abs则可以自然支持对整数和浮点数两个版本(实际上还能够支持复数)
	double cos = abs(M.at<double>(0, 0));
	double sin = abs(M.at<double>(0, 1));

	int nw = w * cos + h * sin;
	int nh = w * sin + h * cos;

	//新图像的旋转中心
	M.at<double>(0, 2) += (nw / 2 - w / 2);
	M.at<double>(1, 2) += (nh / 2 - h / 2);

	warpAffine(image, dst, M, Size(nw,nh),INTER_LINEAR,0,Scalar(0,200,0));

	imshow("旋转演示", dst);

}

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打酱油的;

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值