1. 程式人生 > 其它 >halcon面陣相機標定矯正

halcon面陣相機標定矯正

技術標籤:機器視覺

使用標定助手標定過程很簡單就不贅述了,可以自行查詢,無非就是生成描述檔案=>填寫相機像元引數,鏡頭引數,標定板引數=>拍照=>標定即可

例如標定後得到的引數為
相機內參 => CameraParameters := [0.0130131,-2255.9,2.00077e-006,2e-006,1263.13,1031.32,2592,1944]
相機外參 => CameraPose := [-0.0111166,-0.00766521,0.117412,0.570424,359.157,82.3899,0]

相機內參如果深究起來需要理解矩陣的一些知識,網路上也有很多大神詳細的講解如何根據標定影象來求解內參,歸根結底目的是矯正徑向畸變也就是所謂的桶形畸變和枕形畸變,簡單理解就是讓實際物體的直線在影象上看來仍然是一條直線而不是曲線。對於這個相機外參一直不是很理解,網路上無非說是相機位姿,但是做什麼用的不是很懂,還有為什麼標定的時候需要選擇一個參考位姿的圖片呢?帶著這個疑問查詢了很多資料,終於搞明白了一些。

首先相機標定存在三個座標系分別是 世界座標,相機座標,影象座標。世界座標就是真實世界中的物理座標可以自定義比如我們定義標定板的正中心的黑色圓點的圓心作為原點,垂直標定板向上為z軸建立笛卡爾座標系O-xyz單位可以設為mm。相機座標系其實是以鏡頭中心為原點,光路為z軸的一個笛卡爾座標系O1-x1y1z1。這兩個座標系之間的變換是一種剛體變換,也就是說保持三個座標軸的直角關係不變通過在三維空間中的旋轉,平移即可使得兩個座標軸完全重合到一起,那麼世界座標系分別繞著xyz軸旋轉多少度,然後原點再沿xyz軸平移多少mm兩個座標系就可以重合了呢,這就是我們標定得到的相機外參來描述的比如上面的外參為CameraPose := [-0.0111166,-0.00766521,0.117412,0.570424,359.157,82.3899,0],前三個引數就是表示以世界座標系為參考沿x軸平移-0.0111166m,沿y軸平移-0.00766521m,沿z軸平移0.117412m這兩個座標系的原點即可重合,注意單位是m(米)

。然後再分別繞xyz軸旋轉0.570424度,359.157度,82.3899度兩個座標系的xyz軸即可重合。這就是相機外參的意義所在,為什麼叫位姿,其實就是描述相機相對於標定板的拍攝姿態是怎麼樣的,是從哪個角度來拍攝標定板影象的,只有知道這個引數才能將拍攝的標定板影象轉換成z=0的視角影象(也就是xOy平面,理想的垂直標定板拍攝角度)。在標定助手裡面可以設定不同標定板影象為參考位姿,標定出來的相機外參是不同的,這也不難理解,因為使用不同的標定板作為參考位姿如果想講這個標定板影象轉換成z=0的視角拍攝的影象相機需要調整的角度是不同的。

得到相機內外引數後如果需要測量需要將原始圖片通過內外引數對映才能進行測量真實長度。

左側影象是標定的時候通過標定助手選擇的作為參考位姿的標定板影象,右側是這幅影象轉換成相機從正上方垂直拍攝的無畸變的理想影象,程式碼如下所示

*相機標定得到的相機內參和外參
CameraParameters := [0.0130131,-2255.9,2.00077e-006,2e-006,1263.13,1031.32,2592,1944]
CameraPose := [-0.0111166,-0.00766521,0.117412,0.570424,359.157,82.3899,0]
*讀取作為參考位姿的標定板影象
read_image (Image, 'F:/Desktop/halcontest/Images/20210121-220543-844.bmp')
*這裡為什麼是40,其實這裡40表示的是40mm,後面除以1000是換算成0.040m
realViewWidth := 40
*將mm單位換算成m為單位,表示我想轉換後的圖片顯示0.039m寬的視野
realViewWidth := realViewWidth / 1000.0 
*這裡是重新設定相機位姿,表示將相機的拍攝角度沿原點沿xyz分別平移多少m,可以將轉換後的影象平移到視野中心,注意這裡實際可以理解為移動的是相機而不是標定板
*這也解釋了為什麼上圖往中心移動是負數而不是正數,標定板邊框處的小三角是在OXY平面的第三象限處,原點O是在標定板正中心位置
set_origin_pose (CameraPose, -0.5*realViewWidth, -0.4*realViewWidth, 0, newCameraPose)
*生成對映圖,將畫素為單位的影象轉換成實際長度單位。這裡需要著重說一下這幾個引數
*MapImage[out]:輸出得到的對映圖
*CameraParameters[in]:標定得到的相機內參
*newCameraPose[in]:在標定得到的相機外參基礎上重新調整得到新的相機外參
*2592[in]:輸入畫素為單位的影象寬度
*1944[in]:輸入畫素為單位的影象高度
*2592[in]:輸出影象的畫素寬度
*1944[in]:輸出影象的畫素高度
*realViewWidth / 2592[in]:非常重要的引數,表示轉換後的影象每個畫素代表真實的物理距離,單位為m。輸出影象的寬度高度和每個
*畫素代表的實際長度決定了對映後的影象標定板在影象中的大小。因為如果同為2592*1944大小的影象,標定板所佔比例大小在每個畫素代表0.001m的影象中肯定要大於每個畫素代表0.002m
*的影象比例。如果長為0.002m的直尺在比例為0.001m的影象中佔2個畫素,但是在比例為0.002m的影象中只佔1個畫素。
gen_image_to_world_plane_map (MapImage, CameraParameters, newCameraPose, 2592, 1944, 2592, 1944, realViewWidth / 2592, 'bilinear')
* Calibration 01: Now, images can be rectified using the rectification map
map_image (Image, MapImage, RealWordImage)