CVBpy 15.0
All Classes Namespaces Functions Variables Enumerations Enumerator Properties Modules Pages
foundation/MetricCalibrationRigidBodyTransformation
1# @brief Example for a **rigid-body transformation** (extrinsic calibration)
2# using the AQS12 target.
3
4"""
5CVBpy Example Script for AQS12 Calibration - Use Case 3.
6
7This example shows how to bring an intrinsically calibrated point cloud to
8a world coordinate system via a rigid body transformation.
9This workflow is recommended for area 3D compact sensors.
10
11See also use case 3 described in the CVB Metric documentation:
12https://help.commonvisionblox.com/NextGen/15.0/md_theory_of_operation_tools__metric.html#calibration_setup
13
14The rigid body transformation solely inlcudes rotation and translation.
15"""
16
17import os
18
19import cvb
20import cvb.foundation
21
22
23def print_trafo(trafo: cvb.AffineMatrix3D) -> None:
24 print("Estimated transformation:")
25 print("Translation:")
26 print(f"[{trafo.translation.x}, {trafo.translation.y}, "
27 f"{trafo.translation.z}]")
28 print("Transformation matrix:")
29 print(f"[[{trafo.matrix.at(0, 0)}, "
30 f"{trafo.matrix.at(0, 1)}, "
31 f"{trafo.matrix.at(0, 2)}],")
32 print(f"[{trafo.matrix.at(1, 0)}, "
33 f"{trafo.matrix.at(1, 1)}, "
34 f"{trafo.matrix.at(1, 2)}],")
35 print(f"[{trafo.matrix.at(2, 0)}, "
36 f"{trafo.matrix.at(2, 1)}, "
37 f"{trafo.matrix.at(2, 2)}]]")
38
39
40def print_trafo_parameters(atp: cvb.AffineTransformationParameters) -> None:
41 print("Rotation angles about X, Y, Z axis in degrees:")
42 print(f"{atp.rotation_angles.x}, {atp.rotation_angles.y}, "
43 f"{atp.rotation_angles.z}")
44 print("Shear Syx, Syz:")
45 print(f"{atp.s_yx}, {atp.s_yz}")
46 print("Inclination of laser plane about X, Z axis in degrees:")
47 print(f"{atp.inclination_x}, {atp.inclination_z}")
48 print("Scale in X, Y, Z:")
49 print(f"{atp.scale.x}, {atp.scale.y}, {atp.scale.z}")
50
51
52def print_point_3d_list(points: list[cvb.Point3D]) -> None:
53 data_list = list()
54 for p in points:
55 data_list.append(f"[{p.x}, {p.y}, {p.z}]")
56 delimiter = ",\n"
57 print(f"[{delimiter.join(data_list)}]")
58
59
60def print_residuals(points: list[cvb.Point3D]) -> None:
61 print("Residuals:")
62 print_point_3d_list(points)
63
64
65def print_extrinsic_matrix(matrix: cvb.AffineMatrix3D) -> None:
66 rotation = matrix.matrix.rotation_angles
67 print("Transformation results:")
68 print("Rotation about x, y, and z in degrees:")
69 print(f"{rotation[0]}, {rotation[1]}, {rotation[2]}")
70 print("Translation about x, y, and z in millimeters:")
71 print(f"{matrix.translation.x}, {matrix.translation.y}, "
72 f"{matrix.translation.z}")
73
74
75def create_aqs12():
76 # list of known point coordinates of the AQS12
77 points = [
78 cvb.Point3D(20.0018, 44.9941, 15.0000),
79 cvb.Point3D(24.0018, 39.9942, 14.9994),
80 cvb.Point3D(23.9994, 24.9972, 15.0001),
81 cvb.Point3D(20.0021, 20.0035, 15.0011),
82 cvb.Point3D(15.9994, 25.0079, 15.0016),
83 cvb.Point3D(16.0000, 39.9919, 15.0010),
84 cvb.Point3D(20.0095, 59.9985, 4.9902),
85 cvb.Point3D(32.0093, 44.9958, 4.9909),
86 cvb.Point3D(32.0052, 19.9925, 4.9920),
87 cvb.Point3D(20.0021, 4.9961, 4.9939),
88 cvb.Point3D(8.0024, 19.9980, 5.0009),
89 cvb.Point3D(8.0065, 45.0009, 4.9984)]
90 return cvb.foundation.AQS12Piece(points, 0)
91
92
93# If you like to save the calibrated point cloud, turn this flag on:
94save = False
95
96print("Estimation of a rigid body transformation (rotation and translation)")
97
98# load range map of the calibration target AQS12
99print("Loading range map and calibration file.")
100range_map_file = os.path.join(
101 os.path.join(cvb.install_path(), "tutorial", "Metric", "Images",
102 "RangeMapCalibrationPattern.tif"))
103
104range_map = cvb.Image(range_map_file)
105
106print(f"Range map loaded with size of {range_map.width} x {range_map.height} "
107 f"from {range_map_file}.")
108
109# create AQS12 object with known reference coordinates of corner points
110aqs12 = create_aqs12()
111
112# create (intrinsically) calibrated dense point cloud
113calibrator_file = os.path.join(
114 cvb.install_path(), "tutorial", "Metric", "Images", "SICalibration.json")
115calibrator = cvb.Calibrator3D.load(calibrator_file)
116calibrator.range_map_ignore_value = 0.
117cloud_intrinsic = cvb.PointCloudFactory.create_dense(
118 range_map.planes[0], calibrator,
119 cvb.PointCloudFlags.Float | cvb.PointCloudFlags.XYZConfidence)
120
121print("Dense point cloud created from range map and calibration file "
122 f"with {cloud_intrinsic.num_points} points.")
123
124# create segmentor (segmenting AQS12 faces on dense point cloud)
126 cvb.foundation.SegmentationMethod.KmeansClustering)
127
128# estimate calibration parameters
129print("Estimating a rigid-body transformation.")
130transformation_, residuals_, transformation_parameters_ = \
132 cloud_intrinsic, segmentor, aqs12)
133calibrator.extrinsic_matrix = transformation_
134
135# show results
136if transformation_:
137 print_trafo(transformation_)
138
139if transformation_parameters_:
140 print_trafo_parameters(transformation_parameters_)
141
142if residuals_:
143 print_residuals(residuals_)
144
145print_extrinsic_matrix(calibrator.extrinsic_matrix)
146
147# create calibrated point cloud
148print("Creating calibrated point cloud.")
150 range_map.planes[0], calibrator,
151 cvb.PointCloudFlags.Float | cvb.PointCloudFlags.XYZConfidence)
152
153if save:
154 cloud.save("cloud.ply")
Union[cvb.Calibrator3DAT, cvb.LaserPlaneHomographyCalibrator3D, cvb.LaserPlaneZigZagCalibrator3D, cvb.FactorsCalibrator3D, cvb.MatrixCalibrator3D, cvb.PinholeCameraCalibrator3D] load(str file_name)
Loads a 3D calibration from file.
Definition: __init__.py:671
The Common Vision Blox image.
Definition: __init__.py:2097
Multi-purpose 3D vector class.
Definition: __init__.py:4322
Union[cvb.PointCloud, cvb.DensePointCloud, cvb.SparsePointCloud] create(cvb.ImagePlane range_map, cvb.Calibrator3D calibrator, int flags, Union[Type[cvb.PointCloud|cvb.DensePointCloud|cvb.SparsePointCloud]] point_cloud_type=DensePointCloud)
Creates a new Cartesian 3D point cloud from the given 2.5D range map image.
Definition: __init__.py:4701
cvb.DensePointCloud create_dense(cvb.ImagePlane range_map, cvb.Calibrator3D calibrator, int flags)
Creates a new dense Cartesian 3D point cloud from the given 2.5D range map image.
Definition: __init__.py:4732
cvb.foundation.AQS12DensePointCloudSegmentor create(int method)
Creates an AQS12 segmentor for dense point clouds based on given segmentation method.
Definition: __init__.py:18
Object to collect all input parameters for the AQS12 calibration piece.
Definition: __init__.py:76
Common Vision Blox Foundation module for Python.
Definition: __init__.py:1
Tuple[cvb.AffineMatrix3D, Optional[List[cvb.Point3D]], cvb.AffineTransformationParameters] calculate_rigid_body_transformation_from_aqs12_piece(cvb.DensePointCloud cloud, cvb.foundation.AQS12DensePointCloudSegmentor segmentor, cvb.foundation.AQS12Piece aqs12, Optional[cvb.Rect] aoi=None)
Calculates a rigid body transformation from a given dense cloud of an AQS12 calibration piece.
Definition: __init__.py:2320
str install_path()
Directory Common Vision Blox has been installed to.
Definition: __init__.py:8318