透视变换(Perspective Transformation)是什么,无需多说,但是一个非常惨痛的现实是如果你想知道怎么样才能在编程做,你只能得到一些调用opencv函数的文章,简直有病,谁不会调用函数,我搜索实现肯定是要找代码参考看下是怎么实现算法的,你调用函数还敢叫自己“实现”?那我用调用Django的模块是不是实现了后端框架的开发啊?
言归正传,要了解透视变换的数学原理,请看这个。这篇文章给出了个有小错误的C++实现,但是如果你不是线性代数高手,一开始看肯定云里雾里,不知道他在干嘛。
这里,我就从这篇文章来讲讲透视变换如何去实现。之后你会发现,后面的数学原理非常基础,但是网络高手都跟你讲云里雾里话,让人痛苦不堪。
不多说,我们开始。
下面就是一个基础的变换公式,[x',y',w']是变换后的坐标,[u,v,w]是变换前的坐标,a矩阵是变换矩阵,为什么是3个参数,因为透视变换是3维空间上的变换啊,但是我们一般是处理二维图像,所以源坐标的w恒为1,而目标的坐标我们可以转换为二维的。这个a矩阵的参数各部分有什么意义请参考原文章,可以告诉你的是a33恒为1.
如下
是不是很好,但是有个问题,我们的变换矩阵a里面的参数不知道是啥,除了a33是1,其他8个参数都不知道啊。
如果你用过opencv的话,你知道透视变换需要源坐标4个,目标坐标4个。因为这样我们就能通过这个4对对应坐标构造8个方程吗,y坐标4个,x坐标4个。当然你需要移项等操作,中学生都会的。
最终形式如下:
常数*a11+常数*a12....常数*a32 = 常数 ,共8个。
最后你能写出一个Ax=b形式的矩阵方程,这里面的x就是[a11,a12,a13....a32],一个8未知数的向量。
很快你就能用各种矩阵库把它解出来,你就得到了变换矩阵a矩阵!是不是问题解决了?
且慢,求出变换矩阵后,要进行图像的变换,这个转换矩阵只能从源坐标到目标坐标,但是因为计算机的计算体系是离散的,为了进行插值操作,我们是从目标到源来求解,这怎么办?怎么从x,y反求u,v?
注意观察以下等式,我们已知目标坐标(x,y),又知道a11~a33的值,so,求原始坐标u v也不过求一个二元一次方程组的解而已。
求出来就随便插值了!
最后BALLBALL各路大爷不要把调用opencv叫实现透视变换好吗!