点击上方“计算机视觉工坊”,选择“星标”
干货第一时间送达
来源:公众号@计算摄影学
一. 直观认识立体校正
在文章68. 三维重建3-两视图几何中,我们看到通过三角测量,可以确定一个像点在三维空间中的位置,其前提是我们提前获取了这个像点在另外一个图像中的对应点,并且知道了两个相机的相机矩阵。
获取在两个图像中的成对匹配点,也就是同一个3D点在两个图像上的投影点非常重要。我在上述文章中为你展示了两视角几何模型中的对角几何约束关系,这样当需要搜索像点x的对应匹配点x'时,我们可以将搜索范围控制到第二幅图像的极线l'上。
然而,l'通常不是水平的,因此我们需要在第二幅图像的一条倾斜线段上进行搜索。这样的算法是很低效的,尤其是当我们需要用到图像块的特征去做点匹配的判断时。在之后的文章中,我会介绍”立体匹配“,这个过程需要对图像中的所有点寻找匹配点,如果每个点都还按照这种倾斜线段搜索的方法去操作,就会特别特别慢。因此,我们必须引入立体校正(Rectification)操作,它对两幅图像做变换,最终使得两幅图像的极线平行,且在水平方向对齐。这样,当我们需要搜索对应的匹配点时,就只需要在水平方向上进行一维搜索,大大加快了速度。
这个过程,就好像是我们创造了两个内参相同的虚拟相机,它们指向同一个方向进行拍摄原来的场景,得到两幅新的图像,如下图所示:
下面展示了在同一个场景用双摄手机的两个摄像头拍摄的一对图像,两个摄像头具有不同的内参数,因此拍摄出的图像视角间有明显的空间变换和尺度差异。
这个手机的摄像头是纵向排列的,拍出的图像如下图所示
所以当我们画出部分极线时,会发现这些极线是倾斜的,没有对齐。
即便我们根据内参数对图像进行一定比例的缩放,使得两幅图像尺寸一致,我们发现极线依然不能对齐,而且是倾斜的:
当执行我上面提到的立体校正步骤后,两个图像的所有极线将变为水平,且在纵向对齐,此时两个图像的尺度也校正到一致状态。注意这两个摄像头在手机上是纵向排布的,为了让极线在水平方向,我把图像进行了90度旋转。如果不做这样的旋转,极线就是在纵向对齐的,这不利用后续立体匹配这类算法的处理。
仅为了查看方便,我们可以将图像极线重新调整为纵向,观察和比较一下:
二. 立体校正算法原理
2.1 理论推导
正式来说,图像立体校正是指对两幅图像分别进行一次平面投影变换,使两幅图像的对应极线在同一条水平向上,而对极点被映射到无穷远处, 这样可以使两幅图像只存在水平方向上的视差,立体匹配问题从二维 降到一维,从而提高了匹配的速度。
虽然有各种各样的立体校正算法,今天我只会介绍一种非常容易理解的方法,而且也是广泛应用的一种方法:
作者给出了一种简单的图像校正方法,只需要知道两个相机的相机矩阵,且要求两个相机视角相差不大——这种假设在我面临的项目里面都是成立的,所以我比较喜欢这种算法。
现在来进行一点点简单的推导,请抓稳扶好
由文章66. 三维重建1——相机几何模型和投影矩阵我们知道
又由于
且从Xw到投影成像点的直线一定会过光心,如下图所示
因此,我们可以把三维空间点坐标表示为下面的式子(上横线表示齐次坐标),c是指光心的坐标,\lambda是比例因子,用来调节Xw的位置在这条线上的位置。
接下来,我们看看两个相机在校正前和校正后的几何模型:
可见,在校正前和校正后,相机的投影矩阵发生了变化,所以同一个3D点的投影点也发生了变化。校正后,我们看到两个光心所在的主平面是平行的,它们都看向同一个方向。我们用下标o代表origin,用下标n代表new,那么,上面的公式就变成了:
在进行立体校正时,我们是已知两个相机的相机矩阵的,因而也就知道了两个相机的光心坐标。同时,在立体校正前后,现在讲的Fusiello等的算法假设光心是不变的,因此我们可以联立上面两个式子,得到投影点的关系:
其中:
因此,为了做两个相机的校正,我们只需要确定好新的虚拟相机的内参数及旋转矩阵即可。
先说内参数:在校正之后,我们需要两个内参数完全一致的虚拟相机,因此在Fusiello等的算法中,直接用下面的式子得到新相机的内参数:
再看看旋转矩阵:校正之后,两个相机的方向是一致的,它们的旋转矩阵可以展开如下:
其中,旋转矩阵的三行代表着新相机矩阵的X/Y/Z轴,它们分别具有如下的特点:
-
1. X轴应该平行于两个相机光心的连线,所以有:
-
2. Y轴应该垂直于X轴和原始相机的视线方向(即原始相机坐标系的Z轴,我们用k来表达)所在的平面:
-
3. Z轴应该垂直于X轴和Y轴所在的平面:
到此为止,我们就确定了虚拟相机的方向(旋转矩阵),光心(c1和c2),内参,这样就很容易利用刚提到的公式来对图像进行变换了:
2.2 具体实现
在具体实施中,我们假设已经通过相机的几何参数标定(见文章67. 三维重建2——相机几何参数标定)获得了两个相机的内参和外参,并且已经对图像进行了畸变校正。那么,整个校正过程可以总结如下:
在作者的论文中,列出了22行Matlab代码完成这个过程,你可以查阅看看。作者还把相关的代码、数据放到了sci.univr.it/∼fusiello/rect.html供我们学习,很赞!
这个算法的使用要点如下:
-
算法本身没有考虑图像的镜头畸变,因此使用时需要先对图像点做畸变校正
-
要注意原始相机之间的排布方式。正如一开始所描述的,如果相机之间是纵向排列的,需要先把图像旋转到水平,才能进行水平的极线校正对齐。比如,常见手机多摄像头的排布方式如下,在应用上述算法时,要提前对图像做一些预先的旋转,才能保证校正后极线位于水平方向
-
整个算法非常依赖于准确的内参、外参。如果这些信息有误差,最终校正后的极线就不一定能水平对齐了。
2.3 效果展示
这里我展示用同样一个手机拍出的更多图像,你可以清晰的看到图像在校正前后极线的变化:
校正前:
校正后:
校正前:
校正后:
三. 总结
今天我给你介绍了一个非常简单,容易复现的立体校正算法。事实上,我这边的实际项目中也是在这个算法的基础上进行扩展,进而进行实际应用的。所以我觉得这个算法非常实用,好用,推荐给你学习,希望能给你带来启发。
如果你在实际使用中发现了对极线无法水平对齐,就要考虑到标定的精度了。比如标定时的状态和你实际使用相机时的状态发生了轻微的改变——这种情况很常见——你就需要考虑如何对相关参数进行进一步的调优,才能更好的使用这个算法。
四. 参考文献
-
CMU 2021 Fall Computational Photography Course 15-463, Lecture 17
-
Andrea Fusiello, et al, A compact algorithm for rectification of stereo pairs
-
Richard Szeliski, Computer Vision: Algorithms and Application.
-
Stefano Mattoccia, Stereo vision: algorithms and applications, Università di Firenze, May 2012
-
68. 三维重建3——两视图几何
-
67. 三维重建2——相机几何参数标定
本文仅做学术分享,如有侵权,请联系删除。
重磅!计算机视觉工坊-学习交流群已成立
扫码添加小助手微信,可申请加入3D视觉工坊-学术论文写作与投稿 微信交流群,旨在交流顶会、顶刊、SCI、EI等写作与投稿事宜。
同时也可申请加入我们的细分方向交流群,目前主要有ORB-SLAM系列源码学习、3D视觉、CV&深度学习、SLAM、三维重建、点云后处理、自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、深度估计、学术交流、求职交流等微信群,请扫描下面微信号加群,备注:”研究方向+学校/公司+昵称“,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进去相关微信群。原创投稿也请联系。
▲长按加微信群或投稿
▲长按关注公众号
3D视觉从入门到精通知识星球:针对3D视觉领域的视频课程(三维重建系列、三维点云系列、结构光系列、手眼标定、相机标定、激光/视觉SLAM、自动驾驶等)、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答五个方面进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业为一体的铁杆粉丝聚集区,近4000星球成员为创造更好的AI世界共同进步,知识星球入口:
学习3D视觉核心技术,扫描查看介绍,3天内无条件退款
圈里有高质量教程资料、可答疑解惑、助你高效解决问题