使用的opencv版本是4.5.4,StereoBM可设置的参数及其解释如下。
/*图像预处理匹配*/ bm->setPreFilterCap(63);///31///预处理滤波器的截断值,计算每个像素的x导数,并按[-preFilterCap, preFilterCap]间隔切割其值,结果值传递给 Birchfield-Tomasi 像素成本函数。 bm->setPreFilterSize(7);//预处理滤波器窗口大小,容许范围是[5,255],一般应该在 5x5..21x21 参数之间必须是奇数值 bm->setPreFilterType(cv::StereoBM::PREFILTER_XSOBEL);//预处理滤波器有两种类型:PREFILTER_NORMALIZED_RESPONSE(归一化响应) 或者 PREFILTER_XSOBEL (水平方向Sobel算子,默认类型) /*计算视差参数*/ //bm->setSmallerBlockSize(blockSize/2);// bm->setTextureThreshold(30);如果当前窗口中所有邻居像素点的x导数绝对值之和小于指定阈值,则该窗口对应像素点的视差为0 bm->setUniquenessRatio(10);// 视差窗内最低成本(指最佳结果)为次低成本(1 uniquenessRatio/100)倍时,最低成本对应的视差为像素点的视差,否则像素点的视差为 0.一般5-15左右的值比较合适,价格是多少? bm->setBlockSize(blockSize);// 块的大小,应该是奇数,取值3,11更合适,大块的大小意味着视差图更光滑但不准确。 小块的大小提供了更详细的视差图,但算法发现错误对应关系的机会更大。 bm->setDisp12MaxDiff(-1);//左视差图(直接计算)和右视差图(通过cvValidateDisparity计算)之间的最大允许差。超过阈值的视差将被清除。默认情况下,该参数被认为是 -1,即不执行左右视差检查。 bm->setMinDisparity(0); bm->setNumDisparities(numOfDisparities);// 搜索视差时的范围【MinDisparity,MinDisparity numOfDisparities】,必须是16的整数倍 /*视差图后处理*/ ///计算初始视差图后,将对视差图进行处理,包括中值滤波、连通域检测等。 ///中值滤波可以有效去除视差图中孤立的噪声,连接域检测可以检测视差图中噪声引起的小块(blob)。 ///判断当前像素点邻域点与当前像素点之间的差异diff,如果diff<speckRange,这意味着邻域点与当前像素点是连接域并设置标记。 ///然后以邻域点为中心判断邻域点,步骤相同。停止,直到某个像素点的邻域点不符合条件。 ///然后判断标记的像素点的数量count,若像素点数count<=speckleWindowSize,说明连接域是一个小块(blob),因此 ///将当前像素值设置为newValue(表示错误的视差值,newValue一般设置为负数或0值)。否则,这意味着连接域是一个没有处理的大块。 处理完所有像素点后,将设置符合条件的区域newValue值,后续可以用空洞填充等方法重新估计其视差值。 bm->setSpeckleRange(16);//在sgbm根据官方参数介绍,该值乘以16,设置为1或2更合适,bm应该是16/span bm->setSpeckleWindowSize(72);//检查视差连通区域变化度的窗口大小, 值为 0 时取消 speckle 检查,否则取【50,200】内的值比较合适
参考文献: opencv sgbm opencv bm opencv StereoBM各个参数的意义 OpenCV3.4两种立体匹配算法效果对比