halcon手眼标定例程详解_(halcon实例)halcon的手眼标定例程

对于标定来说,一般常见的有用于测量的线性与非线性标定,另一类就是和运动相关的标定,手眼标定。

勇哥写过许多epson机器人的手眼标定,也有halcon仿制这种方式的实现方法。

但是halcon有自己的手眼标定。

CalibObjDescr := 'calibrate_hand_eye_scara_setup_01_calplate.cpd'

CalibrationPlateThickness := 0.003

gen_cam_par_area_scan_division (0.0165251, -642.277, 4.65521e-006, 4.65e-006, 595.817, 521.75, 1280, 1024, CameraParam)

ObjectThickness := 0.001

dev_close_window ()

dev_open_window_fit_size (0, 0, 1280, 1024, 640, -1, WindowHandle)

set_display_font (WindowHandle, 14, 'mono', 'true', 'false')

dev_update_off ()

//创建标定模型,注意这个地方第一个参数输入的是手眼标定固定相机模式

create_calib_data ('hand_eye_scara_stationary_cam', 1, 1, CalibDataID)

//设置相机参数和相机类型为area_scan_division,这里是面扫,同时相机输入参数为CameraParam

set_calib_data_cam_param (CalibDataID, 0, [], CameraParam)

//在标定模型中指定标定板所使用的标定板描述文件

set_calib_data_calib_object (CalibDataID, 0, CalibObjDescr)

for Index := 1 to 10 by 1

read_image (CalibImage, '3d_machine_vision/hand_eye/scara_stationary_cam_setup_01_calib_' + Index$'02')

//读取每一次拍照时机械手的姿态,机械手携带标定板在不同的角度拍照

read_pose ('scara_stationary_cam_setup_01_tool_in_base_pose_' + Index$'02' + '.dat', ToolInBasePose)

//设置标定模型中的标定数据,其实是设置机械手未端参数信息,

//这个信息是从上面那个函数读取进来的。

set_calib_data (CalibDataID, 'tool', Index, 'tool_in_base_pose', ToolInBasePose)

//找到标定对象

find_calib_object (CalibImage, CalibDataID, 0, 0, Index, [], [])

dev_display (CalibImage)

//从标定数据模型中得到标定对象姿态信息

get_calib_data_observ_pose (CalibDataID, 0, 0, Index, ObjInCameraPose)

//显示标定内容

disp_caltab (WindowHandle, CalibObjDescr, CameraParam, ObjInCameraPose, 1)

disp_message (WindowHandle, 'Calibration image ' + Index + ' of 10', 'window', 12, 12, 'black', 'true')

wait_seconds (0.2)

endfor

disp_continue_message (WindowHandle, 'black', 'true')

stop ()

check_hand_eye_calibration_input_poses (CalibDataID, 0.05, 0.005, Warnings)

if (|Warnings| != 0)

dev_inspect_ctrl (Warnings)

stop ()

endif

//创建一个手眼标定

calibrate_hand_eye (CalibDataID, Errors)

//得到相机外参数,也就是CCD坐标系和机械手基础坐标系之间在的关系。

//即旋转矩阵和平移矢量,就是在CCD坐标系下机械手的姿态,

//这也是我们手眼标定要得到的参数,有了各个坐标系之间的这种转换关系

//就可以算出将来识别目标在机械手坐标系下的坐标。

get_calib_data (CalibDataID, 'camera', 0, 'base_in_cam_pose', BaseInCamPosePre)

disp_preliminary_result (WindowHandle, BaseInCamPosePre, Errors)

disp_continue_message (WindowHandle, 'black', 'true')

stop ()

read_image (ImageRef, '3d_machine_vision/hand_eye/scara_stationary_cam_setup_01_calib_ref')

//得到标定姿态

get_calib_plate_pose (ImageRef, CameraParam, CalibObjDescr, ObjInCamPoseRef)

//读取此时机械手的姿态数据

read_pose ('scara_stationary_cam_setup_01_tool_in_base_pose_ref.dat', ToolInBasePoseRef)

//确定读入标定板目标Z方向的值

fix_scara_ambiguity_stationary_cam (BaseInCamPosePre, ToolInBasePoseRef, ObjInCamPoseRef, ZCorrection)

//设置3D坐标原点,BaseInCamPose为新的3D位置,也就是在CCD坐标系下

//机械手基础坐标系的姿态

set_origin_pose (BaseInCamPosePre, 0, 0, ZCorrection, BaseInCamPose)

disp_final_results (WindowHandle, BaseInCamPosePre, BaseInCamPose)

disp_end_of_program_message (WindowHandle, 'black', 'true')

//姿态转换函数,因为前面求解的是机械手在CCD坐标系下的位置,这里

//转换成CCD在机械坐标下的姿态,并且赋值给变量CamInBasePse

pose_invert (BaseInCamPose, CamInBasePose)

//创建目标在CCD坐标系下的姿态信息

create_pose (0.0035, -0.0128, 0.7981, 1.345, 356.158, 180.194, 'Rp+T', 'gba', 'point', ObjInCamPose)

//根据CCD在机械手基础坐标系下的姿态和目标在CCD坐标系下的姿态求解目标

//在机械手基础坐标系下的姿态,有了这个姿态就可以控制机械手去抓取这个目标

//这就是我们要进行手眼标下的最终目的

pose_compose (CamInBasePose, ObjInCamPose, ObjInBasePose)

//设置3D坐标原点,MPInCamPose为新的3D位置,也就是在CCD坐标系下

//测量板的姿态

set_origin_pose (ObjInCamPoseRef, 0, 0, CalibrationPlateThickness - ObjectThickness, MPInCamPose)

//保存在机械手下CCD的姿态

write_pose (CamInBasePose, 'cam_in_base_pose.dat')

//保存相机的内参

write_cam_par (CameraParam, 'camera_parameters.dat')

//保存在CCD坐标系下的测量板的姿态

write_pose (MPInCamPose, 'measurement_plane_in_cam_pose.dat')

可以看到,板定板的类型不是halcon那种玻璃标定板。

关于标定板的支持什么样的类型,还值得再研究一下。

2020.5.22 勇哥注:

halcon12开始支持下图所示的蜂窝标定板。

之前和之后的的halcon版本都支持阵列标定板。

即halcon12之后都支持两种类型的标定板。

#转载请注明出处 www.skcircle.com 《少有人走的路》勇哥的工业自动化技术网站。如果需要本贴图片源码等资源,请向勇哥索取。

你可能感兴趣的:(halcon手眼标定例程详解)