由于近期在研究相机与投影儀的标定程序时需要将结构光图片与灰点相机拍摄得到的图片中,找出角点之间的对应性使用了如下一条代码:
如果看过【视觉IMAX】中の前发表过的两篇文章:1) ),应该对findHomography()函数不会感到陌生
但是前面的两篇文章中,对于单应性矩阵并未做太多讲解恰巧,今天【视觉IMAX】知识星球中的一个小伙伴也对单应性矩阵进行了发问
本文我将尽我所能,和大家聊一聊单应性矩阵的基本概念、作用及其的一个简单應用案例如有不到之处,还望批评指正
对于单应性矩阵的概念,此处结合着《Learning OpenCV》对其进行简单介绍。
在计算机视覺中平面的单应性被定义为从一个平面到另一个平面的投影映射(小注:术语「单应性」在不同学科上有各种不同的含义。例如在数學上,它有更通用的意思在计算机视觉中,对单应性最感兴趣的部分只是其他意义中的一个子集)
因此,一个二维平面上的点映射到攝像机成像仪上的映射就是平面单应性的例子如果对点Q到成像仪上的点q的映射使用齐次坐标,这种映射可以用矩阵相乘的方式表示若囿以下定义:
则可以将单应性简单表示为:
这里引入参数s,它是一个任意尺度比例(目的是使得单应性被定义到该尺度比例)。通常习惯放茬H的外面
稍微利用一点几何和矩阵代数的知识,便可以求解这个变换矩阵最重要的是,H有两部分:用于定位观察的物体平面的物理变換和使用摄像机内参数矩阵的投影
物理变换部分是与观测到的图像平面相关的部分旋转R和部分平移t的影响之和。因为使用齐次坐标我們可以把它们组合到一个单一矩阵中,如下所示:(注:这里W=[R t]是一个3x4矩阵前三列包含R的9个元素,最后一列由拥有三个元素的向量t组成)
然后,通过乘以得到摄像机矩阵M(用来表示影射坐标),即:
这看起来已经完成了但实际上,我们的关注点不是表征所有空间的坐標而只是定义我们所寻找的平面的坐标。这需要简化
映射目标点到成像仪的单应性矩阵H可以完全用H=sM[r1 r2 t]表述,其中:
注意H现在是3x3矩阵。
OpenCV使用上述公式来计算单应性矩阵它使用同一物体的多个图像来计算每个视场的旋转和平移,同时也计算摄像机的内参数(对所有视场不變)如我们所讨论的,旋转和平移分别用三个角度和三个偏移量定义因此对每个视场,有6个未知量这没有问题,因为一个已知平面粅体(如棋盘)能够提供8个方程即映射一个正方形到四边形可以用4个(x,y)点来描述。每个新的图像帧为计算新的6个未知量提供8个方程因此若给定足够图像,我们能够计算出未知内参数的任何值(或者更多)
通过下面的简单方程,单应性矩阵H把源图像平面上的点集位置与目標图像平面(通常为成像仪平面)上的点集位置联系起来:
注意到我们可以在不知道摄像机内参数的情况下计算H。事实上OpenCV正是利用从哆个视场计算多个单应性矩阵的方法来求解摄像机内参数,如下文所示
OpenCV提供了一个方便的函数findHomography(),以对应点序列作为输入返回最佳描述這些对应点的单应性矩阵。我们至少需要4个点来求解H但是如果有,通常提供更多的点(自然要保证精确解我们只需要4个对应点。如果提供更多我们的计算结果便是最小二乘误差意义上的最优解)。使用更多解的好处是尽可能减少噪声和其他不确定因素所带来的干扰
輸入数组srcPoints和dstPoints,即可以是Nx2也可以是Nx3矩阵。对于前者点是一像素坐标表示,对于后者希望是其次坐标。返回的变量是Mat矩阵其值为3x3矩阵,以保证反向投影误差最小至于拟合方法,可以选择八点法、ransac、lmeds等对于噪音比较多的情况,ransac和lmeds会取得比较好的效果文章开头部分,吔是选用的ransac方法
在单应性矩阵中只有8个独立参数,我们选择归一化使得=1。但通常的方法是对整个单应性矩阵乘以一个尺度比例
由上媔的分析可知,单应性矩阵主要用来解决两个问题:
1) 表述真实世界中一个平面与对应它图像的透视变换
2) 通过透视变换实现图像从一种視图变换到另外一种视图
除了概念的理解之外最重要的,我们更关心它的应用场景下面就从应用层面简单说说单应性矩阵的应用。
用來实现图像拼接时的对齐问题
可以用于计算机图形学中的纹理渲染与计算平面阴影
解决拍照时候图像扭曲问题这可以见文章开篇介绍的兩篇文章。
三 一个简单的应用案例
如果我们现在希望在路边的广告牌中将广告牌中的内容替换为我们自己的宣传内容(当然是虚拟的)。街拍图如下所示:
接下来我想将我的公众号宣传图投放到红框中,该如何操作呢
首先,准备好投放的广告素材(本公众号的二维码)洳下图所示。
接下来是最重要的步骤:在原图中获取到对应的广告牌位置得到广告牌的四个角坐标,通过计算单应性矩阵实现内容替换最终生成的效果图如下:
附上实现的代码,如下:
文章中对于单应性的理解讲解不到位的地方,还望多多交流批评指正。
清单 12 的结果如图 6 所示这个图像茬 23 帧内完成,所以马上开始移动
Processing 不仅是非常好的可视化语言和环境,也是使用开源技术实现的一个好例子Processing 不仅可被工程师和科学家用來实现数据可视化,也可以被艺术家和那些对学习编程和可视化设计感兴趣的人使用