SGBM(Semi-Global Block Matching)是一种用于计算双目视觉中视差(disparity)的半全局匹配算法,在OpenCV中的实现为semi-global block matching(SGBM)。它是基于全局匹配算法和局部匹配算法的优缺点,提出了一种折中的方法,既能保证视差图的质量,又能降低计算复杂度。
作者:小张Tt | 来源:3DCV
添加微信:CV3d007, 备注:立体匹配, 拉你入群。文末附行业细分交流群。
(相关资料图)
SGBM的原理可以分为以下几个步骤:
预处理:使用水平Sobel算子对左右图像进行边缘检测,得到梯度图像。
匹配代价计算:对于每个像素,计算其在不同视差下与对应像素的匹配代价,通常使用绝对差或平方差作为代价函数。
能量函数最小化:对于每个像素,定义一个能量函数,包括数据项和平滑项。数据项表示匹配代价,平滑项表示相邻像素的视差连续性。使用动态规划的方法,沿着多个方向(通常为8个或16个)计算累积代价,并求取最小值作为最终代价。
视差图生成:对于每个像素,根据最终代价选择最佳视差,并生成视差图。
视差图后处理:对于视差图中的异常值或空洞,使用一些后处理方法进行修复或填充,例如中值滤波、WLS滤波等。
SGBM的参数有以下几个:
minDisparity:最小视差值,默认为0。
numDisparities:视差范围,默认为16。必须是16的整数倍。
blockSize:匹配块大小,默认为3。必须是奇数且大于1。
P1:控制视差平滑度的第一个参数,默认为8blockSize。P1越大,越倾向于生成连续的视差图。
P2:控制视差平滑度的第二个参数,默认为32blockSize。P2越大,越倾向于消除小的视差变化。P2必须大于P1。
disp12MaxDiff:左右一致性检查时允许的最大视差差异,默认为-1,表示不进行检查。
preFilterCap:预处理时截断梯度值的上限,默认为63。
uniquenessRatio:唯一性检查时的阈值,默认为10。表示最佳视差值与次佳视差值之间的比例要大于该阈值才被认为是有效的。
speckleWindowSize:消除噪声斑点时考虑的窗口大小,默认为0,表示不进行消除。
speckleRange:消除噪声斑点时考虑的最大视差变化,默认为0,表示不进行消除。
mode:SGBM算法选择模式,默认为StereoSGBM::MODE_SGBM。可选值有StereoSGBM::MODE_SGBM_3WAY(速度快)、StereoSGBM::MODE_HH4(速度慢)、StereoSGBM::MODE_SGBM(速度中等)、StereoSGBM::MODE_HH(速度慢)。
下面通过调整每个参数来观察其影响效果:初始值设置:
minDisparity = 0numDisparities = 16blockSize = 3P1 = 8*blockSize*blockSizeP2 = 32*blockSize*blockSizedisp12MaxDiff = -1preFilterCap = 63uniquenessRatio = 10speckleWindowSize = 0speckleRange = 0
numDisparities:视差数量越多,能够获取到更多详细的深度信息。但是,增加视差数量也会增加计算量,可能会导致较慢的运行速度以及噪声增多,且增大numDisparities会扩大视差范围,即视差图中可以估计的深度范围增大。如果增大的视差范围超过了场景中实际的深度范围,就会出现黑色区域。黑色区域表示无法进行有效的匹配或估计深度。
minDisparity:最小视差越大,物体离相机近的程度就会变小。如果提高最小视差,则可能会使视差图被高估,因为物体不可能有大于最小视差的负的视差值。而如果最小视差过低,则可能会受到噪声的影响,产生错误的视差值。
blockSize:所选的窗口大小越大,所包含的像素就越多,从而产生更稳定,但粗略的视差图。减小块大小,可以获得反之,一些锐利但可能嘈杂(即不确定)的视差边缘。
P1 和 P2:两种参数都是控制视差变化规则的,从而使结果更平滑,增加这些值会使抗噪声能力更强但同时会失去保留锐度的细节。如果P1和P2参数值过小,则会使视差图中出现许多噪声或未对齐的图像。如果参数值太高,将导致平滑的结果,丢失更多的细节和锐度。
disp12MaxDiff:这个参数用于限制左右视图之间的最大视差数量差异。增加这个值可能会导致插值和未对齐的像素点在图像中显示。但太小的值,则视差较光滑,缺少细节特征。
uniquenessRatio:这个参数是用来控制像素值的唯一性,如果唯一性比例越高,则得到的视差图的噪声和未对齐的像素会越小。但如果唯一性比例太高,则有可能会失去细节特征。
speckleWindowSize:这个参数被用来滤除孤立噪点或者离群值,如果窗口太小,则没有过滤到足够的噪声点而窗口太大则会损失一些细节特征。
speckleRange:这个参数规定一个视差变化的阈值,如果发现视差变化超出了这个阈值,则这个像素应该是一些无用的孤立像素。适当调整该参数可以使其过滤掉孤立的杂点和噪声。
preFilterCap:该参数控制了像素的最大值。如果已经将值限制在负值的范围内,那么它必须和像素值相比较,过滤掉那些值过大的像素点。
mode:SGBM算法的解释模式,分别为SGBM,HHSGBM和SGBM_3WAY。这些模式包含了不同的参数设定,也会影响到视差图的效果。
SGBM:这是默认的解释模式,也是最常用的模式。它代表了Semi-Global Block Matching (SGBM) 算法,该算法利用全局视差的一致性来获得更准确的视差图。
HHSGBM:这代表了üller的快速近似SGBM算法(üller's Hierarchical Semi-Global Block Matching),是一种更快速的算法。它在速度上相对于标准SGBM算法有所优化,但可能在某些情况下会牺牲一些准确性。
SGBM_3WAY:这是一种三通道SGBM算法,它将输入图像的三个通道(BGR)分别作为独立的视差图像进行处理。然后,将三个视差图像中的像素最小化,从而得到最终的视差图。这种方法可以改善处理彩色图像时的准确性。
—END—
目前工坊已经建立了3D视觉方向多个社群,包括SLAM、工业3D视觉、自动驾驶方向,细分群包括:[工业方向]三维点云、结构光、机械臂、缺陷检测、三维测量、TOF、相机标定、综合群;[SLAM方向]多传感器融合、ORB-SLAM、激光SLAM、机器人导航、RTK|GPS|UWB等传感器交流群、SLAM综合讨论群;[自动驾驶方向]深度估计、Transformer、毫米波|激光雷达|视觉摄像头传感器讨论群、多传感器标定、自动驾驶综合群等。[三维重建方向]NeRF、colmap、OpenMVS等。除了这些,还有求职、硬件选型、视觉产品落地等交流群。大家可以添加小助理微信: CV3d007,备注:加群+方向+学校|公司, 小助理会拉你入群。
如果大家对3D视觉某一个细分方向想系统学习[从理论、代码到实战],推荐3D视觉精品课程学习网址:
基础课程:
[1]面向三维视觉算法的C++重要模块精讲:从零基础入门到进阶
[2]如何学习相机模型与标定?(代码+实战)
[3]ROS2从入门到精通:理论与实战
工业3D视觉方向课程:
[1]机械臂抓取从入门到实战课程(理论+源码)
[2]从零搭建一套结构光3D重建系统[理论+源码+实践]
[3]三维点云处理:算法与实战汇总
[4]彻底搞懂基于Open3D的点云处理教程!
[5]3D视觉缺陷检测教程:理论与实战!
SLAM方向课程:
[1]如何高效学习基于LeGo-LOAM框架的激光SLAM?
[1]彻底剖析激光-视觉-IMU-GPS融合SLAM算法:理论推导、代码讲解和实战
[2](第二期)彻底搞懂基于LOAM框架的3D激光SLAM:源码剖析到算法优化
[3]彻底搞懂视觉-惯性SLAM:VINS-Fusion原理精讲与源码剖析
[4]彻底剖析室内、室外激光SLAM关键算法和实战(cartographer+LOAM+LIO-SAM)
[5]ORB-SLAM3理论讲解与代码精析(第2期)
视觉三维重建
[1]彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进)
自动驾驶方向课程:
[1]目标检测中的视觉Transformer
[2]单目深度估计方法:算法梳理与代码实现
[3]面向自动驾驶领域的3D点云目标检测全栈学习路线!(单模态+多模态/数据+代码)
[4]如何将深度学习模型部署到实际工程中?(分类+检测+分割)
标签: