双目视觉深度检测测距原理详解与算法实现
尽管近期主要精力被神经科学、大脑记忆机制以及毕业活动占据了不少,但双目视觉方面的进展仍有必要梳理总结。毕竟上一篇博文发布后,多位同行发来邮件交流探讨,许多之前悬而未决的问题,也在讨论和反复试验中逐渐明晰。 开篇先要感谢 maxwellsdemon 和 wobject,没有大家的共同琢磨,这篇文章也不
尽管近期主要精力被神经科学、大脑记忆机制以及毕业活动占据了不少,但双目视觉方面的进展仍有必要梳理总结。毕竟上一篇博文发布后,多位同行发来邮件交流探讨,许多之前悬而未决的问题,也在讨论和反复试验中逐渐明晰。
开篇先要感谢 maxwellsdemon 和 wobject,没有大家的共同琢磨,这篇文章也不可能成形。
谈到双摄像头测距,首先需要回顾一下原理。翻阅 Learning OpenCV 第416页和418页,可以看到下面这两张图:

图1. 双摄像头模型俯视图

图2, 双摄像头模型立体视图
图1清晰地说明了双摄像头测距的原理,书中给出的 Z 公式如下:

在 OpenCV 中,f 以像素为单位,Tx 的量纲由标定所用的棋盘格实际尺寸和输入值决定,通常设为毫米,若需更高精度可设为0.1毫米。d = xl - xr 同样以像素为单位。分子分母相约后,z 的量纲与 Tx 一致。
图2展示了双摄像头如何获取空间中某点的三维坐标。实际计算均基于相似三角形,具体表达式如 Q 矩阵所示:

空间中某点的三维坐标为 (X/W, Y/W, Z/W)。
因此,要精确计算某点与摄像头的距离,需要获取焦距 f、视差 d、摄像头中心距 Tx 这几个参数。若还想知道 X 和 Y 坐标,则还需知晓左右像平面与立体坐标系原点的偏移 cx 和 cy。f、Tx、cx 和 cy 可通过立体标定获得初始值,再通过立体校准进行优化,使两个摄像头在数学上达到完全平行,左右摄像头的 cx、cy、f 均一致(即图2中左右视图完全平行对准的理想状态)。而立体匹配的任务,就是在上述基础上求出最后一个变量——视差 d(通常需要达到亚像素精度)。这样,计算一个点三维坐标所需的准备工作才算完成。
搞清原理后也就明白了,标定、校准、匹配这几个步骤,本质上都是为了更准确地获取 f、d、Tx、cx、cy。
双目测距的原理就介绍到这里。为避免大家看得头晕,下面用 FAQ 的形式,将实现双摄像头测距过程中遇到的几个疑点串联起来。这些解答仅代表个人理解,如有不当之处,欢迎指正。
Q1:标定时棋盘格大小如何设置,对结果有影响吗?
当然有影响。标定时必须指定棋盘方格的实际长度(通常用毫米,更精确可设为0.1毫米),该值必须与实际长度一致,标定结果才能用于实际距离测量。一般来说,尺寸设置准确后,立体标定得到的 Translation 向量第一个分量 Tx 的绝对值,即为左右摄像头的中心距。可用此值验证立体标定的准确性。例如,我将棋盘格大小设为270(27mm),最终得到的 Tx 为602.8(60.28mm),精度相当不错。
Q2:立体标定得到的 Tx 符号为什么是负的?
说实话,这个问题我也未完全吃透。个人理解是:立体标定得到的 T 向量方向是从右摄像头指向左摄像头(即 Tx 为负),而 OpenCV 坐标系中原点位于左摄像头。因此,在校准时,需要将该向量的三个分量符号全部取反,最终计算出的距离才能为正。
不过还有一个问题:Learning OpenCV 中 Q 的表达式,第四行第三列元素为 -1/Tx,但实际使用时求出的却是 1/Tx。针对这一点,作者与同行讨论后认为,可能是书中 Q 表达式里的负号是为了抵消 T 向量的反方向而设,但在实际编写 OpenCV 代码时,那位朋友并未加入负号。这仅是一己之见,期待更详细的解释。
Q3:cvFindStereoCorrespondenceBM 的输出不是以像素为单位的视差?
在 OpenCV 2.0 中,BM 函数的结果以16位有符号数存储。由于精度要求,所有视差在输出时被放大了16倍(2的4次方)。具体代码如下:
dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*128/d : 0) + 15) >> 4);
可以看到,原始视差左移了8位(256),加上一个修正值后,又右移了4位,最终效果相当于左移4位。因此,实际计算距离时,cvReprojectTo3D 输出的 X/W、Y/W、Z/W 都需要乘以16(即 W 除以16),才能得到正确的三维坐标。
Q4:双摄像头测距时,世界坐标系原点在哪?
世界坐标系的原点位于左摄像头凸透镜的光心。
说到这儿,需要提一下针孔模型。图3中描绘的针孔模型是凸透镜成像的简化版。当物距足够远(远大于两倍焦距)时,凸透镜成像可视为在焦距处的小孔成像。

图3. 针孔模型
实际计算时,为方便起见,我们常将像平面翻转并平移到针孔前,得到一种数学上更简单的等价形式(便于计算相似三角形),如图4所示。

图4. 针孔模型的数学等价形式
对应图2即可理解,世界坐标系原点就是左摄像头针孔模型中的针孔,也就是左摄像头凸透镜的光心。
Q5:f 和 d 的单位是像素,这个像素到底代表什么?如何与毫米换算?
这个问题同样与针孔模型有关。在针孔模型中,光线穿过针孔(即凸透镜中心)后在焦距处成像,因此图3的像平面即为摄像头的 CCD 传感器表面。每个 CCD 都有一定的尺寸和分辨率,由此确定了毫米与像素之间的转换关系。例如,CCD 尺寸为8mm×6mm,分辨率为640×480,那么毫米与像素的换算关系为80 pixel/mm。
实际应用中,我们在数学上将该像平面等效到小孔前(图4),相当于在透镜中心点前假设了一块虚拟的 CCD 传感器。
Q6:为什么 cvStereoRectify 求出的 Q 矩阵中 cx、cy、f 与原来不一样?
这一点前面提到过。实际测量中,由于摄像头摆放的原因,左右摄像头的 f、cx、cy 均不相同。为了使左右视图达到完全平行对准的理想状态,便于数学计算,立体校准实际上是在左右像重合区域最大的前提下,让两个摄像头光轴的前向平行,再让左右摄像头的 f、cx、cy 保持一致。因此,Q 矩阵中的值与两个内参矩阵的值不同,也就不难理解了。
实验结果:
实际测量结果表明,虽然 Block Matching 算法本身的精度有限,但测距结果基本可以接受。结果如图5所示:

图5. OpenCV 双摄像头测距结果
图中从左到右的三个物体分别放置在距离摄像头50cm、75cm和90cm的位置。测距效果尚可。当然,这是较好的结果。由于 BM 算法的限制,同一片点云中相同距离的点通常存在正负2厘米以内的误差。
图6是用双目摄像头测量物体长宽的结果,看起来就不那么准确了……

图6. OpenCV 双摄像头测边长结果
物体宽度为117-88=29mm,但实际宽度是5.2cm;高度为71-13=58mm,实际高度却为13cm。这个误差令人有些困惑。
另外还有一个至今未完全弄明白的问题:双摄像头的中心距,为什么用的是 Tx 而不是 T 向量的长度?因为要使左右视图重合区域最大化,两个摄像头的光轴必须与 T 垂直(如图7所示)。这样,校正后两个摄像头的中心距应该是 T 才对。不知道这种理解是否正确?

图7. 双摄像头立体校准俯视图
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:双目视觉深度检测测距原理详解与算法实现要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
相关热点近年来,AI文本转语音与语音克隆技术发展极为迅速,但能够提供超过600种声音、覆盖142种语言的平台却屈指可数。本文介绍的Verbatik正是这样一款工具——它能够将书面文字直接转化为自然流畅的语音,同时支持声音克隆,并集成了脚本编写、虚拟人AI以及音效工作室,堪称一站式音频制作解决方案。什么是Ve
对音乐制作或音频设计感兴趣的朋友,可能已经注意到市面上涌现出许多AI工具,但多数功能单一或需要本地安装。今天介绍的在线AI音乐创作平台——Sounds Studio,则与众不同。 什么是Sounds Studio? Sounds Studio是一款完全基于浏览器的AI音乐制作与音频设计平台,核心优势
需求人群 该平台专为机器学习工程师与数据科学家设计——简而言之,适合那些需要频繁训练模型、又不愿被硬件环境困扰的研发团队。此外,企业若希望搭建自身的机器学习平台,使用此方案也完全能够胜任。 使用场景 在实际应用层面,OpenBayes 覆盖了多个典型的深度学习应用方向: 医学影像的处理与模型训练,例
需求人群 如果你是数据科学爱好者,正在寻找一个可以系统化学习、交流经验的地方——那么这个社区值得关注。在这里,你可以与志同道合的数据科学从业者切磋竞赛经验、共享开源代码,找到学习的同路人。 对于已经在数据科学领域深耕多年的资深人士,这里同样是分享实战代码、行业案例、帮助新人少走弯路的理想平台。贡献自
- 日榜
- 周榜
- 月榜
热点快看
