作者:Kaustubh Sadekar Satya Mallick
翻譯:陳之炎
校對:王可汗
本文約3200字,建議閱讀5分鐘
本文為大家系統地介紹了使用OpenCV實現攝像頭标定。
攝像頭是一種視覺傳感器,它已經成為了機器人技術、監控、空間探索、社交媒體、工業自動化,甚至娛樂業等多個領域不可分割的組成部分。
在攝像頭的多種應用中,了解攝像頭的參數對于視覺傳感器的有效使用至關重要。
在本文中,将闡述攝像頭标定所涉及的步驟及其含義。
此外,文中還共享了棋盤格模式示例圖像的C 和Python代碼。
什麼是攝像頭标定?對攝像頭參數進行估計的過程稱為攝像頭标定。
通過攝像頭标定,可以掌握攝像頭的所有信息(參數或系數),從而可以确定現實世界中的三維點與攝像頭捕獲圖像的二維投影(像素)之間的精确關系。
通常,攝像頭标定意味着恢複以下兩類參數:
1. 攝像頭 /鏡頭系統的固有參數。如:鏡頭的焦距、光心和徑向失真系數等參數。
2. 外部參數:這是指攝像頭相對于某個世界坐标系的方向(旋轉矩陣R和平移向量t)。
在下圖中,采用了幾何标定來估計透鏡的參數,從而消除圖像的失真。
對失真圖像采用幾何标定之後的效果
使用OpenCV實現攝像頭标定為了更好地理解整個标定過程,首先需要了解成像的幾何特征。點擊下面的鍊接來查看詳細的解釋。
成像的幾何特征
正如前文所述,為了找出一個三維點在圖像平面上的投影,首先需要使用外部參數(旋轉矩陣R和平移向量t)将該點從世界坐标系轉換到攝像頭坐标系。
接下來,利用攝像頭的固有參數,将該點投影到圖像平面上。
将世界坐标中的三維點(Xw, YW,Zw)投影到圖像坐标 (u、v)的關聯方程如下所示:
其中,P是一個由兩部分組成的3×4投影矩陣——包含固有參數的固有矩陣(K)、由3×3旋轉矩陣R和3×1平移向量t組合而成的外部矩陣([R|t])。
如前文所述,固有矩陣是上三角矩陣
其中
fx,fy是x和y的焦距(通常二者是相同的)。
cx,cy是圖像平面上光心的x、 y坐标,這一坐标通常用圖像的中心來近似。
γ是各軸之間的斜度,通常為0。
攝像頭标定的目的攝像頭标定的目的是:利用一組已知的3D點坐标(Xw, YW,Zw)及其相應的圖像坐标(u、v)來找出3×3矩陣K、3×3旋轉矩陣R和3×1平移向量t。當得出固有參數和外部參數的值之後,便實現了攝像頭标定。
總之,攝像頭标定算法應具備以下輸入和輸出:
1. 輸入:已知二維圖像坐标和三維世界坐标點的圖像集合。
2. 輸出:3×3攝像頭固有矩陣,每幅圖像的旋轉矩陣和平移向量。
注:在OpenCV中,攝像頭固有矩陣沒有傾斜參數,所以該矩陣的形式為
多種類型的攝像頭标定方法
有以下幾種攝像頭标定方法:
1. 模式标定:當能完全控制成像過程時,執行标定的最佳方法是從不同的角度捕捉一個物體或已知維度模式的多幅圖像。本文中涉及到的基于棋盤格的方法屬于這種标定。也可以使用已知尺寸的圓形模式來替代棋盤格模式。
2. 幾何線索:有時場景中有如直線和消失點等其他的幾何線索,可以利用于這些幾何線索來進行标定。
3. 基于深度學習的标定:當對成像設置的控制很少時(例如:當隻有一個場景的單一圖像),可使用基于深度學習的方法獲得攝像頭的标定信息。
攝像頭标定的步驟标定過程的步驟可用下圖中的流程圖來解釋。
下面,來看看這些步驟是如何實現的:
第1步:用棋盤格模式定義真實世界的坐标
世界坐标系:世界坐标系由附在房間裡一面牆上的棋盤格圖案來固定,三維點是棋盤格中正方形的拐角。上述棋盤格中的任何一個角都可以定為世界坐标系的原點。XW軸和YW軸沿牆移動,ZW軸垂直于牆移動。因此,棋盤格上的所有點都在XY平面上(即ZW=0)。
在标定過程中,通過一組已知的三維點(Xw, YW,Zw)及其在圖像中相應的像素位置(u,v)來計算出攝像頭的參數。
對于3D點,可以在許多不同的方向上拍攝一個已知尺寸的棋盤格圖案。将世界坐标映射到棋盤格上,由于所有的角點都在一個平面上,可以任意選取ZW為0。由于各點在棋盤格中是等間隔的,可以将其中一個點設為參考點(0,0),這樣,便很容易定義出每個三維點的坐标(XW,YW)。
為什麼棋盤格圖案在攝像頭标定中應用如此之廣?棋盤格圖案的獨特之處是:在圖像檢測過程中,它很容易檢測到。不僅如此,棋盤格上的正方形是定位的理想選擇,因為它們在兩個方向的梯度比較尖銳。此外,這些方格與它們在棋盤線的交叉點有關。所有這些特點,都有利于方便地定位出正方形的拐角。
繪制出檢測到的棋盤闆拐角坐标後的結果圖
第2步:從多個不同的角度捕捉多個棋盤格圖像
上述圖像用于标定攝像頭。
接下來,确保棋盤格為靜态,并通過移動攝像頭拍攝出多幅棋盤圖像。
或者,也可以保持攝像頭不動,拍攝不同方向的棋盤格圖案,從數學的角度來看,這兩種情況很類似。
第3步:找出棋盤格闆的二維坐标有了多幅棋盤格圖像之後,世界坐标系上棋盤格上點的三維位置也已知,最後,需要找出的是圖像在棋盤格上二維像素的位置。
3.1找出棋盤格的角OpenCV提供了一個名為findChessboardCorners的内置函數,利用這個函數可以找出棋盤格中各個角的坐标。下面,來看看這一代碼的用法:
C
Python
其中:
根據是否檢測到一個棋盤格模式,輸出為真或假。
3.2調整棋盤格的角良好的标定應完全滿足精度的要求。為了獲得良好的結果,應對各個角的位置進行調整,以獲得亞像素級的精度。
OpenCV有一個 cornerSubPix函數,利用這個函數獲取原始圖像和棋盤格角的位置,并在原始位置的小範圍内找出最佳的位置角度。該算法的本質是一個叠代過程,為此需要指定終止條件(如,叠代次數和/或精度)
C
Python
其中
第4步:标定攝像頭
攝像頭标定的最後一步是:将世界坐标中的三維點及其在所有圖像的二維位置傳遞給OpenCV的calibrateCamera 方法。這是基于張正友的一篇論文。數學上有點複雜,需要線性代數的背景知識。
來看看calibrateCamera方法的語法
C
Python
其中
攝像頭标定源代碼
攝像頭标定的Python和C 代碼如下。利用下面的鍊接,下載所有的圖像和代碼則更為簡單。
攝像頭标定的Python代碼
請仔細閱讀代碼的注釋,它們對每一步都在做什麼作了詳細解釋。
C 源代碼
請通讀每一條注釋,以了解每一步都實現了什麼。
,
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!