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