点击上方“计算机视觉工坊”,选择“星标”

干货第一时间送达

来源:公众号@计算摄影学

一. 直观认识立体校正

在文章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天内无条件退款

圈里有高质量教程资料、可答疑解惑、助你高效解决问题

觉得有用,麻烦给个赞和在看~

三维重建-立体校正(Recitification)相关推荐

  1. 双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python

    双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python 目录 双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python 1.项目结构 2. Environment 3.双 ...

  2. (七)立体标定与立体校正 【计算机视觉学习笔记--双目视觉几何框架系列】

    七.立体标定与立体校正 这篇博文中,让玉米和大家一起了解一下,张氏标定是怎样过渡到立体标定的?在这里主要以双目立体视觉进行分析.对于双目立体视觉,我们有两个摄像头.它们就像人的一双眼睛一样,从不同的方 ...

  3. 立体视觉--双目相机立体校正(Bouguet算法)

    双目相机立体校正(Bouguet算法) 在双目立体视觉的三维重建过程中,需要通过立体匹配算法来进行视差图的计算得到左右两幅图像的视差值,进而来计算深度来恢复场景的三维信息. 计算三维场景中目标点在左右 ...

  4. StereoRectify()函数定义及用法畸变矫正与立体校正

    畸变矫正是上一篇博文的遗留问题,当畸变系数和内外参数矩阵标定完成后,就应该进行畸变的矫正,以达到消除畸变的目的,此其一. 在该系列第一部分的博文中介绍的立体成像原理中提到,要通过两幅图像估计物点的深度 ...

  5. 【立体视觉】双目立体标定与立体校正

    from:https://blog.csdn.net/u011574296/article/details/73826420 参考: 机器视觉学习笔记(6)--双目摄像机标定参数说明  机器视觉学习笔 ...

  6. 双目摄像头立体成像(二)畸变矫正与立体校正

    一.立体校正的原因 **原因一:**当畸变系数和内外参数矩阵标定完成后,就应该进行畸变矫正,以达到消除畸变的目的. **原因二:**在立体成像原理中提到,要通过两幅图像估计物点的深度信息,就必须在两幅 ...

  7. 双摄像头立体成像(三)-畸变矫正与立体校正

    双摄像头立体成像(三)-畸变矫正与立体校正 畸变矫正是上一篇博文的遗留问题,当畸变系数和内外参数矩阵标定完成后,就应该进行畸变的矫正,以达到消除畸变的目的,此其一. 在该系列第一部分的博文中介绍的立体 ...

  8. opencv双目标定+立体校正+立体匹配(源码讲解)

    //双目标定无非就是重复两次单目标定的流程,单目标定参考我上一篇博客. //在学习双目视觉之前,建议大家补充下,双目视觉模型,对极几何的知识,今天只讲源码的流程,以后出一篇对极几何的讲解. //老规矩 ...

  9. Epipolar Recitification 极线校正/立体校正

    在进行极线搜索时,为了方便,将极点通过射影变换转至无穷远点,则图上的极线都变成了平行线,便于搜索 PAT: 只能在极点位于图像外时使用这种方法,极点在图像内时,极点周围的点也会被变换到无穷远处 变换矩 ...

  10. 使用Python进行立体几何和立体校正的综合教程

    需要多个视图 在相机的针孔模型中,光线从物体上反射出来,照射到胶片上形成图像.因此,沿着同一条光线的所有点都将对应于图像中的一个点. 因此,给定图像中的一个点,不可能确定其在世界上的准确位置,也就是说 ...

最新文章

  1. php点击复制按钮到我的粘贴板,JS 实现点击按钮复制内容到粘贴板 clipboard
  2. USERADD命令详解
  3. 前端一HTML:二: html开发工具
  4. 暖通空调系统全面水力平衡解决方案
  5. R-3.1.1 编译安装2
  6. java在线教程_如何自学java-已拿阿里25k offer
  7. LOAM_velodyne学习(三)
  8. React Native之react-native bundle --platform android --dev false --entry-file index.js --bundle失败
  9. 统计php代码执行情况,PHP代码执行函数总结
  10. go路由httprouter中的压缩字典树算法图解及c++实现
  11. HAOI2008 硬币购物
  12. 流媒体基本要点简述:如何在H264数据中获取PTS?
  13. 【狂神说笔记—— Java基础19-MyBatis】
  14. 山东计算机专业的在职硕士,2019年山东科技大学在职研究生计算机技术专业关于招生方面的信息是什么...
  15. Centos7部署Mantis
  16. R语言ETL系列:创建字段(mutate)
  17. Oracle默认数据库角色账号密码
  18. 网络地址转换——NAT
  19. 最小生成树-普利姆和克鲁斯卡尔算法
  20. 15种独一无二的创新数据可视化方式

热门文章

  1. sql server 按年月日分组
  2. C#使用OpcNetApi.dll和OpcNetApi.Com.dll操作OPC
  3. HTML5+Activex+Singr+ABP+MongoDB
  4. Spring之FactoryBean .
  5. DimDate populate data
  6. 获取RenderedGeometry不对的处理
  7. 在SQL Server 2005中实现异步触发器架构
  8. Oracle DBLINK 简单使用
  9. 10. 二进制中1的个数(C++版本)
  10. LitePal(版本1.5.0,写此博客时是最新版本)