OpenCV:图像变换-仿射变换与透视变换研究

                                           

                      

上面三幅图分别为标志图形、道路标线、QR码的校正前后图,校正采用的是透视变换矩阵。

下面就主要研究一下透视变换。

1. 概念

透视变换(Perspective Transformation)是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。

上面是百度百科上关于透视变换的定义。(看了一遍没看懂)

讲到透视变换通常也会听到仿射变换,那么透视变换和仿射变换有什么区别呢?

简单看一眼下图,基本可以从图中看出仿射变换和透视变换的区别:仿射变换可以把图像放大、缩小、旋转、或者是变成平行四边形,而透视变换除了获得仿射变换的这些效果之外,还能将图片变成梯形,具有更高的自由度。

                                                                

仿射变换:

仿射变换是一种二维坐标到二维坐标之间的线性变换,它保持了二维图形的“平直性”(直线经过变换之后依然是直线)和“平行性”(二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变)。任意的仿射变换都能表示为乘以一个矩阵(线性变换),再加上一个向量 (平移) 的形式.

                                                                 

透视变换即投影矩阵H:

透视变换是将图片投影到一个新的视平面,也称作投影映射.它是二维(x,y)到三维(X,Y,Z),再到另一个二维(x’,y’)空间的映射. 
相对于仿射变换,它提供了更大的灵活性,将一个四边形区域映射到另一个四边形区域(不一定是平行四边形).它不止是线性变换.但也是通过矩阵乘法实现的,使用的是一个3x3的矩阵,矩阵的前两行与仿射矩阵相同(m11,m12,m13,m21,m22,m23),也实现了线性变换和平移,第三行用于实现透视变换;

                                                 

其中,(u,v)为变换前的坐标,(x‘,y')为变换后的坐标;

由上述公式可知,仿射变换有6个未知数,透视变换有8个未知数,因此仿射变换矩阵的求解只需3组映射点(三点确定一个平面),透视变换矩阵的求解只需4组点构成8个方程(四点确定一个三维空间)。

2. 透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,

其通用变换公式为:

                                                    

透视变换矩阵元素的含义:

                                                  

注:平移、缩放、旋转矩阵 https://blog.csdn.net/baidu_38172402/article/details/88920639

3. opencv函数形式

仿射变换函数:

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

仿射变换矩阵生成函数:

Mat getAffineTransform(const Point2f* src, const Point2f* dst)
//@param: const Point2f* src:原图的三个固定顶点
//@param: const Point2f* dst:目标图像的三个固定顶点
//@return:仿射变换矩阵,可直接用于warpAffine()函数
//顶点数组长度超过3个,则会自动以前3个为变换顶点;

透视变换函数:

void warpPerspective(InputArray src, 
                     OutputArray dst, 
                     InputArray M, 
                     Size dsize, 
                     int flags=INTER_LINEAR, 
                     int borderMode=BORDER_CONSTANT, 
                     const Scalar& borderValue=Scalar())
Mat getPerspectiveTransform(const Point2f* src, const Point2f* dst)
//@param: src,dst原始点和目标点,个数>=4
//@:透视变换顶点为4个。

参考文章:

1.  https://mp.weixin.qq.com/s/b10zBadlvrSCeXVnrYHwHQ

2.  https://blog.csdn.net/yong_qi2015/article/details/80108276

3.  https://www.cnblogs.com/liekkas0626/p/5262942.html

4.  https://blog.csdn.net/hitwengqi/article/details/6890220 

5.  http://m.elecfans.com/article/593459.html

6. https://blog.csdn.net/flyyufenfei/article/details/80208361仿射变换和透视变换的区别

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值