openCV CV::StereoSGBM_create()参数的含义

static Ptr cv::StereoSGBM::create (
int minDisparity = 0,
int numDisparities = 16,
int blockSize = 3,
int P1 = 0,
int P2 = 0,
int disp12MaxDiff = 0,
int preFilterCap = 0,
int uniquenessRatio = 0,
int speckleWindowSize = 0,
int speckleRange = 0,
int mode = StereoSGBM::MODE_SGBM
)
1、minDisparity 最小可能的差异值。通常情况下,它是零,但有时整流算法可能会改变图像,所以这个参数需要作相应的调整。
2、numDisparities 最大差异减去最小差异。该值总是大于零。在当前的实现中,该参数必须可以被16整除。
3、BLOCKSIZE 匹配的块大小。它必须是> = 1的奇数。通常情况下,它应该在3…11的范围内。
4、P1 控制视差平滑度的第一个参数。见下文。
5、P2 第二个参数控制视差平滑度。值越大,差异越平滑。P1是相邻像素之间的视差变化加或减1的惩罚。P2是相邻像素之间的视差变化超过1的惩罚。该算法需要P2> P1。请参见stereo_match.cpp示例,其中显示了一些相当好的P1和P2值(分别为8 * number_of_image_channels * SADWindowSize * SADWindowSize和32 * number_of_image_channels * SADWindowSize * SADWindowSize)。
6、disp12MaxDiff 左右视差检查中允许的最大差异(以整数像素为单位)。将其设置为非正值以禁用检查。
7、preFilterCap 预滤波图像像素的截断值。该算法首先计算每个像素的x导数,并通过[preFilterCap,preFilterCap]间隔剪切其值。结果值传递给Birchfield-Tomasi像素成本函数。
8、uniquenessRatio 最佳(最小)计算成本函数值应该“赢”第二个最佳值以考虑找到的匹配正确的百分比保证金。通常,5-15范围内的值就足够了。
9、speckleWindowSize 平滑视差区域的最大尺寸,以考虑其噪声斑点和无效。将其设置为0可禁用斑点过滤。否则,将其设置在50-200的范围内。
10、speckleRange 每个连接组件内的最大视差变化。如果你做斑点过滤,将参数设置为正值,它将被隐式乘以16.通常,1或2就足够好了。
11、mode 将其设置为StereoSGBM :: MODE_HH以运行全尺寸双通道动态编程算法。它将消耗O(W * H * numDisparities)字节,这对640x480立体声很大,对于HD尺寸的图片很大。默认情况下,它被设置为false。

英文源文档见链接

opencv中SGBM算法的参数含义及数值选取

一、 预处理参数

1:preFilterCap:水平sobel预处理后,映射滤波器大小。默认为15

int ftzero =max(params.preFilterCap, 15) | 1;

opencv测试例程stereo_match.cpp中取63。

二 、代价参数

2:SADWindowSize:计算代价步骤中SAD窗口的大小。由源码得,此窗口默认大小为5。

SADWindowSize.width= SADWindowSize.height = params.SADWindowSize > 0 ?params.SADWindowSize : 5;

注:窗口大小应为奇数,一般应在3x3到21x21之间。

3:minDisparity:最小视差,默认为0。此参数决定左图中的像素点在右图匹配搜索的起点。int 类型

4:numberOfDisparities:视差搜索范围,其值必须为16的整数倍(CV_Assert( D % 16 == 0 );)。最大搜索边界= numberOfDisparities+ minDisparity。int 类型

三 、动态规划参数

动态规划有两个参数,分别是P1、P2,它们控制视差变化平滑性的参数。P1、P2的值越大,视差越平滑。P1是相邻像素点视差增/减 1 时的惩罚系数;P2是相邻像素点视差变化值大于1时的惩罚系数。P2必须大于P1。需要指出,在动态规划时,P1和P2都是常数。

5:opencv测试例程stereo_match.cpp中,P1 = 8cnsgbmWinSize*sgbmWinSize;

6:opencv测试例程stereo_match.cpp中,P2 = 32cnsgbmWinSize*sgbmWinSize;
四、后处理参数

7:uniquenessRatio:唯一性检测参数。对于左图匹配像素点来说,先定义在numberOfDisparities搜索区间内的最低代价为mincost,次低代价为secdmincost。如果满足在这里插入图片描述
即说明最低代价和次第代价相差太小,也就是匹配的区分度不够,就认为当前匹配像素点是误匹配的。

opencv测试例程stereo_match.cpp中,uniquenessRatio=10。int 类型

8:disp12MaxDiff:左右一致性检测最大容许误差阈值。int 类型

opencv测试例程stereo_match.cpp中,disp12MaxDiff =1。

9:speckleWindowSize:视差连通区域像素点个数的大小。对于每一个视差点,当其连通区域的像素点个数小于speckleWindowSize时,认为该视差值无效,是噪点。

opencv测试例程stereo_match.cpp中,speckleWindowSize=100。

10:speckleRange:视差连通条件,在计算一个视差点的连通区域时,当下一个像素点视差变化绝对值大于speckleRange就认为下一个视差像素点和当前视差像素点是不连通的。

opencv测试例程stereo_match.cpp中,speckleRange=10。

测试示例:

enum { STEREO_BM = 0, STEREO_SGBM = 1, STEREO_HH = 2, STEREO_VAR = 3, STEREO_3WAY = 4 };
 
void calDispWithSGBM(Mat imgL, Mat imgR, Mat &imgDisparity8U)
{
	cv::Size imgSize = imgL.size();
	int numberOfDisparities = ((imgSize.width / 8) + 15) & -16;
	cv::Ptr<cv::StereoSGBM> sgbm = cv::StereoSGBM::create(0, 16, 3);
 
	sgbm->setPreFilterCap(63);
 
	int SADWindowSize = 9;
	int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;
	sgbm->setBlockSize(sgbmWinSize);
 
	int cn = imgL.channels();
	sgbm->setP1(8 * cn*sgbmWinSize*sgbmWinSize);
	sgbm->setP2(32 * cn*sgbmWinSize*sgbmWinSize);
 
	sgbm->setMinDisparity(0);
	sgbm->setNumDisparities(numberOfDisparities);
	sgbm->setUniquenessRatio(10);
	sgbm->setSpeckleWindowSize(100);
	sgbm->setSpeckleRange(32);
	sgbm->setDisp12MaxDiff(1);
 
	int alg = STEREO_SGBM;
	if (alg == STEREO_HH)
		sgbm->setMode(cv::StereoSGBM::MODE_HH);
	else if (alg == STEREO_SGBM)
		sgbm->setMode(cv::StereoSGBM::MODE_SGBM);
	else if (alg == STEREO_3WAY)
		sgbm->setMode(cv::StereoSGBM::MODE_SGBM_3WAY);
 
	Mat imgDisparity16S = Mat(imgL.rows, imgL.cols, CV_16S);
	sgbm->compute(imgL, imgR, imgDisparity16S);
 
	//--Display it as a CV_8UC1 image:16位有符号转为8位无符号
	imgDisparity16S.convertTo(imgDisparity8U, CV_8U, 255 / (numberOfDisparities*16.));
}
 
int main()
{
	//--读取图像
	Mat imgL = imread("..\\image\\aloeL.jpg", 0);
	Mat imgR = imread("..\\image\\aloeR.jpg", 0);
 
	//--And create the image in which we will save our disparities
	Mat imgDisparity8U = Mat(imgL.rows, imgL.cols, CV_8UC1);
 
	//calDispWithBM(imgL, imgR, imgDisparity8U);
	calDispWithSGBM(imgL, imgR, imgDisparity8U);
}

在这里插入图片描述

  • 8
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果在调用`cv::StereoSGBM::create()`函数时报错参数太少,可能是因为你使用的OpenCV版本较旧,或者你的编译设置有问题。 解决这个问题的方法是使用更详细的构造函数来创建`cv::StereoSGBM`对象,而不是使用`create()`函数。下面是一个示例代码: ```cpp #include <opencv2/opencv.hpp> int main() { // 读取左右图像 cv::Mat leftImage = cv::imread("left_image.png", cv::IMREAD_GRAYSCALE); cv::Mat rightImage = cv::imread("right_image.png", cv::IMREAD_GRAYSCALE); // 创建SGBM对象 cv::Ptr<cv::StereoSGBM> sgbm = cv::StereoSGBM::create(0, 16, 11); // 设置SGBM参数 sgbm->setPreFilterCap(63); // 预处理滤波器的最大值 sgbm->setUniquenessRatio(10); // 视差唯一性比率 sgbm->setSpeckleWindowSize(100); // 噪声区域的最大尺寸 sgbm->setSpeckleRange(32); // 噪声视差范围 sgbm->setDisp12MaxDiff(1); // 左右一致性检查的最大差异 // 计算视差图 cv::Mat disparityMap; sgbm->compute(leftImage, rightImage, disparityMap); // 显示视差图 cv::imshow("Disparity Map", disparityMap); cv::waitKey(0); return 0; } ``` 在这个示例中,我们在创建SGBM对象时使用了更详细的构造函数`cv::StereoSGBM::create(minDisparity, numDisparities, blockSize)`。你可以根据实际需要调整这些参数的值。然后,再通过调用成员函数来设置其他参数,并计算和显示视差图。 请确保已经正确安装了OpenCV库,并将示例代码中的图像文件路径替换为你自己的图像路径。如果仍然遇到问题,请确保你使用的是最新的OpenCV版本,并检查编译设置是否正确。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值