导读
在上篇文章中,我们介绍了仿射变换,我们只需要通过一个两行三列的变换矩阵M就能够对图像实现平移、缩放、翻转、旋转操作。这些变换其实都属于平面变换,如果我们想要进行空间变换呢?
![dfaf144f28c03fe8444251e138d9e961.png](https://i-blog.csdnimg.cn/blog_migrate/203f84a273bf67e66ea117a325fc51ec.jpeg)
原始图像
将上图的扑克牌单独提取出来,如下图所示
![ea0a980a59fcd01531d1e38a10b6c30f.png](https://i-blog.csdnimg.cn/blog_migrate/e7d83dc16342fa0b0882aa86d571a9e0.jpeg)
目标图像
这时候我们应该如何来实现这个功能呢?这个其实就涉及到了图像的一个空间变换,就需要用到我们所说的透视变换了。
透视变换
透视变换(Perspective Transformation)是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。简而言之,就是将一个平面通过一个投影矩阵投影到指定平面上。
![07eeaae2bf1899bda4a74e17e44854fe.png](https://i-blog.csdnimg.cn/blog_migrate/dfee3bfc32c15b5e98fef14731fb2361.jpeg)
- 原理解析
透视变换通用的变换公式:
![74a5e6dad01d4a13900b87b1ce624b1b.png](https://i-blog.csdnimg.cn/blog_migrate/060bdf29f2f50b983b2fdf874c2598af.jpeg)
u和v是原始图片,参数ω等于1,通过透视变换后得到的图片坐标x,y,其中
![15b2c3f7b47f0c8ad4c058952bd9ae1f.png](https://i-blog.csdnimg.cn/blog_migrate/52c76bc356eb61fa4f716e1247da8901.jpeg)
上式中的变换矩阵,可以将其拆成四个部分,第一部分表示线性变换:
![295458c9b9e6ba5b18a5a1025e903d21.png](https://i-blog.csdnimg.cn/blog_migrate/779f78fa8603828be9300f4746c75f47.jpeg)
这部分矩阵主要用于图像的缩放、旋转操作,在仿射变换中我们也介绍过。第二部分用来进行平移操作[a31a32],第三部分用来产生透视变换[a13a23],第四部分参数a33等于1。
在上篇文章中我们介绍的仿射变换矩阵一共有6个参数,所以我们只需要3个坐标对(6个方程)就能求解,而透视变换矩阵一共有8个参数,所以需要4个坐标对(8个方程)才能求解,其实仿射变换也是透视变换的一种特殊形式。
所以变换后x和y的表达式为
![30fee76ec9fb1610cc65f05c68f47537.png](https://i-blog.csdnimg.cn/blog_migrate/2bcacb69f7bd05b3458a69638bdfed6d.jpeg)
接下来我们看一个例子,原始图像的四个点的坐标分别为(0,0)、(1,0)、(1,1)、(0,1)与之对应变换后的四个点坐标分别为(x1,y1)、(x2,y2)、(x3,y3)、(x4,y4),根据上面的公式和对应的四个点坐标可得下面的方程式
![b03f9b70689701b25a43e3760be05e4e.png](https://i-blog.csdnimg.cn/blog_migrate/2e60ca7b8ee15892727437836324e248.jpeg)
通过上面的8个方程,我们可以解出8个参数求出透视变换矩阵,最后我们通过opencv的warpPerspective方法利用透视变换矩阵来实现透视变换,接下来我们通过结合一个实例来具体运用一下。
透视变换实例讲解
这里我们主要通过opencv来实现上面介绍的那个功能
- 读取图像
![89febccc4565d2fbb2df890ad0140927.png](https://i-blog.csdnimg.cn/blog_migrate/c19e0a08953dc76f3065ea6336653e94.jpeg)
- Canny边缘检测
Canny函数参数解析:
- image:输入图像数组
- threshold1:最低的阈值
- threshold2:最高的阈值
- edges:输出的边缘图像,单通道8位图像
- apertureSize:Sobel算子的大小
- L2gradient:表示一个布尔值,如果为真,则使用更精确的L2范数进行计算,否则使用L1范数
![6894d0600b2b9877f19133e6b760f528.png](https://i-blog.csdnimg.cn/blog_migrate/1826c0a36110162045d70a390dc6a7eb.jpeg)
![87760a16a0bbd2b9603b4de15e8cdf5d.png](https://i-blog.csdnimg.cn/blog_migrate/acbc148b250942c310a717e68f21b997.jpeg)
- 霍夫直线检测
HoughLinesP函数参数解析:
- image:经过Canny边缘检测后的输出图像
- rho:极坐标的半径r以像素值为单位的分辨率,一般使用1像素
- theta:极坐标的极角θhetaθ以弧度为单位的分辨率,一般使用1度
- threshold:检测一条直线所需最少的曲线交点
- lines:存储检测到的直线,包含直线的起点和终点坐标
- minLineLength:组成一条直线的最少点的数量,点数量不足的直线将被抛弃
- maxLineGap:在一条直线上的点的最大距离
![5c55bb83a2ad6a5364b853f9a931bb1f.png](https://i-blog.csdnimg.cn/blog_migrate/36815e7b42a78ff4cc7eb93e2dc86032.jpeg)
![0b5f9b661157dfc90a85c4ec456c1c6a.png](https://i-blog.csdnimg.cn/blog_migrate/2244235873a6e44f18f43f053025a0d7.jpeg)
- 计算顶点坐标
通过直线两个端点的坐标来计算直线的交点坐标,找出扑克牌的四个顶点位置
![3422f1fc26e250c1e0b5871490ec1c23.png](https://i-blog.csdnimg.cn/blog_migrate/85ca5cf695dd40c2c60177d9a69da7a2.jpeg)
![23e66ca86f7e1e9e101c7897852b8938.png](https://i-blog.csdnimg.cn/blog_migrate/aca6ff5a8e6ce2b96894361affe19767.jpeg)
- 对顶点坐标进行排序
在计算透视变换矩阵之前我们需要对元素图像的坐标与变换后图像的坐标一一对应,按照左->上->右->下的顺序
![274b3a7df32cf51b2267b01fc9188dab.png](https://i-blog.csdnimg.cn/blog_migrate/2ff1b563acdfe84d05d89466bcf671be.jpeg)
- 计算变换矩阵进行透视变换
![4d3013579844b57bc5fa8cacfb3d2f7f.png](https://i-blog.csdnimg.cn/blog_migrate/5883c6342e1633a0d7379060a6541ab8.jpeg)
![8e02c196da05976ee3fd7abd4ecbf057.png](https://i-blog.csdnimg.cn/blog_migrate/ff7b9eda9b27916d5253d8b7a82015cc.jpeg)