Halcon相機標定簡介


 

相機標定簡介

首先鏡頭有畸變,也就是說照出的圖像與實際不符產生了形變。即使工業鏡頭也是有千分之幾的畸變率的。
上個圖告訴大家畸變
在這里插入圖片描述
這個圖里,第一個圖就是我們相機下的真實的形狀,后邊兩個就是照出來有畸變的圖片。

其次鏡頭與相機無論你的機械結構精度多高,也不容易或者說沒辦法將相機安裝的特別正,那相機安裝不正也是會導致誤差的。大家想知道具體數學模型的話可以搜一下相機標定的理論方面的知識,我側重怎么做。
標定就是把上述兩個東西轉化成正常的。
無論是在圖像測量或者機器視覺應用中,相機參數的標定都是非常關鍵的環節,其標定結果的精度及算法的穩定性直接影響相機工作產生結果的准確性。

深度說明

1、相機標定參數介紹

在這里插入圖片描述
內參:確定攝像機從三維空間到二維空間的投影關系。
針孔相機(FA鏡頭相機)模型為6個參數(f,kSx,Sy,Cx,Cy);遠心鏡頭相機模型為5個參數(f,Sx,Sy,Cx,Cy);線陣相機為11個參數(f,k,Sx,Sy,Cx,Cy,Width,Highth,Vx,Vy,Vz)。
其中:
f為焦距;
k表示徑向畸變量級。如果k為負值,畸變為桶形畸變,如果為正值,那么畸變為枕形畸變。
Sx,Sy是縮放比例因子。對於相機(FA鏡頭)表示圖像傳感器水平和垂直方向上相鄰像素之間的距離,初始值與真實值越接近計算速度越快。對於遠心攝像機模型,表示像素在世界坐標系中的尺寸。
Cx,Cy是圖像的主點,對於相機,這個點是投影中心在成像平面上的垂直投影,同時也是徑向畸變的中心。對於遠心攝像機模型,只表示畸變的中心。
Vx,Vy,Vz:線陣相機必須與被拍攝物體之間有相對移動才能拍攝到一幅有用的圖像。這是運動向量。Sx,Sy對於線陣相機是相鄰像元的水平和垂直距離。

2、標定板詳細介紹

問題1:halcon是否只能使用halcon專用的標定板?

halcon提供了簡便、精准的標定算子與標定助手,這在實際使用中極大地方便了使用者
在halcon中有兩種標定方式:
halcon自帶例程中出現的,用halcon定義的標定板,如下圖:
在這里插入圖片描述
用戶自定義標定板,用戶可以制作任何形狀、形式的標定板,如下圖:
在這里插入圖片描述
所以,halcon並非只能使用專用標定板,也可以使用自定義標定板就可以進行標定。

問題2:halcon標定板如何生成?

使用gen_caltab算子來制作一個標定板
gen_caltab( : : XNum, YNum, MarkDist, DiameterRatio, CalPlateDescr, CalPlatePSFile : )
XNum:每行黑色標志圓點的數量
YNum:每列黑色標志圓點的數量
MarkDist:兩個就近黑色圓點中心之間的距離,單位是m
DiameterRatio:黑色圓點直徑與兩圓點中心距離的比值
CalPlateDescr:標定板描述文件的文件路徑
CalPlatePSFile :標定板圖像文件路徑,可以用ps打開
示例:
gen_caltab( 7, 7, 0.1, 0.5, ‘caltab.descr’, ‘caltab.ps’)
大家可以自己思考一下每個參數的含義
行數:7
列數:7
黑色圓點半徑:0.05m
圓點中心間距:0.1m

問題3:halcon標定板如何擺放,拍照數量有無限制?

並非拍照標定數量越多,越能取得高的精度,halcon建議拍攝數量在9-16張,並且對擺放位置做了建議。標定板占標定視野的1/3-1/4,對於標定板成像灰度值應大於128,以便順利提取。如下圖所示:
在這里插入圖片描述

標定步驟

注意只介紹面陣相機,其他的相機和面陣道理想同。

1、設置相機內部初始值

使用set_calib_data_cam_param 算子設置相機內部初始值

set_calib_data_cam_param( : : CalibDataID, CameraIdx, CameraType, CameraParam : )
CalibDataID:標定句柄
CameraIdx:相機序號
CameraType:相機模型種類;面陣相機Division畸變模型’area_scan_division’;polynomial畸變模型’area_scan_polynomial’。。。。。。
CameraParam :與相機模型種類相對應的參數;面陣相機Division畸變模型’area_scan_division’([Focus, Kappa, Sx, Sy, Cx, Cy, ImageWidth, ImageHeight]);polynomial畸變模型’area_scan_polynomial’([Focus, K1, K2, K3, P1, P2, Sx, Sy, Cx, Cy, ImageWidth, ImageHeight])。。。。。。

相機模型種類與相機參數對應表:
在這里插入圖片描述

畸變類型選擇與參數確定技巧

畸變模型選擇
division畸變模型只適用於精度不高的,標定圖片數量較少的情況:
polynomial畸變模型對徑向畸變、切向畸變都進行矯正,精度較高,花費時間較長。
參數確定技巧
Focus代表焦距,按照我們鏡頭參數進行填寫,遠心鏡頭填寫0

Kappa為畸變大小,因為在標定之前,所以默認填寫0

Sx, Sy像元的寬高填寫相機的像元尺寸。可以查相機手冊,或者咨詢相機廠家。
Cx, Cy填寫圖像的中心坐標
ImageWidth, ImageHeight填寫圖像的寬高

2、標定板初始化

使用算子 set_calib_data_calib_object
例如:
CaltabDescr := ‘caltab_100mm.descr’
set_calib_data_calib_object (CalibDataID, 0, CaltabDescr)
這個比較簡單,大家看幫助就可以懂,就不進行介紹了

3、創建標定數據模型

使用算子 create_calib_data( : : CalibSetup, NumCameras, NumCalibObjects : CalibDataID)
CalibSetup:創建的內容
NumCameras:相機個數
NumCalibObjects :標定項目數
CalibDataID:標定句柄
例如:
create_calib_data (‘calibration_object’, 1, 1, CalibDataID)

4、獲取標定圖片

標定板為正方形,尺寸大小為要照射區域寬度的1/3,相機拍攝或者讀入9-16張圖片,拍攝圖片時標定板盡量覆蓋整個視場;標定板圓點的直徑不能小於10個像素。

5、使用圖像進行相機內參標定,得到結果

方式一:
使用標定圖像,直接用halcon全自動,進行標定
find_calib_object (Image, CalibDataID, CameraIndex, 0, PoseIndex, [], [])
得到標定數據
get_calib_data (CalibDataID, ‘camera’, 0, ‘type’, CameraType)

方式二:
1、尋找標定板區域,確定圓心,將結果加載到組元中
find_caltab(Image : CalPlate : CalPlateDescr, SizeGauss, MarkThresh, MinDiamMarks : )
find_marks_and_pose(Image, CalPlateRegion : : CalPlateDescr, StartCamParam, StartThresh, DeltaThresh, MinThresh, Alpha, MinContLength, MaxDiamMarks : RCoord, CCoord, StartPose)
set_calib_data_observ_points( : : CalibDataID, CameraIdx, CalibObjIdx, CalibObjPoseIdx, Row, Column, Index, Pose : )
原理:首先find_caltab算子對圖像高斯濾波(核大小為SizeGauss),接着閾值分割(閾值大小為MarkThresh)將標定板的區域找出來;find_marks_and_pose算子對區域中的圓進行分割,找到圓的個數,周長,坐標等應該和標定板描述文件中的一致,否則會自動調整StartThresh,使得StartThresh按照DeltaThresh步長減小到MinDiamMarks ,直到找到准確的圓心。
2、進行標定
calibrate_cameras( : : CalibDataID : Error)
返回平均投影誤差Error

6、使用圖像進行相機外參標定,得到結果

相機外參:決定攝像機坐標系與世界坐標系之間相對位置關系
其中Pw為世界坐標,Pc為相機坐標,T=(Tx,Ty,Tz)是平移向量,R=(a,b,r)是旋轉矩陣,分別是繞相機坐標系Z軸旋轉角度為r;繞相機坐標系Y軸旋轉角度為b;繞相機坐標系X軸旋轉角度為a。6個參數組成相機外參(a,b,r,Tx,Ty,Tz)
並且滿足下式:
Pc=R*Pw+T

具體步驟:
set_calib_data_cam_param( : : CalibDataID, CameraIdx, CameraType, CameraParam : )
set_calib_data_calib_object( : : CalibDataID, CalibObjIdx, CalibObjDescr : )
find_calib_object(Image : : CalibDataID, CameraIdx, CalibObjIdx, CalibObjPoseIdx, GenParamName, GenParamValue : )
get_calib_data_observ_contours( : Contours : CalibDataID, ContourName, CameraIdx, CalibObjIdx, CalibObjPoseIdx : )
get_calib_data_observ_points( : : CalibDataID, CameraIdx, CalibObjIdx, CalibObjPoseIdx : Row, Column, Index, Pose)
set_origin_pose( : : PoseIn, DX, DY, DZ : PoseNewOrigin)
在這里插入圖片描述

Halcon相機標定代碼與解析

**創建標定板
gen_caltab(7,7,0.008,0.5,'48_48mm.descr','48_48mm.ps') *=======標定內參 dev_close_window () dev_open_window (0, 0, 652, 494, 'black', WindowHandle) dev_update_off () dev_set_draw ('margin') dev_set_line_width (3) OpSystem := environment('OS') set_display_font (WindowHandle, 14, 'mono', 'true', 'false') *標定相機 StartCamPar := [0.0,0.0,0.0000299,0.0000299,4896/2,3264/2,4896,3264] create_calib_data ('calibration_object', 1, 1, CalibDataID) set_calib_data_cam_param (CalibDataID, 0, 'area_scan_telecentric_division', StartCamPar) set_calib_data_calib_object (CalibDataID, 0, '48_48mm.descr') for index := 1 to 13 by 1 read_image (Image, '標定20/' + index + '.png') get_image_size(Image, Width, Height) dev_display (Image) find_calib_object (Image, CalibDataID, 0, 0, index, [], []) get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, index) dev_set_color ('green') dev_display (Caltab) endfor calibrate_cameras (CalibDataID, Error) get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam) get_calib_data (CalibDataID, 'calib_obj_pose', [0,1], 'pose', PoseCalib) *輸出計算的相機內參 write_cam_par (CamParam, 'camera_parameters.dat') Message:= '相機內參已經寫入文件中' disp_message (WindowHandle, Message, 'window', 12, 12, 'red', 'false') clear_calib_data (CalibDataID) stop() *=====標定外參 dev_set_draw ('margin') dev_set_line_width (1) set_display_font (WindowHandle, 14, 'mono', 'true', 'false') *從文件中讀取內參 存儲文件:camera_parameters.dat try read_cam_par ('camera_parameters.dat', CamParam) catch (Exception) stop () endtry *開始計算 open_file('data.csv','output', FileHandle) fwrite_string(FileHandle,'Dis_pix*0.0299204,Dis_m*1000,Distance') fnew_line (FileHandle) close_file(FileHandle) *選擇一張作為標定作為最終標定位姿(任意一張都可以) index:=1 read_image (Image,'標定20/'+index+'.png') dev_display (Image) CaltabName := '48_48mm.descr' create_calib_data ('calibration_object', 1, 1, CalibDataID) set_calib_data_cam_param (CalibDataID, 0, 'area_scan_telecentric_division', CamParam) set_calib_data_calib_object (CalibDataID, 0, CaltabName) find_calib_object (Image, CalibDataID, 0, 0, 1, [], []) get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, 1) get_calib_data_observ_points (CalibDataID, 0, 0, 1, RCoord, CCoord, Index, PoseForCalibrationPlate) dev_set_color ('green') dev_display (Caltab) dev_set_color ('red') disp_caltab (WindowHandle, CaltabName, CamParam, PoseForCalibrationPlate, 1) dev_set_line_width (1) disp_circle (WindowHandle, RCoord, CCoord, gen_tuple_const(|RCoord|,1.5)) * caltab_points (CaltabName, X, Y, Z) * calibrate_cameras (CalibDataID, Error) * To take the thickness of the calibration plate into account, the z-value * of the origin given by the camera pose has to be translated by the * thickness of the calibration plate. * Deactivate the following line if you do not want to add the correction. set_origin_pose (PoseForCalibrationPlate, 0, 0, 0, PoseCalib) * disp_continue_message (WindowHandle, 'black', 'true') * stop () *像素距離 distance_pp(RCoord[0],CCoord[0],RCoord[48],CCoord[48], Dis_pix) *像素直接轉換mm然后計算 pix2mm(RCoord, CCoord,CamParam[2],CamParam[3],newCol,newRow) distance_pp(newRow[0],newCol[0],newRow[48],newCol[48], Dis_m) *用同一個世界坐標系來計算 image_points_to_world_plane(CamParam, PoseCalib,[RCoord[0],RCoord[48]], [CCoord[0],CCoord[48]], 'mm', X1, Y1) distance_pp(Y1[0],X1[0],Y1[1],X1[1],Distance) *輸出計算結果比較 open_file('data.csv','append', FileHandle) fwrite_string(FileHandle, Dis_pix*0.0299+','+Dis_m*1000+','+Distance+'\n') close_file(FileHandle) Message:= '計算完畢' disp_message (WindowHandle, Message, 'window', 12, 12, 'red', 'false') stop()

此文檔由http://www.ihalcon.com/read-7598.html分享整理得到。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM