關(guān)于雙目立體視覺的三大基本算法及發(fā)展現(xiàn)狀的總結(jié)
點(diǎn)擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時間送達(dá)
雙目立體視覺一直是機(jī)器視覺研究領(lǐng)域的發(fā)展熱點(diǎn)和難點(diǎn),“熱”是因為雙目立體視覺有著及其廣闊的應(yīng)用前景,且隨著光學(xué)、計算機(jī)科學(xué)等學(xué)科的不斷發(fā)展,雙目立體技術(shù)將不斷進(jìn)步直到應(yīng)用到人類生活的方方面面。“難”則是因為受到攝像機(jī)、鏡頭等硬件設(shè)備及一些相關(guān)算法的限制,雙目立體視覺的研究及如何更好的應(yīng)用到生產(chǎn)實(shí)際中仍有待在座的各位去進(jìn)行突破。
一.簡介
雙目立體視覺是機(jī)器視覺中的一個重要分支,自上世紀(jì)60年代中期開創(chuàng)以來,經(jīng)過幾十年的發(fā)展,如今在機(jī)器人視覺、航空測繪、軍事應(yīng)及醫(yī)學(xué)成像、工業(yè)檢測上應(yīng)用極其廣泛。雙目立體視覺基于視差原理并利用成像設(shè)備從不同的位置獲取被測物體的左右兩幅圖像,然后根據(jù)三角測量原理計算空間點(diǎn)在二維圖像的位置偏差,最后再利用位置偏差進(jìn)行三維重建來獲取被測物體的三維幾何信息(本文不對雙目立體視覺的數(shù)學(xué)原理進(jìn)行詳細(xì)介紹)。
二.雙目立體視覺的三大基本算法的原理及其代碼實(shí)現(xiàn)(基于opencv)
雙目立體視覺中常用的基于區(qū)域的局部匹配準(zhǔn)則主要有圖像序列中對應(yīng)像素差的絕對值之和SAD(sum of absolute differences)、對應(yīng)像素差的平方之和SSD(sum of squared differences)及半全局匹配算法SGM(semi—global matching)。
2.1 SAD(sum of absolute differences)的原理
匹配算法SAD的基本思想是對經(jīng)行對準(zhǔn)后的左右視圖圖像的對應(yīng)像素塊的對應(yīng)像素差的絕對值進(jìn)行求和。
其數(shù)學(xué)公式如下:

###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; //顯示處理進(jìn)度}return Disparity;}調(diào)用示例:#int main(int argc, char* argv[]){Mat Img_L = imread("Teddy_L.png", 0); //此處調(diào)用的圖像已放入項目文件夾中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最小視差默認(rèn)為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); //預(yù)處理濾波器的截斷值,預(yù)處理的輸出值僅保留//[-preFilterCap, preFilterCap]范圍內(nèi)的值,參數(shù)范圍:1 - 31sgbm->setUniquenessRatio(10); //視差唯一性百分比:視差窗口范圍內(nèi)最低代價是次低代價的(1 + uniquenessRatio/100)倍時//最低代價對應(yīng)的視差值才是該像素點(diǎn)的視差,否則該像素點(diǎn)的視差為 0 ,不能為負(fù)值,一般去5——15sgbm->setSpeckleWindowSize(100); //視差連通區(qū)域像素點(diǎn)個數(shù)的大小:對于每一個視差點(diǎn),當(dāng)其連通區(qū)域的像素點(diǎn)個數(shù)小于//speckleWindowSize時,認(rèn)為該視差值無效,是噪點(diǎn)。sgbm->setSpeckleRange(32); //視差連通條件:在計算一個視差點(diǎn)的連通區(qū)域時,當(dāng)下一個像素點(diǎn)視差變化絕對值大于//speckleRange就認(rèn)為下一個視差像素點(diǎn)和當(dāng)前視差像素點(diǎn)是不連通的。sgbm->setMode(0); //模式選擇sgbm->setBlockSize(sgbmWinSize); //設(shè)置SAD代價計算窗口,一般在3*3到21*21之間//blockSize(SADWindowSize) 越小,也就是匹配代價計算的窗口越小,視差圖噪聲越大;//blockSize越大,視差圖越平滑;//太大的size容易導(dǎo)致過平滑,并且誤匹配增多,體現(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位有符號轉(zhuǎn)為8位無符號imgDisparity16S.convertTo(imgDisparity8U, CV_8U, 255 / (numberOfDisparities*16.));}調(diào)用示例:#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)狀
四.筆者總結(jié)
交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~

