openCV3中双目深度BM算法参数解析
最近使用opencv做有关双目校正以及深度检测的工作,在深度检测时使用到BM算法,特别感谢这两位的博客解析https://blog.****.net/bennygato/article/details/37708195 , https://blog.****.net/zilanpotou182/article/details/72329903
在这两篇博文的指导下很快就熟悉了opencv中视差的使用,但对于新手来说其中的相关参数的作用却不是很了解,在调参数时不能根据实际情况调节相关参数。
opencv中三种算法的运算速度方面BM>SGBM>GC,但相反实际效果BM<SGBM<GC,以及在opencv3中BM算法的更新的使用方法详细内容可以点击第二个链接,进博客自行阅读。在使用BM算法时,需要具体设置的参数
- //BM(bidirectional matching)算法进行双向匹配,首先通过匹配代价在右图中计算得出匹配点。
- //然后相同的原理及计算在左图中的匹配点。比较找到的左匹配点和源匹配点是否一致,如果是,则匹配成功。
- //初始化 stereoBMstate 结构体
- //错误:不允许使用抽象类型的stereoBM对象
- //C++中含有纯虚拟函数并且所有纯虚函数并未完全实现的类称为抽象类,它不能生成对象
- //opencv3以后的版本不能这么用了
- //StereoBM bm;
- //int unitDisparity = 15;//40
- //int numberOfDisparities = unitDisparity * 16;
- //bm.state->roi1 = roi1;
- //bm.state->roi2 = roi2;
- //bm.state->preFilterCap = 13;
- //bm.state->SADWindowSize = 19;
- //bm.state->minDisparity = 0;
- //bm.state->numberOfDisparities = numberOfDisparities;
- //bm.state->textureThreshold = 1000;
- //bm.state->uniquenessRatio = 1;
- //bm.state->speckleWindowSize = 200;
- //bm.state->speckleRange = 32;
- //bm.state->disp12MaxDiff = -1;
- cv::Ptr<cv::StereoBM> bm = cv::StereoBM::create();
- int unitDisparity = 15;//40
- int numberOfDisparities = unitDisparity * 16;
- bm->setROI1(roi1);
- bm->setROI2 (roi2);
- bm->setPreFilterCap(13);
- bm->setBlockSize = 15; //SAD窗口大小 设置为奇数
- bm->setMinDisparity(0); //确定匹配搜索从哪里开始 默认值是0
- bm->setNumDisparities(numberOfDisparities) ; //在该数值确定的视差范围内进行搜索,视差窗口
- // 即最大视差值与最小视差值之差, 大小必须是16的整数倍
- bm->setTextureThreshold(1000); //保证有足够的纹理以克服噪声
- bm->setUniquenessRatio(1); //使用匹配功能模式
- bm->setSpeckleWindowSize(200); //检查视差连通区域变化度的窗口大小, 值为0时取消 speckle 检查
- bm->setSpeckleRange(32); // 视差变化阈值,当窗口内视差变化大于阈值时,该窗口内的视差清零
- bm->setDisp12MaxDiff(-1); //左视差图(直接计算得出)和右视差图(通过cvValidateDisparity计算得出)
- // 之间的最大容许差异,默认为-1
其中影响最大的是SAD窗口大小、setNumDisparities、setSpeckleWindowSize三个参数。
SAD一般为5以上的奇数, numberOfDisparities = ((src0.cols / 8) + 15) & -16;
在实际的调试过程中,经过多次调解上面三个参数在显示时发现根本不能正常观测到深度信息,像图一样这种白色块过大,不能显示更加详细的信息的情况。
调节bm->setSpeckleWindowSize(0); 这种情况是此参数过大,逐步减小此参数便能得到细节信息。这张图片上传不了就不上效果图了。另外视差效果图白色块过大看不出效果的情况也可能是视差变化阈值bm->setSpeckleRange(32);