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双目测距算法调参的代码,供参考: ```python import cv2 # 读取左右视图图像 imgL = cv2.imread('left.png', 0) imgR = cv2.imread('right.png', 0) # 定义SGBM算法的参数 window_size = 3 min_disp = 0 num_disp = 16 * 5 block_size = 5 uniqueness_ratio = 5 speckle_window_size = 100 speckle_range = 32 disp12_max_diff = 1 # 初始化SGBM算法 stereo = cv2.StereoSGBM_create(minDisparity=min_disp, numDisparities=num_disp, blockSize=block_size, P1=8 * 3 * window_size ** 2, P2=32 * 3 * window_size ** 2, disp12MaxDiff=disp12_max_diff, uniquenessRatio=uniqueness_ratio, speckleWindowSize=speckle_window_size, speckleRange=speckle_range) # 计算视差图 disparity = stereo.compute(imgL, imgR).astype(np.float32) / 16.0 # 显示视差图 cv2.imshow('Disparity', (disparity - min_disp) / num_disp) # 等待按键 cv2.waitKey(0) ``` 在这个代码,我们使用了cv2.StereoSGBM_create()函数来初始化SGBM算法。这个函数接受多个参数,包括: - minDisparity:最小视差值。 - numDisparities:最大视差值减去最小视差值,即视差值的范围。 - blockSize:匹配块的大小。 - P1:惩罚系数1。 - P2:惩罚系数2。 - disp12MaxDiff:左右视差图之间的最大差异。 - uniquenessRatio:唯一性比率。 - speckleWindowSize:去除孤立点的窗口大小。 - speckleRange:孤立点的最大范围。 - preFilterCap:预处理滤波器的最大值。 你可能需要根据你的数据集和应用场景来调整这些参数。一般来说,你可以先尝试使用默认值,然后根据实际效果来微调参数。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值