编程语言
首页 > 编程语言> > C++实现opencv中的SGBM匹配算法并实现调参

C++实现opencv中的SGBM匹配算法并实现调参

作者:互联网

实现SGBM调参

C++实现

SGBM的各个参数意义,请参考https://blog.csdn.net/wwp2016/article/details/86080722

整个程序分为3部分SGBMStart,SGBMUpdate,main

#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
using namespace std;
using namespace cv;
// 声明一些全局变量
cv::Ptr<cv::StereoSGBM> SGBM = cv::StereoSGBM::create();

//回调函数
void SGBMUpdate(int pos, void* data) {
	//cv::Mat disp;
	int SGBMNum = 2;
	int blockSize = cv::getTrackbarPos("blockSize", "SGBM_disparity");
	if (blockSize % 2 == 0){
		blockSize += 1;
	}
	if (blockSize < 5){
		blockSize = 5;
	}
	SGBM->setBlockSize(blockSize);
	SGBM->setNumDisparities(cv::getTrackbarPos("numDisparities", "SGBM_disparity"));
	SGBM->setSpeckleWindowSize(cv::getTrackbarPos("speckleWindowSize", "SGBM_disparity"));
	SGBM->setSpeckleRange(cv::getTrackbarPos("speckleRange", "SGBM_disparity"));
	SGBM->setUniquenessRatio(cv::getTrackbarPos("uniquenessRatio", "SGBM_disparity"));
	SGBM->setDisp12MaxDiff(cv::getTrackbarPos("disp12MaxDiff", "SGBM_disparity"));
	/*int P1 = 8 * left.channels() * SADWindowSize* SADWindowSize;
	int P2 = 32 * left.channels() * SADWindowSize* SADWindowSize;*/
	// 惩罚系数,一般:P1=8*通道数*SADWindowSize*SADWindowSize,P2=4*P1
	SGBM->setP1(600);
	// p1控制视差平滑度,p2值越大,差异越平滑
	SGBM->setP2(2400);
	SGBM->setMode(cv::StereoSGBM::MODE_SGBM);
	
}

/*
	SGBM函数初始化函数
*/
void SGBMStart() {
	// 最小视差值
	int minDisparity = 0;
	int SGBMNum = 2;
	// 视差范围,即最大视差值和最小视差值之差,必须是16的倍数。
	int numDisparities = SGBMNum * 16;
	// 匹配块大小,大于1的奇数
	int blockSize = 5; 
	// P1, P2控制视差图的光滑度
	// 惩罚系数,一般:P1 = 8 * 通道数*SADWindowSize*SADWindowSize,P2 = 4 * P1
	int P1 = 600;  
	// p1控制视差平滑度,p2值越大,差异越平滑
	int P2 = 2400; 
	// 左右视差图的最大容许差异(超过将被清零),默认为 - 1,即不执行左右视差检查。
	int disp12MaxDiff = 200; 
	int preFilterCap = 0;
	// 视差唯一性百分比, 视差窗口范围内最低代价是次低代价的(1 + uniquenessRatio / 100)倍时,最低代价对应的视差值才是该像素点的视差,否则该像素点的视差为 0,通常为5~15.
	int uniquenessRatio = 6; 
	// 平滑视差区域的最大尺寸,以考虑其噪声斑点和无效。将其设置为0可禁用斑点过滤。否则,将其设置在50 - 200的范围内。
	int speckleWindowSize = 60; 
	// 视差变化阈值,每个连接组件内的最大视差变化。如果你做斑点过滤,将参数设置为正值,它将被隐式乘以16.通常,1或2就足够好了
	int speckleRange = 2; 
	
	//cv::namedWindow("SGBM_disparity");
	cv::createTrackbar("blockSize", "SGBM_disparity", &blockSize, 21, SGBMUpdate);
	cv::createTrackbar("numDisparities", "SGBM_disparity", &numDisparities, 20, SGBMUpdate);
	cv::createTrackbar("speckleWindowSize", "SGBM_disparity", &speckleWindowSize, 200, SGBMUpdate);
	cv::createTrackbar("speckleRange", "SGBM_disparity", &speckleRange, 50, SGBMUpdate);
	cv::createTrackbar("uniquenessRatio", "SGBM_disparity", &uniquenessRatio, 50, SGBMUpdate);
	cv::createTrackbar("disp12MaxDiff", "SGBM_disparity", &disp12MaxDiff, 21, SGBMUpdate);
	
	// 创建SGBM算法对象
	
}

int main() {
	cv::Mat left = imread("D:\\1.7.7\\pic\\left.png", IMREAD_GRAYSCALE);
	cv::Mat right = imread("D:\\1.7.7\\pic\\right.png", IMREAD_GRAYSCALE);
	cv::Mat disp;
	cv::namedWindow("SGBM_disparity");
	SGBMStart();
	
	while (true) {
		SGBM->compute(left, right, disp);
		cv::Mat disp8U = Mat(disp.rows, disp.cols, CV_8UC1);       //显示
		normalize(disp, disp8U, 0, 255, NORM_MINMAX, CV_8UC1);
		cv::imshow("SGBM_disparity", disp8U);
		cv::waitKey(4);
	}
	return 0;

}

效果图
在这里插入图片描述

标签:SGBM,int,调参,C++,disparity,blockSize,cv,视差
来源: https://blog.csdn.net/Jerseywwwwei/article/details/101385139