引言:基于OpenCV3.0,對BM、SGBM和GC算法進行了對比測試研究。由于SGBM算法視差效果好速度快的特點,常常被廣泛應用和改進,本文針對SGBM算法主要參數設置作了對比測試,以供大家參考。
BM:Block Matching ,采用SAD方法計算匹配代價;
SGBM: 修改自Heiko Hirschmuller的《Stereo Processing by Semi-global Matching and Mutual Information》:http://www.openrs.org/photogrammetry/2015/SGM%202008%20PAMI%20-%20Stereo%20Processing%20by%20Semiglobal%20Matching%20and%20Mutual%20Informtion.pdf;長按以下二維碼可直接打開
與原方法不同點:
沒有實現原文中基于互信息的匹配代價計算,而是采用BT算法("Depth Discontinuities by Pixel-to-Pixel Stereo()" by S. Birchfield and C. Tomasi);
默認運行單通道DP算法,只用了5個方向,而fullDP使能時則使用8個方向(可能需要占用大量內存);
增加了一些BM算法中的預處理和后處理程序;
GC:OpenCV3.0中沒有實現,可以在OpenCV以下版本中找到。該方法效果是最好的,但是速度太慢,不能達到實時的匹配效率;
1、SGBM
主要參數:minDisparity 、numDisparities、blockSize、P1、P2。其他參數設置參照http://blog.csdn.net/zhubaohua_bupt/article/details/51866567
代碼:
#include "stdafx.h"
#include "opencv2/opencv.hpp
using namespace std;
using namespace cv;
int _tmain(int argc, _TCHAR* argv[])
{
Mat left = imread("imgL.jpg", IMREAD_GRAYSCALE);
Mat right = imread("imgR.jpg", IMREAD_GRAYSCALE);
Mat disp;
int mindisparity = 0;
int ndisparities = 64;
int SADWindowSize = 11;
//SGBM
cv::Ptr
int P1 = 8 * left.channels() * SADWindowSize* SADWindowSize;
int P2 = 32 * left.channels() * SADWindowSize* SADWindowSize;
sgbm->setP1(P1);
sgbm->setP2(P2);
sgbm->setPreFilterCap(15);
sgbm->setUniquenessRatio(10);
sgbm->setSpeckleRange(2);
sgbm->setSpeckleWindowSize(100);
sgbm->setDisp12MaxDiff(1);
//sgbm->setMode(cv::StereoSGBM::MODE_HH);
sgbm->compute(left, right, disp);
disp.convertTo(disp, CV_32F, 1.0 / 16); //除以16得到真實視差值
Mat disp8U = Mat(disp.rows, disp.cols, CV_8UC1); //顯示
normalize(disp, disp8U, 0, 255, NORM_MINMAX, CV_8UC1);
imwrite("results/SGBM.jpg", disp8U);
return 0;
}
minDisparity:最小視差,默認為0。此參數決定左圖中的像素點在右圖匹配搜索的起點,int 類型;
numDisparities:視差搜索范圍長度,其值必須為16的整數倍。最大視差 maxDisparity = minDisparity + numDisparities -1;
blockSize:SAD代價計算窗口大小,默認為5。窗口大小為奇數,一般在3*3 到21*21之間;
P1、P2:能量函數參數,P1是相鄰像素點視差增/減 1 時的懲罰系數;P2是相鄰像素點視差變化值大于1時的懲罰系數。P2必須大于P1。需要指出,在動態規劃時,P1和P2都是常數。
一般建議:P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
總結:
1. blockSize(SADWindowSize) 越小,也就是匹配代價計算的窗口越小,視差圖噪聲越大;blockSize越大,視差圖越平滑;太大的size容易導致過平滑,并且誤匹配增多,體現在視差圖中空洞增多;
2. 懲罰系數控制視差圖的平滑度,P2>P1,P2越大則視差圖越平滑;
3. 八方向動態規劃較五方向改善效果不明顯,主要在圖像邊緣能夠找到正確的匹配;
2、BM
代碼:
#include "stdafx.h"
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int _tmain(int argc, _TCHAR* argv[])
{
Mat left = imread("imgL.jpg", IMREAD_GRAYSCALE);
Mat right = imread("imgR.jpg", IMREAD_GRAYSCALE);
Mat disp;
int mindisparity = 0;
int ndisparities = 64;
int SADWindowSize = 11;
cv::Ptr
// setter
bm->setBlockSize(SADWindowSize);
bm->setMinDisparity(mindisparity);
bm->setNumDisparities(ndisparities);
bm->setPreFilterSize(15);
bm->setPreFilterCap(31);
bm->setTextureThreshold(10);
bm->setUniquenessRatio(10);
bm->setDisp12MaxDiff(1);
copyMakeBorder(left, left, 0, 0, 80, 0, IPL_BORDER_REPLICATE); //防止黑邊
copyMakeBorder(right, right, 0, 0, 80, 0, IPL_BORDER_REPLICATE);
bm->compute(left, right, disp);
disp.convertTo(disp, CV_32F, 1.0 / 16); //除以16得到真實視差值
disp = disp.colRange(80, disp.cols);
Mat disp8U = Mat(disp.rows, disp.cols, CV_8UC1);
normalize(disp, disp8U, 0, 255, NORM_MINMAX, CV_8UC1);
imwrite("results/BM.jpg", disp8U);
return 0;
}
-
機器視覺
+關注
關注
162文章
4388瀏覽量
120444 -
OpenCV
+關注
關注
31文章
635瀏覽量
41387
原文標題:立體匹配算法對比研究
文章出處:【微信號:www_51qudong_com,微信公眾號:機器視覺】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論