Halcon学习笔记:Halcon标定步骤-3d_coordinates.hdev示例
Halcon標(biāo)定步驟
1.設(shè)置相機(jī)內(nèi)部參數(shù)的初始值
StartCamPar := [0.016,0,0.0000074,0.0000074,326,247,652,494]
set_calib_data_cam_param (CalibDataID, 0, ‘a(chǎn)rea_scan_division’, StartCamPar)
1.1 相機(jī)型號(hào)
- (1)面陣
- (2)線陣
1.2 參數(shù)設(shè)置(這里只講面陣相機(jī))
- (1)Division 畸變模型
CameraParam:[Focus, Kappa, Sx, Sy, Cx, Cy, ImageWidth, ImageHeight] - (2)Polynomial 畸變模型
CameraParam:[Focus, K1, K2, K3, P1, P2, Sx, Sy, Cx, Cy, ImageWidth, ImageHeight]
注:當(dāng)鏡頭為遠(yuǎn)心鏡頭時(shí),Focus=0;
1.3 畸變類型的選擇
- Division 畸變模型只適用于精度要求不是很高,標(biāo)定圖片數(shù)量較少的情況;Polynomial 畸變模型對(duì)鏡像
畸變和切向畸變都校正,精度較高,花費(fèi)時(shí)間長(zhǎng)。
1.4 標(biāo)定時(shí)個(gè)參數(shù)值的確定技巧
- Focus f:鏡頭的標(biāo)稱焦距,( e.g, 0.016 m; 對(duì)于遠(yuǎn)心鏡頭為0。)
- κ: 一般去0.0
Or:
-
K1, K2, K3,P1, P2:可全部初始化為0
-
Sx: 由CCD\CMOS確定建議取值如下:
Full image (640480) Subsampling (320240)
1/3"-Chip 0.0000055 m 0.0000110 m
1/2"-Chip 0.0000086 m 0.0000172 m
2/3"-Chip 0.0000110 m 0.0000220 m -
Sy: 由CCD\CMOS確定建議取值如下:
for example:
Full image (640480) Subsampling (320240)
1/3"-Chip 0.0000055 m 0.0000110 m
1/2"-Chip 0.0000086 m 0.0000172 m
2/3"-Chip 0.0000110 m 0.0000220 m -
Cx and Cy: 光心坐標(biāo)初始值,建議取值如下:
for example:
Full image (640480) Subsampling (320240)
Cx 320.0 160.0
Cy 240.0 120.0 -
ImageWidth,ImageHeight:有實(shí)際圖片大小來(lái)初始化該值
for example:
Full image (640480) Subsampling (320240)
ImageWidth 640 320
ImageHeight 480 240
2.標(biāo)定板初始化
CaltabName := 'caltab_30mm.descr'//標(biāo)定板描述文件set_calib_data_calib_object (CalibDataID, 0, CaltabName)3.創(chuàng)建數(shù)據(jù)模型
create_calib_data ('calibration_object', 1, 1, CalibDataID)4.獲取標(biāo)定圖片
相機(jī)拍攝不同位姿下圖片8-15張,拍攝圖片時(shí)標(biāo)定板盡量覆蓋整個(gè)視場(chǎng)(標(biāo)定板要根據(jù)工作距離、視場(chǎng)大小定制);拍攝圖片上的圓直徑不得小于10個(gè)像素
#### 5.加載所有圖像,尋找標(biāo)定板區(qū)域,確定圓心,將結(jié)果加載到組元中 for I := 1 to NumImages by 1 ... acquire image ...(獲取圖像) find_caltab (Image, Caltab, CaltabName, SizeGauss, MarkThresh, MinDiamMarks) find_marks_and_pose (Image, Caltab, CaltabName, StartCamPar, StartThresh, \DeltaThresh, MinThresh, Alpha, MinContLength, MaxDiamMarks, RCoord, CCoord, StartPose)// 從標(biāo)定數(shù)據(jù)模型中獲取基于點(diǎn)的觀測(cè)數(shù)據(jù)(49個(gè)點(diǎn)的坐標(biāo),索引,粗略估計(jì)被測(cè)校準(zhǔn)物體相對(duì)于被測(cè)相機(jī)的姿態(tài)) set_calib_data_observ_points (CalibDataID, 0, 0, I, RCoord, CCoord, 'all', StartPose) endfor下面將Halcon中提取目標(biāo)點(diǎn)的大致原理說(shuō)一下:
- 首先f(wàn)ind_caltab 算子對(duì)圖像高斯濾波(核大小為SizeGauss),接著閾值分割(與之大小為MarkThresh)將標(biāo)定板的區(qū)域找出來(lái), find_marks_and_pose 算子對(duì)區(qū)域中的圓進(jìn)行分割,找到圓的個(gè)數(shù),周長(zhǎng),坐標(biāo)位置等應(yīng)該和標(biāo)定板描述文件中的一致,否則會(huì)自動(dòng)調(diào)整StartThresh,使得StartThresh按照DeltaThresh步長(zhǎng)減小到MinThresh,直到找到準(zhǔn)確的圓心。
6.有了所有圖像中的圓心就可以標(biāo)定了
* 返回平均投影誤差Errorscalibrate_cameras (CalibDataID, Errors)7.示例:3d_coordinates 測(cè)量世界坐標(biāo)中的傾斜物體
本地函數(shù): get_measure_positions
(Image : PlateRegion : CalibDataID, PoseIndex : Distance, Phi, RowCenter, ColumnCenter)
主函數(shù) main
* * 1.初始化程序 dev_close_window () dev_open_window (0, 0, 768, 576, 'black', WindowHandle) dev_update_off () dev_set_draw ('margin') dev_set_line_width (3) set_display_font (WindowHandle, 14, 'mono', 'true', 'false') * * 2.標(biāo)定相機(jī) * 為一個(gè)區(qū)域掃描相機(jī)生成一個(gè)相機(jī)參數(shù)數(shù)組,該參數(shù)數(shù)組設(shè)置為面陣相機(jī)的Division畸變模型模板: * CameraParam:[Focus, Kappa, Sx, Sy, Cx, Cy, ImageWidth, ImageHeight] CalTabDescrFile := 'caltab_big.descr' gen_cam_par_area_scan_division (0.008, 0, 0.0000086, 0.0000086, 384, 288, 768, 576, StartCamPar) * 創(chuàng)建haclon 標(biāo)定數(shù)據(jù)模型('calibration_object'為標(biāo)定設(shè)置類型,CalibDataID 數(shù)據(jù)模型的句柄 ) * 在標(biāo)定數(shù)據(jù)模型中設(shè)置相機(jī)的類型和初始參數(shù)(StartCamPar 為初始參數(shù)) * 定義在標(biāo)定模型中的標(biāo)定對(duì)象(CalTabDescrFile 描述文件名) create_calib_data ('calibration_object', 1, 1, CalibDataID) set_calib_data_cam_param (CalibDataID, 0, [], StartCamPar) set_calib_data_calib_object (CalibDataID, 0, CalTabDescrFile) * * 3.采圖 NumImages := 10 for I := 1 to NumImages by 1read_image (Image, 'calib/calib-3d-coord-' + I$'02d')dev_display (Image)Message := 'Find calibration plate in\nall calibration images (' + I + '/' + NumImages + ')'disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true') ***** 找到halcon 標(biāo)定板,并在標(biāo)定數(shù)據(jù)模型中設(shè)置提取的點(diǎn)和輪廓 ******find_calib_object (Image, CalibDataID, 0, 0, I - 1, [], [])* 從標(biāo)定數(shù)據(jù)模型中查詢存儲(chǔ)或計(jì)算的數(shù)據(jù)(O號(hào)相機(jī)數(shù)據(jù),項(xiàng)目類型-'init_params'表示初始相機(jī)內(nèi)部參數(shù),StartCamPar 初始化數(shù)據(jù))* 從標(biāo)定數(shù)據(jù)模型中獲取基于點(diǎn)的觀測(cè)數(shù)據(jù)(49個(gè)點(diǎn)的坐標(biāo),索引,粗略估計(jì)“被測(cè)校準(zhǔn)物體(標(biāo)定板)”相對(duì)于被測(cè)相機(jī)的姿態(tài))* 從校準(zhǔn)數(shù)據(jù)模型中獲取基于輪廓的觀測(cè)數(shù)據(jù)(標(biāo)定板輪廓,所觀察到的校準(zhǔn)對(duì)象位姿的索引)get_calib_data (CalibDataID, 'camera', 0, 'init_params', StartCamPar)get_calib_data_observ_points (CalibDataID, 0, 0, I - 1, Row, Column, Index, Pose)get_calib_data_observ_contours (Contours, CalibDataID, 'caltab', 0, 0, I - 1)* 標(biāo)出圓形坐標(biāo)點(diǎn)-畫叉gen_cross_contour_xld (Cross, Row, Column, 6, 0.785398)dev_set_color ('green')dev_display (Contours)dev_set_color ('yellow')dev_display (Cross) endfor disp_continue_message (WindowHandle, 'black', 'true') stop () * *** 通過(guò)同時(shí)最小化處理 確定所有相機(jī)參數(shù)(Error:優(yōu)化的反投影均方根誤差(RMSE))*** calibrate_cameras (CalibDataID, Error) * 從標(biāo)定數(shù)據(jù)模型中查詢存儲(chǔ)或計(jì)算的數(shù)據(jù)(0號(hào)相機(jī)的數(shù)據(jù),項(xiàng)目類型-'params'表示優(yōu)化后的相機(jī)內(nèi)部參數(shù),CamParam 輸出數(shù)據(jù)) get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam) * ******** 4.Perform measurements 驗(yàn)證(1D 尺寸測(cè)量) ******** * for I := 1 to NumImages by 1read_image (Image, 'calib/calib-3d-coord-' + I$'02d')* ** 一、現(xiàn)在,測(cè)量標(biāo)定板的黑邊的長(zhǎng)度:* I-索引號(hào); PlateRegion-標(biāo)定板區(qū)域;Distance-垂直邊框的距離;* Phi-公垂線的方向;RowCenter/ColumnCenter-table中心點(diǎn)坐標(biāo);* 生成一個(gè)矩形的XLD輪廓。get_measure_positions (Image, PlateRegion, CalibDataID, I, Distance, Phi, RowCenter, ColumnCenter)gen_rectangle2_contour_xld (Rectangle, RowCenter, ColumnCenter, Phi, Distance * 0.52, 8)*** 二、一維尺寸測(cè)量:* 1.設(shè)置測(cè)量區(qū)域:準(zhǔn)備提取垂直于矩形的直邊(MeasureHandle——測(cè)量矩形對(duì)象句柄)* 2.找尋你設(shè)定檢測(cè)區(qū)域內(nèi)的邊緣:提取垂直于矩形或環(huán)形弧的直邊* (Amplitude-指定的是一個(gè)縮放,通過(guò)邊界的坐標(biāo)加上縮放的計(jì)算,可以計(jì)算出確切的距離就存在Distance里)* 3.刪除一個(gè)測(cè)量對(duì)象gen_measure_rectangle2 (RowCenter, ColumnCenter, Phi, Distance * 0.52, 8, 768, 576, 'nearest_neighbor', MeasureHandle) measure_pos (Image, MeasureHandle, 1, 40, 'all', 'all', RowEdge, ColumnEdge, Amplitude, Distance1)close_measure (MeasureHandle)Rows := [RowEdge[0],RowEdge[|RowEdge| - 1]]Columns := [ColumnEdge[0],ColumnEdge[|RowEdge| - 1]]gen_cross_contour_xld (Cross, Rows, Columns, 16, Phi)*** 三、轉(zhuǎn)換坐標(biāo):(相機(jī)坐標(biāo)系->世界坐標(biāo)系的轉(zhuǎn)化)* 查詢標(biāo)定數(shù)據(jù)(所有標(biāo)定對(duì)象的總體姿態(tài)或特定的標(biāo)定對(duì)象姿態(tài)的數(shù)據(jù) * 通過(guò)選擇DataName中的以下參數(shù),您可以查詢?cè)谟蒫alibrate_cameras執(zhí)行標(biāo)定期間,* 哪些標(biāo)定對(duì)象位姿參數(shù)得到了(或已經(jīng)得到了)優(yōu)化)* 'pose'——優(yōu)化標(biāo)定對(duì)象位姿,相對(duì)于當(dāng)前參考相機(jī)get_calib_data (CalibDataID, 'calib_obj_pose', [0,I - 1], 'pose', Pose)* 將兩個(gè)邊界點(diǎn)轉(zhuǎn)換為世界坐標(biāo)系* 計(jì)算兩點(diǎn)的距離image_points_to_world_plane (CamParam, Pose, Rows, Columns, 'm', SX, SY)distance_pp (SY[0], SX[0], SY[1], SX[1], Width)* ** 四、顯示寬度測(cè)量結(jié)果dev_display (Image)dev_set_color ('white')dev_set_line_width (3)dev_display (Rectangle)dev_set_color ('green')dev_set_draw ('fill')dev_set_line_width (2)dev_display (Cross)dev_set_draw ('margin')* 寬度顯示disp_message (WindowHandle, 'Width = ' + (Width * 100)$'8.3f' + 'cm', 'window', 12, 12, 'black', 'true')disp_continue_message (WindowHandle, 'black', 'true')stop ()* ** 五、現(xiàn)在,測(cè)量標(biāo)定標(biāo)記(標(biāo)定板上的標(biāo)定點(diǎn))的大小 * 提取圖像中的橢圓erosion_circle (PlateRegion, ROI, 17.5)reduce_domain (Image, ROI, ImageReduced)*使用Deriche, Lanser, Shen或Canny過(guò)濾器提取亞像素精確的邊緣edges_sub_pix (ImageReduced, Edges, 'canny', 1, 20, 60)select_contours_xld (Edges, SelectedEdges, 'contour_length', 20, 99999999, -0.5, 0.5)* Fit ellipses to extracted edges 將橢圓匹配到提取的邊緣* 由橢圓或橢圓弧構(gòu)成的近似的XLD輪廓(輸出橢圓參數(shù))fit_ellipse_contour_xld (SelectedEdges, 'fitzgibbon', -1, 2, 0, 200, 3, 2, Row, Column, Phi, Radius1, Radius2, StartPhi, EndPhi, PointOrder)MeanRadius1 := mean(Radius1)MeanRadius2 := mean(Radius2)DevRadius1 := deviation(Radius1)DevRadius2 := deviation(Radius2)** 將橢圓轉(zhuǎn)換為世界坐標(biāo),它們應(yīng)該是圓,并將圓從米轉(zhuǎn)換為毫米,這樣我們就可以看到它們。contour_to_world_plane_xld (SelectedEdges, WorldCircles, CamParam, Pose, 'mm')* Fit ellipses to the circles in world coordinates 在世界坐標(biāo)中將橢圓與圓匹配fit_ellipse_contour_xld (WorldCircles, 'fitzgibbon', -1, 2, 0, 200, 3, 2, Row, Column, Phi, RadiusW1, RadiusW2, StartPhi, EndPhi, PointOrder)MeanRadiusW1 := mean(RadiusW1)MeanRadiusW2 := mean(RadiusW2)DevRadiusW1 := deviation(RadiusW1)DevRadiusW2 := deviation(RadiusW2)* * 顯示橢圓測(cè)量結(jié)果dev_display (Image)dev_set_color ('yellow')dev_set_line_width (3)dev_display (SelectedEdges)Message := 'Measured dimensions of the ellipses'Message[0] := ' Mean Radius1; Mean Radius2; (Standard deviations [%])'Message[1] := 'Image coordinates: ' + MeanRadius1$'5.2f' + 'px; ' + MeanRadius2$'5.2f' + 'px (' + (DevRadius1 / MeanRadius1 * 100)$'4.2f' + ', ' + (DevRadius2 / MeanRadius2 * 100)$'4.2f' + ')'Message[2] := 'World coordinates: ' + (MeanRadiusW1 / 10)$'5.2f' + 'cm; ' + (MeanRadiusW2 / 10)$'5.2f' + 'cm (' + (DevRadiusW1 / MeanRadiusW1 * 100)$'4.2f' + ', ' + (DevRadiusW2 / MeanRadiusW2 * 100)$'4.2f' + ')'disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')if (I < 10)disp_continue_message (WindowHandle, 'black', 'true')stop ()endif endfor clear_calib_data (CalibDataID)結(jié)果:
1.read_image
2.find_calib_object 填充標(biāo)定數(shù)據(jù)模型
3.calibrate_cameras (CalibDataID, Error) 矯正所有相機(jī)參數(shù)
4.驗(yàn)證相機(jī)標(biāo)定結(jié)果:通過(guò) 1D mesuring
- 1)get_measure_positions 找到需要測(cè)量區(qū)域的位姿(位置和方向)
- 2)gen_measure_rectangle2 設(shè)置測(cè)量區(qū)域
- 3)measure_pos 找尋你設(shè)定檢測(cè)區(qū)域內(nèi)的邊緣:提取垂直于矩形的所有直邊
- 4)image_points_to_world_plane 轉(zhuǎn)換坐標(biāo):(相機(jī)坐標(biāo)系->世界坐標(biāo)系的轉(zhuǎn)化)
5)測(cè)量標(biāo)記點(diǎn)的大小: - Radius1 ,Radius2 橢圓長(zhǎng)短 半徑
8.參考算子介紹
- HALCON 1D Measure 算子初識(shí)
- 一維測(cè)量中measure_pos和measure_pairs算子
總結(jié)
以上是生活随笔為你收集整理的Halcon学习笔记:Halcon标定步骤-3d_coordinates.hdev示例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: QT学习笔记(四):Qt5+MSVC编译
- 下一篇: Python绘制决策树的节点