立体匹配在OpenCV中的实现(BM和SGBM算法)

        有关双目稠密匹配算法,OpenCV提供了BM和SGBM的实现。本文主要介绍其代码实现

        首先,需要定义相关变量。

    cv::Mat imL, imR, disparity;

        其次,在当前路径下存放双目的左视图和右视图,或者在其他路径下存放也可以,不过需要用到绝对路径。此处使用相对路径。

	imL = cv::imread("imL.png", 0);
	imR = cv::imread("imR.png", 0);

        值得注意的是,默认状态下,OpenCV中的imread会将flag设置为1,也就是读入图像均为BGR三通道图像(包括灰度图像)。如果flag设为0,则转为灰度图像。

        (1)BM的代码实现

	int num_disp = 16;
	int bsize = 9;

	cv::Ptr<cv::StereoBM> bm = cv::StereoBM::create(num_disp, bsize);

	// 设置参数
	bm->setPreFilterType(CV_STEREO_BM_NORMALIZED_RESPONSE);
	bm->setPreFilterSize(9);
	bm->setPreFilterCap(31);
	bm->setBlockSize(9);
	bm->setMinDisparity(0);
	bm->setNumDisparities(16);
	bm->setTextureThreshold(10);
	bm->setUniquenessRatio(5);
	bm->setSpeckleWindowSize(100);
	bm->setSpeckleRange(32);

	// 计算视差
	bm->compute(imL, imR, disparity);

	// 将视差图的值除以16,同时转换为32为float型
	disparity.convertTo(disparity, CV_32F, 1.0 / 16);

        代码中变量num_disp表示自行设置的最大视差值,bsize为匹配块的大小。这两个为必须设置的参数,其他参数可以使用默认值,如有需要可以设置(在设置参数部分)。视差图的值除以16,得到真实视差。此时disparity中最大值为15。

        (2)SGBM的代码实现

	int min_disp = 0;
	int num_disp = 16;
	int bsize = 3;

	// 设置参数
	cv::Ptr<cv::StereoSGBM> left_matcher = cv::StereoSGBM::create(min_disp, num_disp, bsize);

	left_matcher->setP1(24 * bsize * bsize);
	left_matcher->setP2(96 * bsize * bsize);
	left_matcher->setPreFilterCap(63);
	left_matcher->setMode(cv::StereoSGBM::MODE_SGBM_3WAY);

	// 计算视差
	left_matcher->compute(imL, imR, disparity);

	// 转换视差
	disparity.convertTo(disparity, CV_32F, 1.0 / 16);

        SGBM和BM的参数设置类似,只不过必要的参数需要增加一个min_disp,即最小视差。此外,SGBM的效果也更好。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值