双目立体视觉(一) 基本原理和步骤

article/2025/10/9 19:05:25

目录

一、双目立体视觉系统的四个基本步骤

二、各步骤原理

1、相机标定

2、立体校正

3、立体匹配


一、双目立体视觉系统的四个基本步骤

  1. 相机标定主要包含两部分内容: 单相机的内参标定和双目相机的外参标定,前者可以获得每个相机的焦距、光心、畸变系数等参数,后者可以获得双目相机之间的相机坐标系的旋转、平移关系。
  2. 立体校正过程是根据相机的标定结果,对两个相机采集到的原始图像进行校正,校正后的两张图像位于同一平面且互相平行,即图像的每行像素之间共线。
  3. 立体匹配过程是根据立体校正后的图像,进行像素点的匹配,匹配成功的点表示真实世界中的某点在这两个图像中的不同位置。
  4. 深度计算过程是根据立体匹配结果得到视差图,通过视差图计算每个像素对应的深度,从而获得深度图。

二、各步骤原理

1、相机标定

  • 单目相机的内参标定

      基础知识,具体过程参考:opencv相机内参标定

      内参矩阵:

           

      畸变参数:k1,k2,k3径向畸变,p1,p2是切向畸变系数。

  • 双目相机标定

       主要为了计算两个相机坐标系之间的旋转和平移关系,以OpenCV为例,最终可以得到旋转矩阵R,平移向量T,本质矩阵E和基础矩阵F。

double err = cv::stereoCalibrate(object_points, imagepointL, imagepointR,intrinsic_left, distCoeffs_left, intrinsic_right, distCoeffs_right,srcImgSize, R, T, E, F,CALIB_USE_INTRINSIC_GUESS,cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 30, 1e-6));

         

2、立体校正

  •  为什么要立体校正呢?

     首先需要从理想双目相机成像模型说起。

              

 

其中:   b 为基线,即两个相机原点之间的距离 ;

              fl和fr 分别为左右相机的焦距,理想的双目相机fl=fr=f ;

              cl和cr 分别为左右相机的光心,理想的双目相机cl=cr ;

              xl和xr 分别为空间中的一点P投影在左右相机的图像中的横坐标 ;

则根据几何关系,可以得到:

\frac{b - (xl-cl)-(cr-xr)}{b} = \frac{z-f}{z}

整理得:

z = \frac{f*b}{xr-xl}

这里的(xr-xl)就是视差disparity 。

可以发现如果要计算深度z,必须要知道:

1、相机焦距f,左右相机基线b。这些参数可以通过先验信息或者相机标定得到。

2、视差d。需要知道左相机的每个像素点(xl, yl)和右相机中对应点(xr, yr)的对应关系。这是双目视觉的核心问题。视差是指在两个摄像机图像之间的像素位置的差异。假设立体视觉相机中的左图像在位置(1,30)具有像素,并且相同的像素在右图像中的位置(4,30)存在,视差值或差值为(4-1)=3。视差值与上述公式的深度成反比。

 那么问题来了,对于左图中的一个像素点,如何确定该点在右图中的位置?是不是需要我们在整 个图像中地毯式搜索一个个匹配?

答案是:不需要。因为有极线约束。极线约束对于求解图像对中像素点的对应关系非常重要。

  • 什么是极线呢?

如下图所示。C1,C2是两个相机,P是空间中的一个点,P和两个相机中心点C1、C2形成了三维空间中的一个平面PC1C2,称为极平面(Epipolar plane)。极平面和两幅图像相交于两条直线,这两条直线称为极线(Epipolar line)。P在相机C1中的成像点是P1,在相机C2中的成像点是P2,但是P的位置事先是未知的。

我们的目标是:对于左图的P1点,寻找它在右图中的对应点P2,这样就能确定P点的空间位置,也就是我们想要的空间物体和相机的距离(深度)。

所谓极线约束(Epipolar Constraint)就是指当同一个空间点在两幅图像上分别成像时,已知左图投影点p1,那么对应右图投影点p2一定在相对于p1的极线上,这样可以极大的缩小匹配范围。

根据极线约束的定义,我们可以在下图中直观的看到P2一定在对极线上,所以我们只需要沿着极线搜索一定可以找到和P1的对应点P2。

 

但是,上述过程考虑的情况是(两相机共面且光轴平行,参数相同)非常理想状态的,即认为两个相机成像面是完全平行对齐的。这种假设在现实世界中是基本难以成立的,因为有些场景下两个相机需要独立固定,很难保证光心C1,C2完全水平,即使是固定在同一个基板上也会因为装配的原因导致光心不完全水平。如下图所示。我们看到两个相机的极线不仅不平行,还不共面,之前的理想模型不再适用。

 我们先来看看这种情况下拍摄的两张左右图片,如下所示。左图中三个十字标志的点,在右图中对应的极线是右图中的三条白色直线,也就是对应的搜索区域。我们看到这三条直线并不是水平的,如果进行逐点搜索效率非常低。

                            左图中三个点(十字标志)在右图中对应的极线是右图中的三条白色直线 

  • 立体校正

针对现实中这种非理想情况,我们需要通过立体校正,对左右相机拍摄的图像像素做重新排列,以达到理想状态下的成像面平行对齐状态。具体来说就是,通过分别对两张图片用单应(homography)矩阵变换(可以通过标定获得),把两个不同方向的图像平面(下图中灰色平面)重新投影到同一个平面且光轴互相平行(下图中黄色平面),这样就可以用前面理想情况下的模型了,两个相机的极线也变成水平的了。

但是让两个相机光轴平行的方法有很多,可以:

1)左相机不动,右相机动。

2)也可以两部相机旋转到中间等等。

最常见的校正方法就是Bouguet极线校正方法

Bouguet极线校正方法:左右相机成像平面各旋转一半,使得左右图像重投影造成的误差最小,左右视图的共同面积最大。

CV_EXPORTS_W void stereoRectify( InputArray cameraMatrix1, InputArray distCoeffs1,InputArray cameraMatrix2, InputArray distCoeffs2,Size imageSize, InputArray R, InputArray T,OutputArray R1, OutputArray R2,OutputArray P1, OutputArray P2,OutputArray Q, int flags = CALIB_ZERO_DISPARITY,double alpha = -1, Size newImageSize = Size(),CV_OUT Rect* validPixROI1 = 0, CV_OUT Rect* validPixROI2 = 0 );

 经过图像矫正后,左图中的像素点只需要沿着水平的极线方向搜索对应点就可以了。从下图中可以看到三个点对应的视差(红色双箭头线段)是不同的,越远的物体视差越小,越近的物体视差越大,这和我们的常识是一致的。

图像校正后的结果。红色双箭头线段是对应点的视差

(1)双目校正前的左右相机图像

(2)双目校正后的左右相机图像

3、立体匹配

上面讲到的对于左图的一个点,沿着它在右图中水平极线方向寻找和它最匹配的像素点,说起来简单,实际操作起来却不容易。这是因为上述都是理想情况下的假设。实际进行像素点匹配的时候会发现几个问题:

1、实际上要保证两个相机完全共面且参数一致是非常困难的,而且计算过程中也会产生误差累积,因此对于左图的一个点,其在右图的对应点不一定恰好在极线上。但是应该是在极线附近,所以搜索范围需要适当放宽。

2、单个像素点进行比较鲁棒性很差,很容易受到光照变化和视角不同的影响。

双目立体匹配可划分为四个步骤:匹配代价计算、代价聚合、视差计算和视差优化。

  • 匹配代价计算的目的是衡量待匹配像素与候选像素之间的相关性。两个像素无论是否为同名点,都可以通过匹配代价函数计算匹配代价,代价越小则说明相关性越大,是同名点的概率也越大。

        匹配代价计算的方法有很多,传统的摄影测量中,使用灰度绝对值差(AD,Absolute Differences)、灰度绝对值差之和(SAD,Sum of Absolute Differences)、归一化相关系数(NCC,Normalized Cross-correlation)等方法来计算两个像素的匹配代价;计算机视觉中,多使用互信息(MI,Mutual Information)法、Census变换(CT,Census Transform)法、Rank变换(RT, Rank Transform)法、BT(Birchfield and Tomasi)法 等作为匹配代价的计算方法。不同的代价计算算法都有各自的特点,对各类数据的表现也不尽相同,选择合适的匹配代价计算函数是立体匹配中不可忽视的关键步骤。

每个像素在搜索同名点之前,往往会指定一个视差搜索范围 ,视差搜索时将范围限定在D(D_{min} \sim D_{max})内,用一个大小为 ( [公式] 为影像宽度, [公式] 为影像高度)的三维矩阵C来存储每个像素在视差范围内每个视差下的匹配代价值。矩阵 [公式] 通常称为DSI(Disparity Space Image)。

图1 DSI示意图(C(x,y,d)代表像素(x,y)在视差为d时的匹配代价)

  • 代价聚合的根本目的是让代价值能够准确的反映像素之间的相关性。上一步匹配代价的计算往往只会考虑局部信息,通过两个像素邻域内一定大小的窗口内的像素信息来计算代价值,这很容易受到影像噪声的影响,而且当影像处于弱纹理或重复纹理区域,这个代价值极有可能无法准确的反映像素之间的相关性。

        而代价聚合则是建立邻接像素之间的联系,以一定的准则,如相邻像素应该具有连续的视差值,来对代价矩阵进行优化,这种优化往往是全局的,每个像素在某个视差下的新代价值都会根据其相邻像素在同一视差值或者附近视差值下的代价值来重新计算得到新的DSI,用矩阵 S 来表示。        

        实际上代价聚合类似于一种视差传播步骤,信噪比高的区域匹配效果好,初始代价能够很好的反映相关性,可以更准确的得到最优视差值,通过代价聚合传播至信噪比低、匹配效果不好的区域,最终使所有影像的代价值都能够准确反映真实相关性。常用的代价聚合方法有扫描线法、动态规划法、SGM算法中的路径聚合法等。

 

  • 视差计算即通过代价聚合之后的代价矩阵 S 来确定每个像素的最优视差值,通常使用赢家通吃算法(WTA,Winner-Takes-All)来计算,如图所示,某个像素的所有视差下的代价值中,选择最小代价值所对应的视差作为最优视差。这一步非常简单,这意味着聚合代价矩阵S的值必须能够准确的反映像素之间的相关性,也表明上一步代价聚合步骤是立体匹配中极为关键的步骤,直接决定了算法的准确性。

 

  • 视差优化的目的是对上一步得到的视差图进行进一步优化,改善视差图的质量,包括剔除错误视差、适当平滑以及子像素精度优化等步骤,一般采用左右一致性检查(Left-Right Check)算法剔除因为遮挡和噪声而导致的错误视差;采用剔除小连通区域算法来剔除孤立异常点;采用中值滤波(Median Filter)、双边滤波(Bilateral Filter)等平滑算法对视差图进行平滑;另外还有一些有效提高视差图质量的方法如鲁棒平面拟合(Robust Plane Fitting)、亮度一致性约束(Intensity Consistent)、局部一致性约束(Locally Consistent)等也常被使用。

         由于WTA算法所得到的视差值是整像素精度,为了获得更高的子像素精度,需要对视差值进行进一步的子像素细化,常用的子像素细化方法是一元二次曲线拟合法,通过最优视差下的代价值以及左右两个视差下的代价值拟合一条一元二次曲线,取二次曲线的极小值点所代表的视差值为子像素视差值。

        局部匹配算法的步骤一般包括匹配代价计算、代价聚合和视差计算三个步骤,全局算法则包括匹配代价计算,视差计算与视差优化三个步骤,半全局算法SGM则四个步骤都有。

OpenCV提供了以下四种立体匹配算法的函数,后面会详细学习BM和SGBM

  1. Block Matching(BM) StereoBM
  2. Semi-Global Block Matching(SGBM) StereoSGBM
  3. Graph Cut(GC)cvStereoGCState()
  4. Dynamic Programming(DP)cvFindStereoCorrespondence()

第一种是最简单的块匹配,速度最快,精度最差,第二种是半全局快匹配,是一种速度和精度的折中,第三,四种是基于全局的匹配。

 

参考:

1. https://zhuanlan.zhihu.com/p/378738199

2. https://www.cnblogs.com/zyly/p/9373991.html#_label1_2

3. https://zhuanlan.zhihu.com/p/159055657

4. https://zhuanlan.zhihu.com/p/31243203


http://chatgpt.dhexx.cn/article/cOUApYMZ.shtml

相关文章

长连接和短链接的区别

长连接意味着进行一次数据传输后,不关闭连接,长期保持连通状态。如果两个应用程序之间有新的数据需要传输,则直接复用这个连接,无需再建立一个新的连接。就像下图这样。 它的优势是在多次通信中可以省去连接建立和关闭连接的开销…

springboot 实现长链接转短链接

实现结果: 转换短链接api: 接口:http://127.0.0.1/api?urlurlencode(要缩短的网址) 例如:http://127.0.0.1/api?urlhttp%3a%2f%2fwww.baidu.com 返回:http://127.0.0.1/baidu 访问短链接即可还原原url;…

长链接与短链接

1、Http协议 1.1 HTTP协议与TCP/IP协议的关系 HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递…

长连接与短链接

短链接:客户端每次请求成功后,将关闭链接 长连接:客户端请求成功后,并不会立即关闭链接,适用于客户端请求较为频繁的情况 ———————————————————————————————————— 1. HTTP协议与TC…

如何实现 长链接变 短 链接?

短链接,通俗来说,就是将长的 URL 网址,通过程序计算等方式,转换为简短的网址字符串。 大家经常会收到一些莫名的营销短信,里面有一个非常短的链接让你跳转。新浪微博因为限制字数,所以也会经常见到这种看着…

微信:长链接转短链接

前言 微信复制出来的链接太长,想转短连接如何做? 将一条长链接转成短链接。 主要使用场景: 开发者用于生成二维码的原链接(商品、支付二维码等)太长导致扫码速度和成功率下降,将原长链接通过此接口转成短…

长链接 转换成 短链接

文章目录 参考来源思路方法一方法二 参考来源 豆瓣 短链接生成的算法原理 思路 方法一 一般会想到用哈希,这里可以用MD5码获取哈希值,但时MD5生成的串挺长的,这类要考虑怎么把它变短。 做法如下: 方法二 很好想的思路&…

长链接 转短链接URL的设计思路

最烂的回答 实现一个算法,将长地址转成短地址。实现长和短一一对应。然后再实现它的逆运算,将短地址还能换算回长地址。 这个回答看起来挺完美的,然后候选人也会说现在时间比较短,如果给我时间我去找这个算法就解决问题了。但是稍…

长链接转成短链接的原理和实现详解

一、为什么要设计短链接,短链接有什么好处? 1、链接变短,在对内容长度有限制的平台发文,可编辑的文字就变多了。 比如:微博,限定了只能发 140 个字,如果一串长链直接怼上去,其他可…

长链到短链转化

文章目录 1:为什么将长链转化为短链?2:短链跳转的基本原理3:将长链转化为短链(Hash)3.1:hash3.1.1:hash算法的选取3.1.2hash后还是有点长3.1.3:解决hash冲突 3.2:自增序列算法 1:为什么将长链转化为短链? 1、链接变短…

2022年最新Python学习路线图(内附视频资料)【六张图带你掌握Python技巧】

目录 一、基础语法学习 二、制定发展方向 三、编程实践 四、资料获取 五、学习路线图​ 一、基础语法学习 Python的基础语法包括两大部分,其一是函数式编程部分,其二是面向对象编程部分。函数式部分的内容还是比较简单的,包括列表、函数…

零基础Python学习路线图,小白的进阶之路!

近几年Python的受欢迎程度可谓是扶摇直上,当然了学习的人也是愈来愈多。一些学习Python的小白在学习初期,总希望能够得到一份Python学习路线图,小编经过多方汇总为大家汇总了一份Python学习路线图。 对于一个零基础的想学习python的朋友来说…

15张超详细的Python学习路线图,纯良心分享,零基础学习宝典

这是一篇 Python 入门指南,针对那些没有任何编程经验,从零开始学习 Python 的同学。不管你学习的出发点是兴趣驱动、拓展思维,还是工作需要、想要转行,都可以用此文作为一个参考。 在这个信息爆炸的时代,以 “Python入…

2020最新版Python学习路线图

Python学习路线图网上有很多版本,前川网的这套Python学习路线图是2020最新版的,是根据企业招聘的要求不断更新的学习路线图,对之前的Pyhton学习路线图做了一些调整和改变,想要用Python爬虫或者深度学习人工智能的看这套Python学习…

Python 学习之路

最近在疫情静默管理期间,刚好有时间可以学习一下Python,非常幸运,找到一本Eric Matthes的《Python Crash Course》Python编程从入门到实践,好好研究一下。基础的语法就是一带而过了,使用的Python3.8.10版本&#xff0c…

一文讲清Python的7大学习路线(建议收藏)

现如今铺天盖地都是来自学习Python的勇士,Python这个编程语言中最友好的语言早已不是高不可攀的状态了。 无论是业余爱好,还是专职求学,学习Python的朋友都在依靠着自己的方法,勤勤恳恳的学习着,但是学习有方向&#x…

超全的Python学习路线图

Python是一种编程语言 完成同一个任务,C语言要写1000行代码,Java只需要写100行,而Python可能只要20行。用Python完成项目,编写的代码量更少,代码简短可读性强,团队协作开发时读别人的代码速度会非常快&…

零基础Python学习路线图

Python学习路线图先奉上: Python教程_完全入门 推荐视频:https://www.bilibili.com/video/BV1jZ4y1p7zQ Python学习路线 第一阶段Python基础与Linux数据库 掌握Python基本语法规则及变量、逻辑控制、内置数据结构、文件操作、高级函数、模块、常用标…

Python学习路线图(2021最新版)

这是我最开始学Python时的一套学习路线,从入门到上手。(不敢说精通,哈哈~) 一、Python基础知识、变量、数据类型 二、Python条件结构、循环结构 三、Python函数 四、字符串 五、列表与元组 六、字典与集合 最后再送给大家一套免费…

python学习路线-思维导图

文章目录 1. python学习大纲2. python基础大纲2.1 python语言基础2.2 标准数据类型12.3 标准类型补充2.4 标准数据类型22.5 标准数据类型32.6 条件&循环2.7 计算机基础 3. python进阶大纲3.1 进阶条件&循环3.2 函数&模块3.3 面向对象3.4 补充知识3.5 文件对象3.6 异…