Zivid Calibration Object
Zivid supports the following calibration objects:
Zivid Calibration Boards
ArUco Markers
The main Zivid calibration boards can be purchased at the Zivid WebShop. These boards are also used for camera maintenance with infield correction. To use the board in hand-eye calibration, both the checkerboard and ArUco marker need to be detectable in each capture.
CAD files for the boards can be downloaded from Accessories Downloads.
Pose Detection
The pose returned by the checkerboard detection has its origin at the top left inner corner of the checkerboard, with the axes oriented as shown below.
To estimate the pose, detect the checkerboard and read the pose from the detection result.
std::cout << "Detecting and estimating pose of the Zivid checkerboard in the camera frame" << std::endl;
const auto detectionResult = Zivid::Calibration::detectCalibrationBoard(frame);
if(!detectionResult.valid())
{
throw std::runtime_error("No checkerboard detected. " + detectionResult.statusDescription());
}
const auto cameraToCheckerboardTransform = detectionResult.pose().toMatrix();
Console.WriteLine("Detecting and estimating pose of the Zivid checkerboard in the camera frame");
var detectionResult = Detector.DetectCalibrationBoard(frame);
var cameraToCheckerboardTransform = new Zivid.NET.Matrix4x4(detectionResult.Pose().ToMatrix());
print("Detecting and estimating pose of the Zivid checkerboard in the camera frame")
detection_result = zivid.calibration.detect_calibration_board(frame)
if not detection_result.valid():
raise RuntimeError(f"No Checkerboard detected. {detection_result.status_description()}")
camera_to_checkerboard_transform = detection_result.pose().to_matrix()
The image above was created by projecting the pose onto the 2D image and drawing the coordinate system axes.
std::cout << "Converting to OpenCV image format" << std::endl;
const auto bgraImage = pointCloudToColorBGRA_SRGB(pointCloud);
std::cout << "Visualizing checkerboard with coordinate system" << std::endl;
cv::Mat bgrCoordinateSystem;
cv::cvtColor(bgraImage, bgrCoordinateSystem, cv::COLOR_BGRA2BGR);
drawCoordinateSystem(frame, cameraToCheckerboardTransform, bgrCoordinateSystem);
displayBGR(bgrCoordinateSystem, "Checkerboard transformation frame");
print("Converting to OpenCV image format")
bgra_image = point_cloud.copy_data("bgra_srgb")
print("Visualizing checkerboard with coordinate system")
bgr_coordinate_system = bgra_image[:, :, 0:3].copy()
_draw_coordinate_system(frame, camera_to_checkerboard_transform, bgr_coordinate_system)
display_bgr(bgr_coordinate_system, "Checkerboard transformation frame")
For the full example, see Transform via Checkerboard.
Zivid hand-eye calibration also works with one or several ArUco markers as calibration objects. In general, the more markers are used, the better. You can generate and print ArUco markers at https://chev.me/arucogen/. Make sure that the markers are printed on a flat surface. The OpenCV dictionaries that we support are 4x4, 5x5, 6x6, and 7x7. One benefit of using ArUco markers for hand-eye calibration is that they are small. Another is that not all markers need to be detectable in each capture.
Pose Detection
The pose returned by the ArUco marker detection has its origin at the center of the marker. Its z-axis points perpendicularly into the face of the marker, as shown below.
To estimate the pose, detect the marker and read the pose from the detected marker.
std::cout << "Detecting ArUco marker" << std::endl;
const auto detectionResult = Zivid::Calibration::detectMarkers(frame, markerId, markerDictionary);
std::cout << "Estimating pose of detected ArUco marker" << std::endl;
const auto cameraToMarkerTransform = detectionResult.detectedMarkers()[0].pose().toMatrix();
The image above was created by projecting the pose onto the 2D image and drawing the coordinate system axes.
std::cout << "Converting to OpenCV image format" << std::endl;
const auto bgraImage = pointCloudToColorBGRA_SRGB(pointCloud);
std::cout << "Visualizing ArUco marker with coordinate system" << std::endl;
cv::Mat bgrCoordinateSystem;
cv::cvtColor(bgraImage, bgrCoordinateSystem, cv::COLOR_BGRA2BGR);
drawCoordinateSystem(frame, cameraToMarkerTransform, bgrCoordinateSystem);
displayBGR(bgrCoordinateSystem, "ArUco marker transformation frame");
print("Converting to OpenCV image format")
bgra_image = point_cloud.copy_data("bgra_srgb")
print("Visualizing ArUco marker with coordinate system")
bgr_coordinate_system = bgra_image[:, :, 0:3].copy()
_draw_coordinate_system(frame, camera_to_marker_transform, bgr_coordinate_system)
display_bgr(bgr_coordinate_system, "ArUco marker transformation frame")
For the full example, see Transform via ArUco marker.
How large does the ArUco marker need to be?
We recommend having at least 7 pixels per ArUco bit side at the furthest imaging distance. The image below shows a zoomed-in image of an ArUco marker where each ArUco bit is represented by 8 pixels. How you can figure out the minimum needed size in mm is explained in the following example.
For a 4x4 ArUco dictionary, there are 6 bits (4 inner bits and 2 outer bits), so you should aim for a minimum of 42 pixels per marker side.
Let us assume that you are using the Zivid 2+ M130 camera at a maximum imaging distance of 2 meters. The spatial resolution for this camera and distance is 0.5 mm (see Calculate FOV and Imaging Distance). Multiplying 0.5 mm by 42 pixels gives us 21 mm.
Therefore, to use the Zivid 2+ M130 at a distance of up to 2 meters, your ArUco marker should be at least 21 mm in size.
Note
You should leave some white space around your ArUco marker, with at least 1 bit of border. For the example above, this means 3.5 mm on each side (7 pixels multiplied by 0.5 mm).
Which Calibration Object to use?
We recommend using the Zivid calibration board whenever possible. Choose the board model based on the camera model you are using, as shown in the table below:
Camera Model |
Recommended Board |
|---|---|
Zivid 2 M70 |
7x8 - 30 mm |
Zivid 2 L100 |
7x8 - 30 mm |
Zivid 2+ MR130 |
7x8 - 30 mm |
Zivid 2+ LR110 |
7x8 - 30 mm |
Zivid 2+ MR60 |
5x6 - 20 mm |
Zivid 3 XL250 |
7x8 - 30 mm |
Use ArUco markers for the following use case:
Eye-to-hand configuration
Calibration object needs to be permanently mounted on the robot
Zivid calibration board is too large
Now that you have selected the calibration object, check How to run and integrate Zivid Hand-Eye Calibration.
Version History
SDK |
Changes |
|---|---|
2.16.0 |
Added support for a smaller calibration board, ZVDA-CB02 (5x6 20 mm). |
2.14.0 |
Removed support for 9x6 grey-white checkerboards. |
2.13.0 |
Added support for ArUco markers. |