Halcon 学习笔记---单相机标定(2)
一、单项机标定原因
- 降低畸变(相差)
- 测量
二、相机标定求出什么
该方程是求取世界坐标系与像素坐标系之间转换矩阵,本质就是求出相机的内外参数。其中dx和dy为每个像素在图像坐标系(UVO)沿U和V方向的物理尺寸,单位毫米每像素, U0 和 V0 为像素坐标 中心即图像中心(光轴与图像平面的交点)。
三、标定助手
设置标定参数;
尽量选择9到16张图片,且图片覆盖整个视野,Mark点出现在视野各个区域,同时标定板也可以发生倾斜,旋转,注意只要不出现标定点提取失败就可以。点击标定按钮前,选择一张设置位姿。
查看结果:相机内外参数。也可插入代码。
四、畸变校正(不需要外参)
畸变的原因自己去查找,在这里不罗嗦了。畸变如B所示。
过程:
标定助手---->获取相机内外参数------->校正(相机位置不能发生改变)
change_radial_distortion_cam_param() 径向畸变
gen_radial_distorition_map() 形成映射矩阵
map_image() 图像映射
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | * Calibration 01: Code generated by Calibration 01 ImageFiles := [] ImageFiles[0] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_01.png' ImageFiles[1] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_02.png' ImageFiles[2] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_03.png' ImageFiles[3] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_04.png' ImageFiles[4] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_05.png' ImageFiles[5] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_06.png' ImageFiles[6] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_07.png' ImageFiles[7] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_08.png' ImageFiles[8] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_09.png' ImageFiles[9] := 'E:/欣奕华/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_10.png' ImageFiles[10] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_11.png' ImageFiles[11] := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_12.png' dev_close_window() read_image (Image1, 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_01.png' ) get_image_size (Image1, Width, Height) dev_open_window (0, 0, Width, Height, 'black' , WindowHandle) dev_set_line_width (2) dev_set_draw ( 'margin' ) TmpCtrl_ReferenceIndex := 0 TmpCtrl_PlateDescription := 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/caltab_30mm.descr' StartParameters := [0.008,0,8.3e-006,8.3e-006,320,240,640,480] TmpCtrl_FindCalObjParNames := [ 'gap_tolerance' , 'alpha' , 'skip_find_caltab' ] TmpCtrl_FindCalObjParValues := [1,1, 'false' ] * Calibration 01: Create calibration model for managing calibration data create_calib_data ( 'calibration_object' , 1, 1, CalibHandle) set_calib_data_cam_param (CalibHandle, 0, 'area_scan_division' , StartParameters) set_calib_data_calib_object (CalibHandle, 0, TmpCtrl_PlateDescription) * Calibration 01: Collect mark positions and estimated poses for all plates for Index := 0 to |ImageFiles|-1 by 1 read_image (Image, ImageFiles[Index]) find_calib_object (Image, CalibHandle, 0, 0, Index, TmpCtrl_FindCalObjParNames, TmpCtrl_FindCalObjParValues) get_calib_data_observ_contours (Contours, CalibHandle, 'marks' , 0, 0, Index) get_calib_data_observ_points (CalibHandle, 0, 0, Index, RCoord, CCoord, Index1, Pose) dev_set_color ( 'green' ) dev_display (Image) dev_display (Contours) disp_cross (WindowHandle, RCoord, CCoord, 6, 0) dev_set_color ( 'yellow' ) disp_3d_coord_system (WindowHandle, StartParameters, Pose, 0.02) endfor * Calibration 01: Perform the actual calibration calibrate_cameras (CalibHandle, TmpCtrl_Errors) get_calib_data (CalibHandle, 'camera' , 0, 'params' , CameraParameters) get_calib_data (CalibHandle, 'calib_obj_pose' , [0, TmpCtrl_ReferenceIndex], 'pose' , CameraPose) * Calibration 01: Adjust origin for plate thickness set_origin_pose (CameraPose, 0.0, 0.0, 0.001, CameraPose) * Calibration 01: Clear calibration model when done clear_calib_data (CalibHandle) stop () CameraParametersDis := CameraParameters CameraParametersDis[1] := 0 change_radial_distortion_cam_par ( 'adaptive' , CameraParameters, 0, CamParamOut) gen_radial_distortion_map (Map, CameraParameters, CamParamOut, 'bilinear' ) map_image (Image1, Map, ImageMapped) |
五、测量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | * Measure 01: Code generated by Measure 01 * Measure 01: Initialize calibration CameraParameters := [0.0186517,-518.695,8.35295e-006,8.3e-006,243.968,254.876,640,480] CameraPose := [0.0102948,-0.00294296,0.290575,358.426,32.4473,91.0773,0] * Measure 01: Prepare measurement AmplitudeThreshold := 15 RoiWidthLen2 := 2 set_system ( 'int_zooming' , 'true' ) * Measure 01: Coordinates for line Measure 01 [0] LineRowStart_Measure_01_0 := 143.25 LineColumnStart_Measure_01_0 := 359.016 LineRowEnd_Measure_01_0 := 143.25 LineColumnEnd_Measure_01_0 := 382.761 * 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.5*sqrt(TmpCtrl_Dr*TmpCtrl_Dr + TmpCtrl_Dc*TmpCtrl_Dc) TmpCtrl_Len2 := RoiWidthLen2 * Measure 01: Create measure for line Measure 01 [0] * Measure 01: Attention: This assumes all images have the same size! gen_measure_rectangle2 (TmpCtrl_Row, TmpCtrl_Column, TmpCtrl_Phi, TmpCtrl_Len1, TmpCtrl_Len2, 640, 480, 'nearest_neighbor' , MsrHandle_Measure_01_0) * Measure 01: *************************************************************** * Measure 01: * The code which follows is to be executed once / measurement * * Measure 01: *************************************************************** * Measure 01: Load image read_image (Image, 'E:/项目/Halcon/STUDY/Lesson_13_棋盘格标定/scratch/scratch_calib_01.png' ) * Measure 01: Execute measurements measure_pos (Image, MsrHandle_Measure_01_0, 0.4, 15, '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 * Measure 01: Clear measure when done close_measure (MsrHandle_Measure_01_0) |
分类:
相机标定
, Halcon 学习笔记
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)