OpenCV BM对于处理非畸变的立体图像, 主要有以下 3 个步骤:

1. 预处理滤波: 使图像亮度归一化并加强图像纹理

2. 立体匹配: 沿着水平极线用 SAD 窗口进行匹配搜索

3. 再滤波: 去除坏的匹配点.

匹配之后, 如果左右视差检查使能了 disp12MaxDiff >= 0, 还有使用

cv::validateDisparity进行左右视差检查.

最后, 由于匹配窗口捕捉的是物体一侧的前景和另一侧的背景, 基于块匹配在物体边界附近会有一些问题.

这会导致同时产生大小视差的局部区域(散斑). 可以通过 filterSpeckles 滤除散斑.

1 预处理滤波

预处理滤波(Pre-filter), 左右两个矫正过的图像并行计算, 使图像亮度归一化并加强图像纹理.

  • 在预处理滤波中 输入图像被归一化处理, 从而减少了亮度差异, 也增强了图像纹理. 算法:

  • X-方向 Sobel运算, 可以加强 X 方向图像纹理, 同时归一化图像亮度
    (计算图像亮度梯度的近似值, 然后归一化到 [0, 2ftzero], ftzero: 预处理滤波截断值).

  • “Normalized Response” TODO

  • 这个过程通过在整幅图像上移动窗口实现, 窗口大小 [5×5, 7×7 … 21×21].

  • 最后得到两张滤波后图像, 然后用于下一步匹配

2 立体匹配

即 Stereo correspondence.

立体匹配: 沿着水平极线用 SAD 窗口进行匹配搜索 多路并行计算

结果: 生成视差图.

对左图像的每个特征而言, 搜索右图像中对应行以找到最佳匹配.

校正之后, 每一行就是一条极线, 因此右图像上的匹配位置就一定会在左图像的相同行上

(即具有同样的 y 坐标).

如果特征有足够多的可检测纹理, 并且位于右相机视图内, 就可以找出该匹配位置 如图:

如果左特征像素位于 (x0,y0) 那么对于水平前向平行的相机排列,

它的匹配点(若有)就一定与 x0 在同一行,

3 再滤波

或后滤波即 Post-filters, knock out bad matches.

在立体匹配后开始后滤波成处理, 仅在视差唯一性百分比(uniqueness_ratio)大于 0 时才执行,

去除坏的匹配点, 预防虚匹配.

由于匹配值经常有一个特点 — 强烈的中央峰被副瓣包围

因此视差窗口范围内最低代价是次低代价的 (1 + uniquenessRatio / 100) 倍时,

最低代价对应的视差值才是该像素点的视差, 否则该像素点的视差为 0. 即 SAD 的阈值为:

int const thresh = minsad + (minsad * uniquenessRatio / 100);.

因此检查 idx in [0, nDisp) 共 nDisp 个 SADs,

如果idx 不在 [minDispIdx – 1, minDispIdx + 1] 范围内,

并且SAD 值小于或等于 thresh 则视差无效:

for (d = 0; d < nDisp; ++d) {if (((d < minDispIdx - 1) || (d > minDispIdx + 1)) && (sad[d] <= thresh)) {break;}
}
if (d < nDisp) {dptr[y * dstep] = FILTERED;continue;
}

立体匹配主要是通过找出每对图像间的对应关系,根据三角测量原理,得到视差图;在获得了视差信息后,根据投影模型很容易地可以得到原始图像的深度信息和三维信息。立体匹配技术被普遍认为是立体视觉中最困难也是最关键的问题,主要是以下因素的影响:

(1) 光学失真和噪声(亮度、色调、饱和度等失衡)

(2) 平滑表面的镜面反射

(3) 投影缩减(Foreshortening)

(4) 透视失真(Perspective distortions)

(5) 低纹理(Low texture)

(6) 重复纹理(Repetitive/ambiguous patterns)

(7) 透明物体

(8) 重叠和非连续

目前立体匹配算法是计算机视觉中的一个难点和热点,算法很多,但是一般的步骤是:

A、匹配代价计算

匹配代价计算是整个立体匹配算法的基础,实际是对不同视差下进行灰度相似性测量。常见的方法有灰度差的平方SD(squared intensity differences),灰度差的绝对值AD(absolute intensity differences)等。另外,在求原始匹配代价时可以设定一个上限值,来减弱叠加过程中的误匹配的影响。以AD法求匹配代价为例,可用下式进行计算,其中T为设定的阈值。

图18

B、 匹配代价叠加

一般来说,全局算法基于原始匹配代价进行后续算法计算。而区域算法则需要通过窗口叠加来增强匹配代价的可靠性,根据原始匹配代价不同,可分为:

图19

C、 视差获取

对于区域算法来说,在完成匹配代价的叠加以后,视差的获取就很容易了,只需在一定范围内选取叠加匹配代价最优的点(SAD和SSD取最小值,NCC取最大值)作为对应匹配点,如胜者为王算法WTA(Winner-take-all)。而全局算法则直接对原始匹配代价进行处理,一般会先给出一个能量评价函数,然后通过不同的优化算法来求得能量的最小值,同时每个点的视差值也就计算出来了。

D、视差细化(亚像素级)

大多数立体匹配算法计算出来的视差都是一些离散的特定整数值,可满足一般应用的精度要求。但在一些精度要求比较高的场合,如精确的三维重构中,就需要在初始视差获取后采用一些措施对视差进行细化,如匹配代价的曲线拟合、图像滤波、图像分割等。

有关立体匹配的介绍和常见匹配算法的比较,推荐大家看看Stefano Mattoccia 的讲义 Stereo Vision: algorithms and applications,190页的ppt,讲解得非常形象详尽。

opencv-StereoBM算法流程(二)相关推荐

  1. SURF网格化特征点提取算法流程(一)

    SURF网格化特征点提取算法流程(一) 相关: SURF网格化特征点提取的算法流程(二) SURF网格化特征点提取的算法流程(三) SURF网格化算法主要包括下面三个阶段: 第一部分:特征点检测 1. ...

  2. OpenCV学习笔记(二十六)——小试SVM算法ml OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video Ope

    OpenCV学习笔记(二十六)--小试SVM算法ml 总感觉自己停留在码农的初级阶段,要想更上一层,就得静下心来,好好研究一下算法的东西.OpenCV作为一个计算机视觉的开源库,肯定不会只停留在数字图 ...

  3. OpenCV学习笔记(二十一)——绘图函数core OpenCV学习笔记(二十二)——粒子滤波跟踪方法 OpenCV学习笔记(二十三)——OpenCV的GUI之凤凰涅槃Qt OpenCV学习笔记(二十

    OpenCV学习笔记(二十一)--绘图函数core 在图像中,我们经常想要在图像中做一些标识记号,这就需要绘图函数.OpenCV虽然没有太优秀的GUI,但在绘图方面还是做得很完整的.这里就介绍一下相关 ...

  4. Zbar算法流程介绍

    算法介绍: zbar算法是现在网上开源的条形码,二维码检测算法,算法可识别大部分种类的一维码(条形码),比如I25,CODE39,CODE128,不过大家更关心的应该是现在很火的QR码的解码效率,随着 ...

  5. OpenCV C++案例实战二十二《手势识别》

    OpenCV C++案例实战二十二<手势识别> 前言 一.手部关键点检测 1.1 功能源码 1.2 功能效果 二.手势识别 2.1算法原理 2.2功能源码 三.结果显示 3.1功能源码 3 ...

  6. OpenCV+python:图像二值化

    1,图像二值化概念及方法 一个像素点的颜色是由RGB三个值来表现的,所以一个像素点矩阵对应三个颜色向量矩阵,分别是R矩阵,G矩阵,B矩阵,它们也都是同样大小的矩阵. 在图像处理中,用RGB三个分量(R ...

  7. 【算法系列 二】Stack

    为什么80%的码农都做不了架构师?>>>    栈应用的场景: 1.括号问题 2.后缀表达式 3.深度优先遍历 4.保存现场 1. 给定字符串,仅由"()[]{}" ...

  8. opencv学习笔记(二):基于肤色的人手检测

    opencv学习笔记(二):基于肤色的人手检测 原文:http://blog.csdn.net/wzmsltw/article/details/50849810 先写了人手的检测程序,下一步基于检测程 ...

  9. opencv 一堆算法,图像处理等

    http://blog.csdn.net/wangzhebupt/article/category/1675453 数据挖掘十大经典实用算法及OpenCV算法 http://www.xuebuyuan ...

  10. moead算法流程步骤_数据聚类(一)常见聚类算法的基本原理[图解]

    文章整理了五种常见聚类算法的基本原理,通过简易图解的形式对算法原理进行形象化的描述,同时给出了算法的实现流程和数学表达.全文约4192字. 相关名词的英文翻译 监督学习Supervised Learn ...

最新文章

  1. 基于激光雷达的里程计及3D点云地图中的定位方法
  2. globalmem设备代码分析
  3. 主流mes厂商_MES为什么可以成为企业核心
  4. 【OS学习笔记】三十二 保护模式九:分页机制对应的汇编代码之---内核代码
  5. 机器学习 - 随机森林手动10 折交叉验证
  6. Linux系统:centos7下搭建ZooKeeper3.4中间件,常用命令总结
  7. 差分隐私与机器学习的综述【笔记】
  8. java实现单向循环链表_java实现的带头单向循环链表
  9. android studio ADT+SDK \appium下载与安装
  10. 扣费克星-您的话费守护神 v1.42 新增联网程序管理扩展插件发布
  11. 批量修改密码脚本--------小练习
  12. windows上装Ubuntu
  13. 韦德是梦八“救火队员“
  14. Pytorch中Parameter的打印和修改
  15. 断裂韧性、冲击强度、抗弯强度——烧结钕铁硼的力学性能
  16. GOF设计模式之组合设计模式(结构型模式) ✨ 每日积累
  17. 计算机学院 讲坛名称,计算机学院举办科技节之“学子讲坛”
  18. 1.工厂模式获取服务实例
  19. win10运行无线服务器,win10系统无线不能用没有运行windows无线服务的解决方法
  20. 曝光 兼职达人(深圳市青木网络科技)无耻、恶心

热门文章

  1. mysql怎么安装安全补丁_MySQL 安装与安全优化
  2. SpringMVC重要注解(二)@ControllerAdvice
  3. hdu训练赛 火球术(组合数打表)
  4. 我爱你用计算机二进制怎么表示,520用数学公式怎么表达
  5. 多线程并发知识,肝完这篇10W+字超详细的文章就够了
  6. 利用VBA实现word文档手写体打印
  7. 【操作类】使用file-saver导出excel
  8. 接入萤石云的踩坑问题
  9. mac u盘只读怎么修改_解决Mac U盘不能写入问题
  10. OpenGL蓝宝书源码学习(准备工作)