雙目測距的基本原理

2021-06-21 22:50:20 字數 3435 閱讀 7572

雙目測距的基本原理

如上圖所示,雙目測距主要是利用了目標點在左右兩幅檢視上成像的橫向座標直接存在的差異(即視差在opencv中,f的量綱是畫素點,t的量綱由定標板棋盤格的實際尺寸和使用者輸入值確定,一般是以公釐為單位(當然為了精度提高也可以設定為0.1公釐量級),d=xl-xr的量綱也是畫素點。因此分子分母約去,z的量綱與t相同。

假設目標點在左檢視中的座標為(x,y),在左右檢視上形成的視差為d,目標點在以左攝像頭光心為原點的世界座標系中的座標為(x,y,z),則存在上圖所示的變換矩陣q,使得 q*[x y d 1]』 = [x y z w]』。

「@scyscyao :為了精確地求得某個點在三維空間裡的距離z,我們需要獲得的引數有焦距f、視差d、攝像頭中心距tx。如果還需要獲得x座標和y座標的話,那麼還需要額外知道左右像平面的座標系與立體座標系中原點的偏移cx和cy。其中f, tx, cx和cy可以通過立體標定獲得初始值,並通過立體校準優化,使得兩個攝像頭在數學上完全平行放置,並且左右攝像頭的cx, cy和f相同(也就是實現圖2中左右檢視完全平行對準的理想形式)。而立體匹配所做的工作,就是在之前的基礎上,求取最後乙個變數:視差d(這個d一般需要達到亞畫素精度)。從而最終完成求乙個點三維座標所需要的準備工作。在清楚了上述原理之後,我們也就知道了,所有的這幾步:標定、校準和匹配,都是圍繞著如何更精確地獲得f, d, tx, cx 和cy而設計的 。

二、攝像頭定標

攝像頭定標一般都需要乙個放在攝像頭前的特製的標定參照物(棋盤紙),攝像頭獲取該物體的影象,並由此計算攝像頭的內外引數。標定參照物上的每乙個特徵點相對於世界座標系的位置在製作時應精確測定,世界座標系可選為參照物的物體座標系。在得到這些已知點在影象上的投影位置後,可計算出攝像頭的內外引數。

如上圖所示,攝像頭由於光學透鏡的特性使得成像存在著徑向畸變,可由三個引數k1,k2,k3確定;由於裝配方面的誤差,感測器與光學鏡頭之間並非完全平行,因此成像存在切向畸變,可由兩個引數p1,p2確定。單個攝像頭的定標主要是計算出攝像頭的內參(焦距f和成像原點cx,cy、五個畸變引數(一般只需要計算出k1,k2,p1,p2,對於魚眼鏡頭等徑向畸變特別大的才需要計算k3))以及外參(標定物的世界座標)。 opencv

中使用的求解焦距和成像原點的演算法是基於張正友的方法(

pdf),而求解畸變引數是基於

brown

的方法(

pdf)。

1. 影象座標系、攝像頭座標系和世界座標系的關係

攝像頭成像幾何關係,其中oc 點稱為攝像頭(透鏡)的光心,xc 軸和yc 軸與影象的x軸和y軸平行,zc 軸為攝像頭的光軸,它與影象平面垂直。光軸與影象平面的交點o1 ,即為影象座標系的原點。由點oc 與xc 、yc 、zc 軸組成的座標系稱為攝像頭座標系,oc o1 的距離為攝像頭焦距,用f表示。

影象座標系是乙個二維平面,又稱為像平面,「@scyscyao :實際上就是攝像頭的ccd感測器的表面。每個ccd感測器都有一定的尺寸,也有一定的解析度,這個就確定了公釐與畫素點之間的轉換關係。舉個例子,ccd的尺寸是8mm x 6mm,幀畫面的解析度設定為640x480,那麼公釐與畫素點之間的轉換關係就是80pixel/mm。」設ccd感測器每個畫素點的物理大小為dx*dy,相應地,就有 dx=dy=1/80。(他咋算的???)

2. 進行攝像頭定標時,棋盤方格的實際大小 square_size (預設為 1.0f )的設定對定標引數是否有影響?

「@scyscyao :當然有。在標定時,需要指定乙個棋盤方格的長度,這個長度(一般以公釐為單位,如果需要更精確可以設為0.1公釐量級)與實際長度相同,標 定得出的結果才能用於實際距離測量。一般如果尺寸設定準確的話,通過立體標定得出的translation向量的第乙個分量tx的絕對值就是左右攝像頭的中心距。一般可以用這個來驗證立體標定的準確度。比如我設定的棋盤格大小為270 (27mm),最終得出的tx大小就是602.8 (60.28mm),相當精確。」

3. 定標所得的攝像頭內引數,即焦距和原點座標,其數值單位都是一致的嗎?怎麼把焦距數值換算為實際的物理量?

「@wobject :是的,都是以畫素為單位。假設畫素點的大小為k x l,單位為mm,則fx = f / k, fy = f / (l * sina), a一般假設為 90°,是指攝像頭座標系的偏斜度(就是鏡頭座標和ccd是否垂直)。攝像頭矩陣(內參)的目的是把影象的點從影象座標轉換成實際物理的三維座標。因此其中的fx, fy, cx, cy 都是使用類似上面的綱量。同樣,q 中的變數 f,cx, cy 也應該是一樣的。」

4. 棋盤影象數目應該取多少對攝像頭定標比較適宜?

opencv中文論壇上piao的帖子《在opencv中用cvcalibratecamera2進行相機標定(附程式) 》中指出影響攝像頭定標結果的準確性和穩定性的因素主要有三個:

(1) 標定板所在平面與成像平面(image plane)之間的夾角;

(2) 標定時拍攝的數目(棋盤影象數目);

(3) 影象上角點提取的不準確。

感覺opencv1.2以後對影象角點的提取準確度是比較高的,cvfindchessboardcorners 和 cvfindcornersubpix結合可以獲得很好的角點檢測效果(hqhuang1在《[hq]角點檢測(corner detection) cvfindcornersubpix 使用範例 》中給出了相關的應用範例)。因此,影響定標結果較大的就是標定板與鏡頭的夾角和棋盤影象數目,在實際定標過程中,我感覺棋盤影象數目應該大於20張,每成功檢測一次完整的棋盤角點就要變換一下標定板的姿態(包括角度、距離)

5. 單目定標函式cvcalibratecamera2採用怎樣的 flags 比較合適?

由於一般鏡頭只需要計算k1,k2,p1,p2四個引數,所以我們首先要設定 cv_calib_fix_k3;其次,如果所用的攝像頭不是高階的、切向畸變係數非常少的,則不要設定 cv_calib_zero_tangent_dist,否則單目校正誤差會很大;如果事先知道攝像頭內參的大概數值,並且cvcalibratecamera2函式的第五個引數intrinsic_matrix非空,則也可設定 cv_calib_use_intrinsic_guess ,以輸入的intrinsic_matrix為初始估計值來加快內參的計算;其它的 flag 一般都不需要設定,對單目定標的影響不大。

p.s. 使用opencv進行攝像機定標雖然方便,但是定標結果往往不夠準確和穩定,最好是使用 matlab標定工具箱 來進行定標,再將定標結果取回來用於立體匹配和視差計算。工具箱的使用官方主頁 有**並茂的詳細說明,此外,有兩篇博文也進行了不錯的總結,推薦閱讀:

(1)分享一些opencv實現立體視覺的經驗

(2)matlab標定工具箱使用的一些注意事項

雙目測距測深度 科普 雙目測距原理

參考資料 1 深度相機原理揭秘 雙目立體視覺 2 雙目測距原理 3 相機標定原理及實現 1 雙目測距基本原理 如圖所示,p點是待測物體,camera r和camera l代表相機的光心位置,兩綠點為點p在兩個相機感光器上的成像點,f為相機焦距,b為兩相機中心距,z為所求深度資訊,兩綠點間距為d。d ...

雙目測距的實現

說到雙攝像頭測距,首先要複習一下測距原理,把learning opencv翻到416和418頁,可以看到下面兩幅圖 圖1.雙攝像頭模型俯檢視 圖2,雙攝像頭模型立體檢視 圖1解釋了雙攝像頭測距的原理,書中z的公式如下 在opencv中,f的量綱是畫素點,tx的量綱由定標棋盤格的實際尺寸和使用者輸入值...

雙目測距原理 兩公式區別

我在學習上述兩個部落格時發現,兩者對於雙目視覺深度值計算公式的推導過程有些細微的出入。如圖1所示,其中xl與xr,分別為左右相機像平面上的成像點距主點的距離 x方向 可以理解為x1與xr,是在相機座標系測得的。如圖2所示,其中xr與xt分別為左右相機像平面上的成像點距像平面左邊緣的距離,可以理解為x...