Halcon單相機標定
一、理論
為什麼要進行單相機標定?
廣義:畸變矯正和一維和二維測量
畸變矯正:
在幾何光學和陰極射線管(CRT)顯示中。畸變是對直線投影的一種偏移。簡單來說直線投影是場景內的一條直線投影到圖片上也保持為一條直線。那畸變簡單來說就是一條直線投影到圖片上不能保持為一條直線了。這是一種光學畸變(optical aberration)。畸變是一種相差,可能由於攝像機鏡頭導致,會對拍攝的物體的形狀產生變化,影響測量。
我自己對畸變矯正的理解就是,當相機進行標定時,雖然標定板也產生了畸變,但是標定板(圓形)的準確資料我們已經告訴了halcon,比如,圓的排列方式、直徑、中心距等。通過載入多張標定板圖片,halcon可以通過函式求出鏡頭裡發生畸變的標定板與未發生畸變的標定板之間的對映關係,也就是相機本身的內參(拍攝有畸變)和矯正之後無畸變內參之間的對映關係,將這種對映關係作用到拍攝時發生畸變的物體當中,就完成了畸變校正.。
步驟:
1)通過標定求出相機內參。
2)通過有畸變的內參求出無畸變的內參。用chage_radial_distortion_cam_par()函式完成。
3)求出有畸變的內參和無畸變的內參之間的對映關係。用
gen_radial_distortion_map()函式
4)將上邊的對映關係作用到產生畸變的物體當中,完成畸變校正一維和二維的測量
一維和二維的測量:
圖片上的尺寸是畫素距離,標定後,可以求出畫素距離與物理空間距離的換算關係,從而計算出實際的物理尺寸。
狹義:求解相機的內參和外參以及畸變引數,得到二維平面畫素座標和三維世界座標的關係,從而進行三維重建。
相機內參:相機的固有屬性,在進行畸變校正時需要用到相機的內參。相機外參:物體在經過透鏡成像之後,實際上是經過了旋轉和平移,而外參就是告訴我們物體成像後經過了那種旋轉和平移,相機的外參包括平移向量和旋轉矩陣。畸變引數:採用理想針孔模型,由於通過針孔的光線少,攝像機曝光太慢,在實際使用中均採用透鏡,可以使影像生成迅速,但代價是引入了畸變。有兩種畸變對投影影像影響較大: 徑向畸變和切向畸變。
相機的畸變和內參是相機本身的固有特性,標定一次即可一直使用。但由於相機本身並非理想的小孔成像模型以及計算誤差,採用不同的圖片進行標定時得到的結果都有差異。一般重投影誤差很小的話,標定結果均可用。
為什麼要求解相機的內參和外參?
首先,我們需要知道四個座標系,即影像畫素座標系 (u,v)、影像物理座標系(x,y)、相機座標系(Xc,Yc,Zc)和 世界座標系(Xw,Yw,Zw)(標定板所在的座標系)。
一、畫素座標系(u,v)與CCD的影像物理座標系(x,y)的關係:
畫素座標系不利於座標變換,因此需要建立影像座標系XOY,其座標軸的單位通常為毫米(mm),原點是相機光軸與相面的交點(稱為主點),即影像的中心點。X軸、Y軸分別與u軸、v軸平行。故兩個座標系實際是平移關係,即可以通過平移就可得到。
兩座標軸互相垂直
此時有:
其中,dX、dY分別為畫素在X、Y軸方向上的物理尺寸,u0,v0為主點(影像原點)座標。
這裡引用了齊次矩陣(就是將一個原本是2維的x,y向量用一個3維向量(加個1)來表示),引入齊次矩陣的目的主要是合併矩陣運算中的乘法和加法,表示為x=P*X的形式。即它提供了用矩陣運算把二維、三維甚至高維空間中的一個點集從一個座標系變換到另一個座標系的有效方法
兩座標軸不互相垂直
此時有
寫成矩陣形式:
二、相機座標系(Xc,Yc,Zc)與影像座標系(x,y)的關係:
根據小孔成像原理:
如圖,空間任意一點P與其影像點p之間的關係,P與相機光心o的連線為oP,oP與像面的交點p即為空間點P在影像平面上的投影。
該過程為透視投影,根據三角形相似性原理得如下矩陣:
其中,s為比例因子(s不為0),f為有效焦距(光心到影像平面的距離),(x,y,z,1)T是空間點P在相機座標系oxyz中的齊次座標,(X,Y,1)T是像點pp在影像座標系OXY中的齊次座標。
三、世界座標系(Xw,Yw,Zw)至相機座標系(Xc,Yc,Zc)
其中:R為3* 3的旋轉矩陣,T為3*1的平移矩陣,(xc,yc,zc,1)T為相機座標系的齊次座標,(xw,yw,zw,1)T為世界座標系的齊次座標。
四、世界座標系轉化為畫素座標系
其中,M1稱為相機的內部引數矩陣,完全由相機的內部引數ax,ay,uo,vo決定,(uo,vo)為主點座標,ax,ay分別表示影像u軸和v軸的尺度因子;M2完全由攝像機相對於世界座標系的方位決定,稱為攝像機的外部引數;Xw為空間點在世界座標系下的齊次座標;M為一個34的矩陣,稱為投影矩陣。
總結:其實說白了,我們需要找到世界座標系和畫素座標系之間的關係,而兩者的關係可以通過將世界座標系轉化為相機座標系,相機座標系通過投影變換轉化為CCD的影像物理座標系,在通過變換可以把影像物理座標系的物理單位轉化為影像畫素座標系的畫素單位[即(x,y)→(u,v)],從而得到世界座標系和畫素座標系之間的關係,即通過A->B,B->C,C->D之間的關係,找到A->D的關係。
要想找到世界座標系到畫素座標系之間的轉換關係,必須要求出相機內參,外參,而標定就是求相機內外參的過程,通過求得的內外參,達到對成像物體的一、二維測量和畸變矯正的目的。
二、標定流程
實現的原理是根據相機的像元尺寸、焦距和標定板的描述檔案(.descr)來找到顯示的標定板影像上面的標誌點,從而確定標定板實際輸入的引數(Distance、Diameter等)和這些引數對應的影像畫素大小的關係,完成標定。
這裡我用的標定板是77圓點標定板,型號:HC070—3.75
標定板資料可參考:
標定步驟:
1)使用gen_caltab運算元生成一個標定檔案
標定前需要生成一個.descr的描述檔案,也就是世界座標系與畫素座標系的關係,當我們下一次做別的專案時,只需要呼叫描述檔案,即可完成標定過程。
生成標記檔案的運算元:gen_caltab (7, x方向的標記數;
7, y方向的標記數;
0.0075, 標記點圓心之間的距離,單位:米;
0.5, 標記點直徑與標記點圓心之間距離的比值;
‘C:/Users/Administrator/Desktop/caltab.descr’,標定板的描述檔案的儲存路徑;
‘caltab.ps’,描述標定板的一些資訊,列印標定板時會用到)
2)開啟標定助手,載入標定檔案,設定相機引數(單個像元寬高(問相機廠商或看手冊),相機焦距)
3)實時獲取各個角度、位置的標定板圖片(9-16張左右),並選擇其中一種圖片設定參考位姿,然後標定。
可以看到相機的引數:
4)儲存相機內、外參,下次使用測量助手直接呼叫內外參檔案。
單獨說一下如何進行畸變校正,可以接上面的第三步之後:生成標定資料(相機內、外參)程式碼,從而進行畸變校正
程式碼:
*相機內參
CameraParameters := [0.0375147,-270.806,8.30152e-006,8.3e-006,647.48,520.914,1280,960]
*相機位姿,即外參(旋轉矩陣+平移向量)
CameraPose := [-0.0091626,-0.00625214,0.700967,2.46926,358.933,179.443,0]
*1、校正徑向畸變,得到新的相機內參
change_radial_distortion_cam_par (‘adaptive’, CameraParameters, 0, CamParamOut)
stop ()
- Image Acquisition 02: Code generated by Image Acquisition 02
open_framegrabber (‘GigEVision’, 0, 0, 0, 0, 0, 0, ‘default’, -1, ‘default’, -1, ‘false’, ‘default’, ‘CAMERA_QBY_DM’, 0, -1, AcqHandle)
grab_image_start (AcqHandle, -1)
while (true)
grab_image_async (Image, AcqHandle, -1)
*2、對發生徑向畸變的影像生成投影對映,影像的對映資料存在第一個引數中
gen_radial_distortion_map (Map, CameraParameters, CamParamOut, ‘bilinear’)
*3、對影像進行畸變校正
map_image (Image, Map, ImageMapped)
endwhile
close_framegrabber (AcqHandle)
三、實戰:以一元硬幣為例
1、 開啟測量助手,載入上面得到的相機內、外參
2、.進行快速測量,可以看到最後測量結果24.1232mm
3、生成程式碼後,加入上面的畸變校正,即可完成完整的標定過程
3. Measure 01: Code generated by Measure 01
4. Measure 01: Initialize acquisition
open_framegrabber (‘GigEVision’, 0, 0, 0, 0, 0, 0, ‘default’, -1, ‘default’, -1, ‘false’, ‘default’, ‘CAMERA_QBY_DM’, 0, -1, AcqHandle)
5. Measure 01: Initialize calibration
CameraParameters := [0.0220788,-613.469,6.00309e-006,6e-006,613.491,509.255,1280,960]
CameraPose := [-0.00464111,-0.00298404,0.341764,2.05327,359.502,89.9295,0]
1、校正徑向畸變,得到新的相機內參
change_radial_distortion_cam_par (‘adaptive’, CameraParameters, 0, CamParamOut)
stop ()
6. Measure 01: Prepare measurement
AmplitudeThreshold := 40
RoiWidthLen2 := 25
set_system (‘int_zooming’, ‘true’)
7. Measure 01: Coordinates for line Measure 01 [0]
LineRowStart_Measure_01_0 := 495.5
LineColumnStart_Measure_01_0 := 385.5
LineRowEnd_Measure_01_0 := 498.167
LineColumnEnd_Measure_01_0 := 745.5
8. Measure 01: Convert coordinates to rectangle2 type
TmpCtrl_Row := 0.5(LineRowStart_Measure_01_0+LineRowEnd_Measure_01_0)
TmpCtrl_Column := 0.5*(LineColumnStart_Measure_01_0+LineColumnEnd_Measure_01_0)
TmpCtrl_Dr := LineRowStart_Measure_01_0-LineRowEnd_Measure_01_0
TmpCtrl_Dc := LineColumnEnd_Measure_01_0-LineColumnStart_Measure_01_0
TmpCtrl_Phi := atan2(TmpCtrl_Dr, TmpCtrl_Dc)
TmpCtrl_Len1 := 0.5sqrt(TmpCtrl_DrTmpCtrl_Dr + TmpCtrl_Dc*TmpCtrl_Dc)
TmpCtrl_Len2 := RoiWidthLen2
9. Measure 01: Create measure for line Measure 01 [0]
10. Measure 01: Attention: This assumes all images have the same size!
gen_measure_rectangle2 (TmpCtrl_Row, TmpCtrl_Column, TmpCtrl_Phi, TmpCtrl_Len1, TmpCtrl_Len2, 1280, 960, ‘nearest_neighbor’, MsrHandle_Measure_01_0)
while (true)
* Measure 01: Acquire image
grab_image (Image, AcqHandle)
* Measure 01: Execute measurements
*2、對發生徑向畸變的影像生成投影對映,影像的對映資料存在第一個引數中
gen_radial_distortion_map (Map, CameraParameters, CamParamOut, ‘bilinear’)
*3、對影像進行畸變校正
map_image (Image, Map, ImageMapped)
measure_pos (ImageMapped, MsrHandle_Measure_01_0, 19.5, 40, ‘all’, ‘all’, Row_Measure_01_0, Column_Measure_01_0, Amplitude_Measure_01_0, Distance_Measure_01_0)
* Measure 01: Transform to world coordinates
* Measure 01: Calibrate positions for Measure 01 [0]
image_points_to_world_plane (CameraParameters, CameraPose, Row_Measure_01_0, Column_Measure_01_0, 0.001, Column_World_Measure_01_0, Row_World_Measure_01_0)
* Measure 01: Calibrate distances
TmpCtrl_Length := |Row_World_Measure_01_0|
if (TmpCtrl_Length > 0)
tuple_select_range (Row_World_Measure_01_0, 0, TmpCtrl_Length - 2, TmpCtrl_RowFrom)
tuple_select_range (Column_World_Measure_01_0, 0, TmpCtrl_Length - 2, TmpCtrl_ColumnFrom)
tuple_select_range (Row_World_Measure_01_0, 1, TmpCtrl_Length - 1, TmpCtrl_RowTo)
tuple_select_range (Column_World_Measure_01_0, 1, TmpCtrl_Length - 1, TmpCtrl_ColumnTo)
distance_pp (TmpCtrl_RowFrom, TmpCtrl_ColumnFrom, TmpCtrl_RowTo, TmpCtrl_ColumnTo, Distance_World_Measure_01_0)
endif
* Measure 01: Do something with the results
endwhile
11. Measure 01: Clear measure when done
close_measure (MsrHandle_Measure_01_0)
相關文章
- 使用Halcon軟體和圓形標定板進行相機標定的步驟和教程
- 自動生成相機標定軌跡
- Autoware 標定工具 Calibration Tool Kit 聯合標定 Robosense-16 和 ZED 相機!Zed
- 高速攝影機輔助的相機方位線上標定
- 【軟體硬體】相機標定(Camera calibration)原理、步驟
- 1, 單相電機及單相調速電機
- 幾何校準 和 ros環境下標定Balser相機ROS
- ROS下采用camera_calibration進行雙目相機標定ROS
- OpenCV開發筆記(七十七):相機標定(二):透過棋盤標定計算相機內參矩陣矯正畸變攝像頭影像OpenCV筆記矩陣
- kalibr標定realsenseD435i --多相機標定
- halcon視訊教程 halcon模板匹配 halcon機器視覺 halcon C/C++/C# halcon視訊教程超人初級->超人強化->超人高階教材逐步進階,全面突破,簡單高效率學習視覺視覺C++C#
- 單目相機成像過程
- 機器人工具座標系標定原理機器人
- [快速閱讀七] Halcon裡emphasize函式相關資料.函式
- basler工業相機引數設定
- 基於halcon的目標定位與方向確定例項
- OpenCV開發筆記(七十六):相機標定(一):識別棋盤並繪製角點OpenCV筆記
- [Halcon] 機器視覺中常用運算元視覺
- 指標相關指標
- 安川機器人零點標定機器人
- 單目標定:從理論到OpenCV實踐OpenCV
- 微單相機和單反相機的區別?攝影入門第一課
- IER 512程式單印表機設定
- mybaties 標籤相關BAT
- halcon 修改影像格式
- Halcon快速入門
- halcon缺陷檢測
- ReelSteady Go for mac(GoPro相機防抖穩定處理工具)GoMac
- GoLand 相關設定GoLand
- 海康相機 畫素座標(px,py)到sdk ptz 座標轉換最後到onvif ptz座標
- html文字相關標籤HTML
- 簡單計算給定兩個給定經緯度座標的距離
- [機器視覺]halcon應用例項 邊緣檢測視覺
- 360如何定時關機win10_win10簡單設定360定時關機的方法Win10
- Halcon-表面檢測-----確定光度立體法系統的光源的方向
- AI降噪耳機,可在嘈雜人群中單獨通話,看一眼鎖定目標AI
- 驅動開發目標測試機器設定
- 全景拍攝“快門時間”相機引數設定策略