Skip to content

hand_eye_calibrationHandEyeCalibrationHandEyeCalibrationhand_eye_calibrationT_hand_eye_calibration๐Ÿ”—

Short description๐Ÿ”—

hand_eye_calibrationHandEyeCalibrationHandEyeCalibrationhand_eye_calibrationT_hand_eye_calibration โ€” Perform a hand-eye calibration.

Signature๐Ÿ”—

hand_eye_calibration( number X, number Y, number Z, number Row, number Col, integer NumPoints, pose RobotPoses, campar CameraParam, string Method, string QualityType, out pose CameraPose, out pose CalibrationPose, out real Quality )void HandEyeCalibration( const HTuple& X, const HTuple& Y, const HTuple& Z, const HTuple& Row, const HTuple& Col, const HTuple& NumPoints, const HTuple& RobotPoses, const HTuple& CameraParam, const HTuple& Method, const HTuple& QualityType, HTuple* CameraPose, HTuple* CalibrationPose, HTuple* Quality )static void HOperatorSet.HandEyeCalibration( HTuple x, HTuple y, HTuple z, HTuple row, HTuple col, HTuple numPoints, HTuple robotPoses, HTuple cameraParam, HTuple method, HTuple qualityType, out HTuple cameraPose, out HTuple calibrationPose, out HTuple quality )def hand_eye_calibration( x: Sequence[Union[float, int]], y: Sequence[Union[float, int]], z: Sequence[Union[float, int]], row: Sequence[Union[float, int]], col: Sequence[Union[float, int]], num_points: Sequence[int], robot_poses: Sequence[Union[int, float]], camera_param: Sequence[Union[int, float, str]], method: str, quality_type: MaybeSequence[str] ) -> Tuple[Sequence[Union[int, float]], Sequence[Union[int, float]], Sequence[float]]

def hand_eye_calibration_s( x: Sequence[Union[float, int]], y: Sequence[Union[float, int]], z: Sequence[Union[float, int]], row: Sequence[Union[float, int]], col: Sequence[Union[float, int]], num_points: Sequence[int], robot_poses: Sequence[Union[int, float]], camera_param: Sequence[Union[int, float, str]], method: str, quality_type: MaybeSequence[str] ) -> Tuple[Sequence[Union[int, float]], Sequence[Union[int, float]], float]Herror T_hand_eye_calibration( const Htuple X, const Htuple Y, const Htuple Z, const Htuple Row, const Htuple Col, const Htuple NumPoints, const Htuple RobotPoses, const Htuple CameraParam, const Htuple Method, const Htuple QualityType, Htuple* CameraPose, Htuple* CalibrationPose, Htuple* Quality )

HPose HCamPar::HandEyeCalibration( const HTuple& X, const HTuple& Y, const HTuple& Z, const HTuple& Row, const HTuple& Col, const HTuple& NumPoints, const HPoseArray& RobotPoses, const HString& Method, const HTuple& QualityType, HPose* CalibrationPose, HTuple* Quality ) const

HPose HCamPar::HandEyeCalibration( const HTuple& X, const HTuple& Y, const HTuple& Z, const HTuple& Row, const HTuple& Col, const HTuple& NumPoints, const HPoseArray& RobotPoses, const HString& Method, const HString& QualityType, HPose* CalibrationPose, double* Quality ) const

HPose HCamPar::HandEyeCalibration( const HTuple& X, const HTuple& Y, const HTuple& Z, const HTuple& Row, const HTuple& Col, const HTuple& NumPoints, const HPoseArray& RobotPoses, const char* Method, const char* QualityType, HPose* CalibrationPose, double* Quality ) const

HPose HCamPar::HandEyeCalibration( const HTuple& X, const HTuple& Y, const HTuple& Z, const HTuple& Row, const HTuple& Col, const HTuple& NumPoints, const HPoseArray& RobotPoses, const wchar_t* Method, const wchar_t* QualityType, HPose* CalibrationPose, double* Quality ) const (Windows only)

static HPose HPose::HandEyeCalibration( const HTuple& X, const HTuple& Y, const HTuple& Z, const HTuple& Row, const HTuple& Col, const HTuple& NumPoints, const HPoseArray& RobotPoses, const HCamPar& CameraParam, const HString& Method, const HTuple& QualityType, HPose* CalibrationPose, HTuple* Quality )

static HPose HPose::HandEyeCalibration( const HTuple& X, const HTuple& Y, const HTuple& Z, const HTuple& Row, const HTuple& Col, const HTuple& NumPoints, const HPoseArray& RobotPoses, const HCamPar& CameraParam, const HString& Method, const HString& QualityType, HPose* CalibrationPose, double* Quality )

static HPose HPose::HandEyeCalibration( const HTuple& X, const HTuple& Y, const HTuple& Z, const HTuple& Row, const HTuple& Col, const HTuple& NumPoints, const HPoseArray& RobotPoses, const HCamPar& CameraParam, const char* Method, const char* QualityType, HPose* CalibrationPose, double* Quality )

static HPose HPose::HandEyeCalibration( const HTuple& X, const HTuple& Y, const HTuple& Z, const HTuple& Row, const HTuple& Col, const HTuple& NumPoints, const HPoseArray& RobotPoses, const HCamPar& CameraParam, const wchar_t* Method, const wchar_t* QualityType, HPose* CalibrationPose, double* Quality ) (Windows only)

HPose HCamPar.HandEyeCalibration( HTuple x, HTuple y, HTuple z, HTuple row, HTuple col, HTuple numPoints, HPose[] robotPoses, string method, HTuple qualityType, out HPose calibrationPose, out HTuple quality )

HPose HCamPar.HandEyeCalibration( HTuple x, HTuple y, HTuple z, HTuple row, HTuple col, HTuple numPoints, HPose[] robotPoses, string method, string qualityType, out HPose calibrationPose, out double quality )

static HPose HPose.HandEyeCalibration( HTuple x, HTuple y, HTuple z, HTuple row, HTuple col, HTuple numPoints, HPose[] robotPoses, HCamPar cameraParam, string method, HTuple qualityType, out HPose calibrationPose, out HTuple quality )

static HPose HPose.HandEyeCalibration( HTuple x, HTuple y, HTuple z, HTuple row, HTuple col, HTuple numPoints, HPose[] robotPoses, HCamPar cameraParam, string method, string qualityType, out HPose calibrationPose, out double quality )

Description๐Ÿ”—

The operator hand_eye_calibrationHandEyeCalibration determines the 3D pose of a robot (โ€œhandโ€) relative to a camera (โ€œeyeโ€). With this information, the results of image processing can be transformed into the coordinate system of the robot which can then, e.g., grasp an inspected part. Please note that the operator hand_eye_calibrationHandEyeCalibration does not support 3D sensors. A hand-eye calibration including 3D sensors is only supported by the operator calibrate_hand_eyeCalibrateHandEye. That operator furthermore provides a more user-friendly interface to the hand-eye calibration than the operator hand_eye_calibrationHandEyeCalibration, since the reference coordinate systems are explicitly indicated.

There are two possible configurations of robot-camera (hand-eye) systems: The camera can be mounted on the robot or be stationary and observe the robot. Note that the term robot is used in place for a mechanism that moves objects. Thus, you can use hand_eye_calibrationHandEyeCalibration to calibrate many different systems, from pan-tilt heads to multi-axis manipulators.

In essence, systems suitable for hand-eye calibration are described by a closed chain of four Euclidean transformations. In this chain two non-consecutive transformations are either known from the robot controller or computed from calibration points seen by a camera system. The two other constant transformations are computed by the hand-eye calibration procedure.

A hand-eye calibration is performed similarly to the calibration of the external camera parameters (see camera_calibrationCameraCalibration): You acquire a set of images of a calibration object, determine correspondences between known calibration points and their projection in the images and pass them to hand_eye_calibrationHandEyeCalibration via the parameters Xxx, Yyy, Zzz, Rowrowrow, Colcolcol, and NumPointsnumPointsnum_points. If you use the standard calibration plate, the correspondences can be determined very easily with the operators find_caltabFindCaltab and find_marks_and_poseFindMarksAndPose. Furthermore, the camera is identical for the complete calibration sequence and is specified by the internal camera parameters in CameraParamcameraParamcamera_param. The internal camera parameters are calibrated beforehand deploying the operator calibrate_camerasCalibrateCameras or camera_calibrationCameraCalibration.

In contrast to the camera calibration, the calibration object is not moved manually. This task is delegated to the robot, which either moves the camera (mounted camera) or the calibration object (stationary camera). The robotโ€™s movements are assumed to be known and therefore are also used as an input for the calibration (parameter RobotPosesrobotPosesrobot_poses).

The output of hand_eye_calibrationHandEyeCalibration are the two poses CameraPosecameraPosecamera_pose and CalibrationPosecalibrationPosecalibration_pose. Their pose type is identical to the pose type of the first input robot pose.

Basically, two hand-eye configurations can be distinguished and are discussed in more detail below, followed by general information about the process of hand-eye calibration.

Moving camera (mounted on a robot)๐Ÿ”—

In this configuration, the calibration object remains stationary and the camera is moved to different positions by the robot. The main idea behind the hand-eye calibration is that the information extracted from a calibration image, i.e., the pose of the calibration object relative to the camera (i.e., the external camera parameters), can be seen as a chain of poses or homogeneous transformation matrices, from the calibration object via the base of the robot to its tool (end-effector) and finally to the camera:

    Moving camera:     cam_H_cal = cam_H_tool * tool_H_base * base_H_cal
                                       |             |             |
                                   CameraPose     RobotPoses   CalibrationPose

From the set of calibration images, the operator hand_eye_calibrationHandEyeCalibration determines the two transformations at the ends of the chain, i.e., the pose of the robot tool in camera coordinates (\(\mvHomMatrixVar{cam}{tool}\),CameraPosecameraPosecamera_pose) and the pose of the calibration object in the robot base coordinate system (\(\mvHomMatrixVar{base}{cal}\),CalibrationPosecalibrationPosecalibration_pose).

In contrast, the transformation in the middle of the chain, \(\mvHomMatrixVar{tool}{base}\), is known but changes for each calibration image, because it describes the pose of the robot moving the camera, or to be more exact its inverse pose (pose of the base coordinate system in robot tool coordinates). You must specify the inverse robot poses in the calibration images in the parameter RobotPosesrobotPosesrobot_poses.

Note that when calibrating SCARA robots it is not possible to determine the Z translation of CalibrationPosecalibrationPosecalibration_pose. To eliminate this ambiguity the Z translation of CalibrationPosecalibrationPosecalibration_pose is internally set to 0.0 and the CameraPosecameraPosecamera_pose is calculated accordingly. It is necessary to determine the true translation in Z after the calibration (see calibrate_hand_eyeCalibrateHandEye).

Stationary camera๐Ÿ”—

In this configuration, the robot grasps the calibration object and moves it in front of the camera. Again, the information extracted from a calibration image, i.e., the pose of the calibration object in camera coordinates (the external camera parameters), are equal to a chain of poses or homogeneous transformation matrices, this time from the calibration object via the robotโ€™s tool to its base and finally to the camera:

    Stationary camera:  cam_H_cal = cam_H_base * base_H_tool * tool_H_cal
                                        |             |             |
                                    CameraPose     RobotPoses   CalibrationPose

Analogously to the configuration with a moving camera, the operator hand_eye_calibrationHandEyeCalibration determines the two transformations at the ends of the chain, here the pose of the robot base coordinate system in camera coordinates (\(\mvHomMatrixVar{cam}{base}\),CameraPosecameraPosecamera_pose) and the pose of the calibration object relative to the robot tool (\(\mvHomMatrixVar{tool}{cal}\),CalibrationPosecalibrationPosecalibration_pose).

The transformation in the middle of the chain, \(\mvHomMatrixVar{base}{tool}\), describes the pose of the robot moving the calibration object, i.e., the pose of the tool relative to the base coordinate system. You must specify the robot poses in the calibration images in the parameter RobotPosesrobotPosesrobot_poses.

Note that when calibrating SCARA robots it is not possible to determine the Z translation of CalibrationPosecalibrationPosecalibration_pose. To eliminate this ambiguity the Z translation of CalibrationPosecalibrationPosecalibration_pose is internally set to 0.0 and the CameraPosecameraPosecamera_pose is calculated accordingly. It is necessary to determine the true translation in Z after the calibration (see calibrate_hand_eyeCalibrateHandEye).

Additional information about the calibration process๐Ÿ”—

The following sections discuss individual questions arising from the use of hand_eye_calibrationHandEyeCalibration. They are intended to be a guideline for using the operator in an application, as well as to help understanding the operator.

Execution information๐Ÿ”—

Execution information
  • Multithreading type: reentrant (runs in parallel with non-exclusive operators).

  • Multithreading scope: global (may be called from any thread).

  • Processed without parallelization.

Parameters๐Ÿ”—

Xxx (input_control) number-array โ†’ (real / integer)HTuple (double / Hlong)HTuple (double / int / long)Sequence[Union[float, int]]Htuple (double / Hlong)

Linear list containing all the x coordinates of the calibration points (in the order of the images).

Yyy (input_control) number-array โ†’ (real / integer)HTuple (double / Hlong)HTuple (double / int / long)Sequence[Union[float, int]]Htuple (double / Hlong)

Linear list containing all the y coordinates of the calibration points (in the order of the images).

Zzz (input_control) number-array โ†’ (real / integer)HTuple (double / Hlong)HTuple (double / int / long)Sequence[Union[float, int]]Htuple (double / Hlong)

Linear list containing all the z coordinates of the calibration points (in the order of the images).

Rowrowrow (input_control) number-array โ†’ (real / integer)HTuple (double / Hlong)HTuple (double / int / long)Sequence[Union[float, int]]Htuple (double / Hlong)

Linear list containing all row coordinates of the calibration points (in the order of the images).

Colcolcol (input_control) number-array โ†’ (real / integer)HTuple (double / Hlong)HTuple (double / int / long)Sequence[Union[float, int]]Htuple (double / Hlong)

Linear list containing all the column coordinates of the calibration points (in the order of the images).

NumPointsnumPointsnum_points (input_control) integer-array โ†’ (integer)HTuple (Hlong)HTuple (int / long)Sequence[int]Htuple (Hlong)

Number of the calibration points for each image.

RobotPosesrobotPosesrobot_poses (input_control) pose-array โ†’ (real / integer)HTuple (double / Hlong)HPose, HTuple (double / int / long)Sequence[Union[int, float]]Htuple (double / Hlong)

Known 3D pose of the robot for each image (moving camera: robot base in robot tool coordinates; stationary camera: robot tool in robot base coordinates).

CameraParamcameraParamcamera_param (input_control) campar โ†’ (real / integer / string)HTuple (double / Hlong / HString)HCamPar, HTuple (double / int / long / string)Sequence[Union[int, float, str]]Htuple (double / Hlong / char*)

Internal camera parameters.

Methodmethodmethod (input_control) string โ†’ (string)HTuple (HString)HTuple (string)strHtuple (char*)

Method of hand-eye calibration.

Default: 'nonlinear'"nonlinear"
List of values: 'linear', 'nonlinear', 'scara_linear', 'scara_nonlinear'"linear", "nonlinear", "scara_linear", "scara_nonlinear"

QualityTypequalityTypequality_type (input_control) string(-array) โ†’ (string)HTuple (HString)HTuple (string)MaybeSequence[str]Htuple (char*)

Type of quality assessment.

Default: 'error_pose'"error_pose"
List of values: 'covariance', 'error_pose', 'standard_deviation'"covariance", "error_pose", "standard_deviation"

CameraPosecameraPosecamera_pose (output_control) pose โ†’ (real / integer)HTuple (double / Hlong)HPose, HTuple (double / int / long)Sequence[Union[int, float]]Htuple (double / Hlong)

Computed relative camera pose: 3D pose of the robot tool (moving camera) or robot base (stationary camera), respectively, in camera coordinates.

CalibrationPosecalibrationPosecalibration_pose (output_control) pose โ†’ (real / integer)HTuple (double / Hlong)HPose, HTuple (double / int / long)Sequence[Union[int, float]]Htuple (double / Hlong)

Computed 3D pose of the calibration points in robot base coordinates (moving camera) or in robot tool coordinates (stationary camera), respectively.

Qualityqualityquality (output_control) real(-array) โ†’ (real)HTuple (double)HTuple (double)Sequence[float]Htuple (double)

Quality assessment of the result.

Example๐Ÿ”—

(HDevelop)


* Note that, in order to use this code snippet, you must provide
* the camera parameters, the calibration plate description file,
* the calibration images, and the robot poses.
read_cam_par('campar.dat', CameraParam)
CalDescr := 'caltab.descr'
caltab_points(CalDescr, X, Y, Z)
* Process all calibration images.
for i := 0 to NumImages-1 by 1
  read_image(Image, 'calib_'+i$'02d')
  * Find marks on the calibration plate in every image.
  find_caltab(Image, CalPlate, CalDescr, 3, 150, 5)
  find_marks_and_pose(Image, CalPlate, CalDescr, CameraParam, 128, 10, 18, \
                      0.9, 15, 100, RCoordTmp, CCoordTmp, StartPose)
  * Accumulate 2D and 3D coordinates of the marks.
  RCoord := [RCoord, RCoordTmp]
  CCoord := [CCoord, CCoordTmp]
  XCoord := [XCoord, X]
  YCoord := [YCoord, Y]
  ZCoord := [ZCoord, Z]
  NumMarker := [NumMarker, |RCoordTmp|]
  * Read pose of the robot tool in robot base coordinates.
  read_pose('robpose_'+i$'02d'+'.dat', RobPose)
  * Moving camera? Invert pose.
  if (IsMovingCameraConfig == 'true')
    pose_to_hom_mat3d(RobPose, base_H_tool)
    hom_mat3d_invert(base_H_tool, tool_H_base)
    hom_mat3d_to_pose(tool_H_base, RobPose)
  endif
  * Accumulate robot poses.
  RobotPoses := [RobotPoses, RobPose]
endfor
*
* Perform hand-eye calibration.
*
hand_eye_calibration(XCoord, YCoord, ZCoord, RCoord, CCoord, NumMarker, \
                     RobotPoses, CameraParam, 'nonlinear', 'error_pose', \
                     CameraPose, CalibrationPose, Error)

Result๐Ÿ”—

The operator hand_eye_calibrationHandEyeCalibration returns the value 2 (H_MSG_TRUE) if the given parameters are correct. Otherwise, an exception will be raised.

Combinations with other operators๐Ÿ”—

Combinations

Possible predecessors

find_marks_and_poseFindMarksAndPose, camera_calibrationCameraCalibration, calibrate_camerasCalibrateCameras

Possible successors

write_poseWritePose, convert_pose_typeConvertPoseType, pose_to_hom_mat3dPoseToHomMat3d, disp_caltabDispCaltab, sim_caltabSimCaltab

Alternatives

calibrate_hand_eyeCalibrateHandEye

See also

find_caltabFindCaltab, find_marks_and_poseFindMarksAndPose, disp_caltabDispCaltab, sim_caltabSimCaltab, write_cam_parWriteCamPar, read_cam_parReadCamPar, create_poseCreatePose, convert_pose_typeConvertPoseType, write_poseWritePose, read_poseReadPose, pose_to_hom_mat3dPoseToHomMat3d, hom_mat3d_to_poseHomMat3dToPose, caltab_pointsCaltabPoints, gen_caltabGenCaltab, calibrate_hand_eyeCalibrateHandEye

References๐Ÿ”—

K. Daniilidis: โ€œHand-Eye Calibration Using Dual Quaternionsโ€; International Journal of Robotics Research, Vol. 18, No. 3, pp. 286-298; 1999.

M. Ulrich, C. Steger: ``Hand-Eye Calibration of SCARA Robots Using Dual Quaternionsโ€™โ€˜; Pattern Recognition and Image Analysis, Vol. 26, No. 1, pp. 231-239; January 2016.

Module๐Ÿ”—

Calibration