關于雙目立體視覺的三大基本算法及發(fā)展現(xiàn)狀的總結
加入極市專業(yè)CV交流群,與?10000+來自港科大、北大、清華、中科院、CMU、騰訊、百度?等名校名企視覺開發(fā)者互動交流!
同時提供每月大咖直播分享、真實項目需求對接、干貨資訊匯總,行業(yè)技術交流。關注?極市平臺?公眾號?,回復?加群,立刻申請入群~
雙目立體視覺一直是機器視覺研究領域的發(fā)展熱點和難點,“熱”是因為雙目立體視覺有著及其廣闊的應用前景,且隨著光學、計算機科學等學科的不斷發(fā)展,雙目立體技術將不斷進步直到應用到人類生活的方方面面?!?strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">難”則是因為受到攝像機、鏡頭等硬件設備及一些相關算法的限制,雙目立體視覺的研究及如何更好的應用到生產實際中仍有待在座的各位去進行突破。
一.簡介
雙目立體視覺是機器視覺中的一個重要分支,自上世紀60年代中期開創(chuàng)以來,經(jīng)過幾十年的發(fā)展,如今在機器人視覺、航空測繪、軍事應及醫(yī)學成像、工業(yè)檢測上應用極其廣泛。雙目立體視覺基于視差原理并利用成像設備從不同的位置獲取被測物體的左右兩幅圖像,然后根據(jù)三角測量原理計算空間點在二維圖像的位置偏差,最后再利用位置偏差進行三維重建來獲取被測物體的三維幾何信息(本文不對雙目立體視覺的數(shù)學原理進行詳細介紹)。
二.雙目立體視覺的三大基本算法的原理及其代碼實現(xiàn)(基于opencv)
雙目立體視覺中常用的基于區(qū)域的局部匹配準則主要有圖像序列中對應像素差的絕對值之和SAD(sum of absolute differences)、對應像素差的平方之和SSD(sum of squared differences)及半全局匹配算法SGM(semi—global matching)。
2.1 SAD(sum of absolute differences)的原理
匹配算法SAD的基本思想是對經(jīng)行對準后的左右視圖圖像的對應像素塊的對應像素差的絕對值進行求和。
其數(shù)學公式如下:

###using namespace std;using namespace cv;class SAD{public:SAD() :winSize(7), DSR(30) {}SAD(int _winSize, int _DSR) :winSize(_winSize), DSR(_DSR) {}Mat computerSAD(Mat &L, Mat &R); //計算SADprivate:int winSize; //卷積核的尺寸int DSR; //視差搜索范圍};Mat SAD::computerSAD(Mat &L, Mat &R){int Height = L.rows;int Width = L.cols;Mat Kernel_L(Size(winSize, winSize), CV_8U, Scalar::all(0));Mat Kernel_R(Size(winSize, winSize), CV_8U, Scalar::all(0));Mat Disparity(Height, Width, CV_8U, Scalar(0)); //視差圖for (int i = 0; i//左圖從DSR開始遍歷 {for (int j = 0; j{Kernel_L = L(Rect(i, j, winSize, winSize));Mat MM(1, DSR, CV_32F, Scalar(0));for (int k = 0; k{int x = i - k;if (x >= 0){Kernel_R = R(Rect(x, j, winSize, winSize));Mat Dif;absdiff(Kernel_L, Kernel_R, Dif);//求差的絕對值之和Scalar ADD = sum(Dif);float a = ADD[0];MM.at<float>(k) = a;}}Point minLoc;minMaxLoc(MM, NULL, NULL, &minLoc, NULL);int loc = minLoc.x;//int loc=DSR-loc;Disparity.at<char>(j, i) = loc * 16;}double rate = double(i) / (Width);cout << "已完成" << setprecision(2) << rate * 100 << "%" << endl; //顯示處理進度}return Disparity;}調用示例:#int main(int argc, char* argv[]){Mat Img_L = imread("Teddy_L.png", 0); //此處調用的圖像已放入項目文件夾中Mat Img_R = imread("Teddy_R.png", 0);Mat Disparity; //創(chuàng)建視差圖SAD mySAD(7, 30); //給出SAD的參數(shù)Disparity = mySAD.computerSAD(Img_L, Img_R);imshow("Teddy_L", Img_L);imshow("Teddy_R", Img_R);imshow("Disparity", Disparity); //顯示視差圖waitKey();system("pause"); //按任意鍵退出return 0;}




enum { STEREO_BM = 0, STEREO_SGBM = 1, STEREO_HH = 2, STEREO_VAR = 3, STEREO_3WAY = 4 };#include"iostream"#include"opencv2/opencv.hpp"using namespace std;using namespace cv;void calDispWithSGBM(Mat Img_L, Mat Img_R, Mat &imgDisparity8U){Size imgSize = Img_L.size();int numberOfDisparities = ((imgSize.width / 8) + 15) & -16;Ptrsgbm = StereoSGBM::create(0, 16, 3); int cn = Img_L.channels(); //左圖像的通道數(shù)int SADWindowSize = 9;int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;sgbm->setMinDisparity(0); //minDisparity最小視差默認為0;sgbm->setNumDisparities(numberOfDisparities); //numDisparity視差搜索范圍,其值必須為16的整數(shù)倍;sgbm->setP1(8 * cn*sgbmWinSize*sgbmWinSize);sgbm->setP2(32 * cn*sgbmWinSize*sgbmWinSize); //一般建議懲罰系數(shù)P1、P2取此兩值,P1、P2控制視差圖的光滑度//P2越大,視差圖越平滑sgbm->setDisp12MaxDiff(1); //左右一致性檢測最大容許誤差閾值sgbm->setPreFilterCap(31); //預處理濾波器的截斷值,預處理的輸出值僅保留//[-preFilterCap, preFilterCap]范圍內的值,參數(shù)范圍:1 - 31sgbm->setUniquenessRatio(10); //視差唯一性百分比:視差窗口范圍內最低代價是次低代價的(1 + uniquenessRatio/100)倍時//最低代價對應的視差值才是該像素點的視差,否則該像素點的視差為 0 ,不能為負值,一般去5——15sgbm->setSpeckleWindowSize(100); //視差連通區(qū)域像素點個數(shù)的大小:對于每一個視差點,當其連通區(qū)域的像素點個數(shù)小于//speckleWindowSize時,認為該視差值無效,是噪點。sgbm->setSpeckleRange(32); //視差連通條件:在計算一個視差點的連通區(qū)域時,當下一個像素點視差變化絕對值大于//speckleRange就認為下一個視差像素點和當前視差像素點是不連通的。sgbm->setMode(0); //模式選擇sgbm->setBlockSize(sgbmWinSize); //設置SAD代價計算窗口,一般在3*3到21*21之間//blockSize(SADWindowSize) 越小,也就是匹配代價計算的窗口越小,視差圖噪聲越大;//blockSize越大,視差圖越平滑;//太大的size容易導致過平滑,并且誤匹配增多,體現(xiàn)在視差圖中空洞增多//三種模式選擇(HH、SGBM、3WAY)int algorithm = STEREO_SGBM;if (algorithm == STEREO_HH)sgbm->setMode(StereoSGBM::MODE_HH);else if (algorithm == STEREO_SGBM)sgbm->setMode(StereoSGBM::MODE_SGBM);else if (algorithm == STEREO_3WAY)sgbm->setMode(StereoSGBM::MODE_SGBM_3WAY);Mat imgDisparity16S = Mat(Img_L.rows, Img_L.cols, CV_16S);sgbm->compute(Img_L, Img_R, imgDisparity16S);//--Display it as a CV_8UC1 image:16位有符號轉為8位無符號imgDisparity16S.convertTo(imgDisparity8U, CV_8U, 255 / (numberOfDisparities*16.));}調用示例:#include"SGBM_Algorithm.h"int main(){Mat Img_L = imread("Teddy_L.png", 0);Mat Img_R = imread("Teddy_R.png", 0);Mat Disparity8U = Mat(Img_L.rows, Img_R.cols, CV_8UC1);//創(chuàng)建一個Disparity圖像calDispWithSGBM(Img_L, Img_R, Disparity8U);imshow("Teddy_L", Img_L);imshow("Teddy_R", Img_R);imshow("Disparity", Disparity8U);waitKey();system("pause"); //按任意鍵退出return 0;}





三.雙目立體視覺的發(fā)展現(xiàn)狀
四.筆者總結
推薦閱讀
雙目圖像超分辨:現(xiàn)狀、挑戰(zhàn)與展望
NeurIPS2019|首篇單目無監(jiān)督深度估計與視覺里程計,效果超越雙目算法,已開源
極市干貨|第50期直播回放-邊佳旺:NeurIPS2019_無監(jiān)督且尺度一致的深度估計與視覺SLAM

