雙目立體視覺的第二部分,視差圖計算算法。
大家好!歡迎來到立體視覺深度第二部分。我將簡要解釋塊匹配算法。我假設(shè)您已經(jīng)閱讀了前一篇文章,如果你還沒有讀過,去讀一下。
在第一篇文章中,我們分別拍攝了左右兩幅圖像,并對相機(jī)進(jìn)行了校準(zhǔn)。校準(zhǔn)過程之后,我們有了立體圖像,兩張圖像中相同的點在同一條線上,這意味著如果這一對圖片種有一支筆,筆上的對應(yīng)的點應(yīng)該分別是(X1, Y)和(X2, Y),Y是行號,X1和X2的圖像的列號。
校正過的圖像顯示相同的P點。
在本例中,X1和x2之間的差異為我們提供了視差值。我們已經(jīng)提到過,如果我們用左眼閉著看一個近距離的物體,反之亦然,位置根據(jù)睜眼的角度而變化。當(dāng)物體距離越遠(yuǎn),這種差別就越明顯。這意味著如果視差值越小,物體越近。每個點都可以做這個操作,但是效率不高,因為:
這是一個很慢的過程。時間是寶貴的。
如果校正的不夠好,每個點都不理想。
我們需要減少誤差,在這種情況下,逐點處理不會有幫助。
這就是我們使用塊匹配的原因。其中一些是使用光流(圖像流),或減少圖像大小,以使用更少的處理能力。第二點我簡單提一下,如果你想了解更詳細(xì)的信息,請查閱相關(guān)論文。
我們從左邊的圖像開始。使用左圖不是強(qiáng)制的,我就是這么用的。太大的塊會產(chǎn)生平滑的圖像,太小的塊會產(chǎn)生噪聲。你都應(yīng)該嘗試一下,找到最佳值。在選擇最左邊的塊之后,我們從左到右搜索,并嘗試盡可能多地與右邊的圖像匹配。由于圖像被校正過了,在一個軸上搜索就足夠了。
黑塊是我們的待搜索塊
在一個軸上搜索,從左到右搜索
如何進(jìn)行塊匹配?有很多公式。大多數(shù)人用的是絕對差的和以及差的平方和。你可以研究一下相關(guān)的論文以及人們是如何使用它的。在這些方法中,較小的結(jié)果意味著非常相似。這將是我們選擇的塊的差異值。
絕對差和的例子
左校正后的圖像,右校正后圖像,塊匹配后的視差圖。
既然我們已經(jīng)介紹了基礎(chǔ)知識,讓我們查看一下代碼。在塊匹配之后,我使用了WLS(加權(quán)最小二乘)濾波器來獲得更平滑和更接近的視差值,可以更好地代表圖像。函數(shù)為:
defdepth_map(imgL,imgR): """Depthmapcalculation.WorkswithSGBMandWLS.Needrectifiedimages,returnsdepthmap(lefttorightdisparity)""" #SGBMParameters----------------- window_size=3#wsizedefault3;5;7forSGBMreducedsizeimage;15forSGBMfullsizeimage(1300pxandabove);5Worksnicely left_matcher=cv2.StereoSGBM_create( minDisparity=-1, numDisparities=5*16,#max_disphastobedividableby16f.E.HH192,256 blockSize=window_size, P1=8*3*window_size, #wsizedefault3;5;7forSGBMreducedsizeimage;15forSGBMfullsizeimage(1300pxandabove);5Worksnicely P2=32*3*window_size, disp12MaxDiff=12, uniquenessRatio=10, speckleWindowSize=50, speckleRange=32, preFilterCap=63, mode=cv2.STEREO_SGBM_MODE_SGBM_3WAY ) right_matcher=cv2.ximgproc.createRightMatcher(left_matcher) #FILTERParameters lmbda=80000 sigma=1.3 visual_multiplier=6 wls_filter=cv2.ximgproc.createDisparityWLSFilter(matcher_left=left_matcher) wls_filter.setLambda(lmbda) wls_filter.setSigmaColor(sigma) displ=left_matcher.compute(imgL,imgR)#.astype(np.float32)/16 dispr=right_matcher.compute(imgR,imgL)#.astype(np.float32)/16 displ=np.int16(displ) dispr=np.int16(dispr) filteredImg=wls_filter.filter(displ,imgL,None,dispr)#importanttoput"imgL"here!!! filteredImg=cv2.normalize(src=filteredImg,dst=filteredImg,beta=0,alpha=255,norm_type=cv2.NORM_MINMAX); filteredImg=np.uint8(filteredImg) returnfilteredImg
你可以再這里:https://github.com/aliyasineser/stereoDepth檢查項目。代碼基本上就是在創(chuàng)建匹配器。OpenCV的文檔很差(我添加了一些,但這只是冰山一角),但編碼方面真的很容易。讓我們來看看參數(shù):
minDisparity: 最小視差值。通常我們期望這里是0,但當(dāng)校正算法移動圖像時,有時需要設(shè)置。
numDisparities: 最大視差值,必須大于0,定義視差邊界。
blockSize: 匹配塊的塊大小。推薦使用[3-11],推薦使用奇數(shù),因為奇數(shù)大小的塊有一個中心。
P1 和 P2: 負(fù)責(zé)平滑圖像,規(guī)則是P2>P1。
disp12MaxDiff: 視差計算的最大像素差。
preFilterCap:過濾前使用的值。在塊匹配之前,計算圖像x軸的一個導(dǎo)數(shù),并用于檢查邊界[-prefiltercap, prefiltercap]。其余的值用Birchfield-Tomasi代價函數(shù)處理。
uniquenessRatio: 經(jīng)過成本函數(shù)計算,此值用于比較。建議取值范圍[5-15]。
speckleWindowSize: 過濾刪除大的值,得到一個更平滑的圖像。建議取值范圍[50-200]。
speckleRange: 使用領(lǐng)域檢查視差得到一個平滑的圖像。如果你決定嘗試,我建議1或2。小心,這個值會乘以16!OpenCV會這樣做,所以你不需要自己去乘。
在代碼中我們使用了SGBM。創(chuàng)建左右視差圖,使用WLS濾波平滑優(yōu)化圖像。我還沒有掌握這個,我用數(shù)值做了實驗,所以我就不詳細(xì)講了。
代碼:https://github.com/aliyasineser/stereoDepth可用于單目和立體攝像機(jī)標(biāo)定,以及視差圖計算。之后,你可以對結(jié)果做任何你想做的事。在我的項目中,我用它來檢測前方是否有物體或距離太近,都是關(guān)于無人機(jī)的。你可以用你的想象力創(chuàng)造很多東西。
編輯:黃飛
-
雙目立體視覺
+關(guān)注
關(guān)注
0文章
17瀏覽量
8580
原文標(biāo)題:雙目立體視覺 II:塊匹配視差圖計算
文章出處:【微信號:vision263com,微信公眾號:新機(jī)器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論