CVBpy 15.0
All Classes Namespaces Functions Variables Enumerations Enumerator Properties Modules Pages
foundation/MetricCalibrationInclinationLaserPlane
1# @brief Example for **extrinsic calibration**, including the
2# **correction of an inclined laser plane**,
3# in a laser triangulation system using the AQS12 target.
4
5"""
6CVBpy Example Script for AQS12 Calibration - Use Case 2.
7
8This example shows how to calibrate range maps acquired by a compact 3D
9sensor where the intrinsic calibration parameters are given, but the
10laser plane is not exactly vertical to the direction of movement.
11
12See also use case 2 described in the CVB Metric documentation:
13https://help.commonvisionblox.com/NextGen/15.0/md_theory_of_operation_tools__metric.html#calibration_setup
14
15This example program estimates an affine transformation.
16The affine transformation:
17- corrects errors induced by an incline laser plane
18- corrects scaling in x, y, z
19- moves the point cloud to the coordinate system given by the reference
20points of the AQS12
21"""
22
23import os
24
25import cvb
26import cvb.foundation
27
28
29def print_trafo(trafo: cvb.AffineMatrix3D) -> None:
30 print("Estimated transformation:")
31 print("Translation:")
32 print(f"[{trafo.translation.x}, {trafo.translation.y}, "
33 f"{trafo.translation.z}]")
34 print("Transformation matrix:")
35 print(f"[[{trafo.matrix.at(0, 0)}, "
36 f"{trafo.matrix.at(0, 1)}, "
37 f"{trafo.matrix.at(0, 2)}],")
38 print(f"[{trafo.matrix.at(1, 0)}, "
39 f"{trafo.matrix.at(1, 1)}, "
40 f"{trafo.matrix.at(1, 2)}],")
41 print(f"[{trafo.matrix.at(2, 0)}, "
42 f"{trafo.matrix.at(2, 1)}, "
43 f"{trafo.matrix.at(2, 2)}]]")
44
45
46def print_trafo_parameters(atp: cvb.AffineTransformationParameters) -> None:
47 print("Rotation angles about X, Y, Z axis in degrees:")
48 print(f"{atp.rotation_angles.x}, {atp.rotation_angles.y}, "
49 f"{atp.rotation_angles.z}")
50 print("Shear Syx, Syz:")
51 print(f"{atp.s_yx}, {atp.s_yz}")
52 print("Inclination of laser plane about X, Z axis in degrees:")
53 print(f"{atp.inclination_x}, {atp.inclination_z}")
54 print("Scale in X, Y, Z:")
55 print(f"{atp.scale.x}, {atp.scale.y}, {atp.scale.z}")
56
57
58def print_point_3d_list(points: list[cvb.Point3D]) -> None:
59 data_list = list()
60 for p in points:
61 data_list.append(f"[{p.x}, {p.y}, {p.z}]")
62 delimiter = ",\n"
63 print(f"[{delimiter.join(data_list)}]")
64
65
66def print_residuals(points: list[cvb.Point3D]) -> None:
67 print("Residuals:")
68 print_point_3d_list(points)
69
70
71def print_aqs12_points(points: list[cvb.Point3D]) -> None:
72 print("AQS12 points:")
73 print_point_3d_list(points)
74
75
76def create_aqs12():
77 # list of known point coordinates of the AQS12
78 points = [
79 cvb.Point3D(20.0018, 44.9941, 15.0000),
80 cvb.Point3D(24.0018, 39.9942, 14.9994),
81 cvb.Point3D(23.9994, 24.9972, 15.0001),
82 cvb.Point3D(20.0021, 20.0035, 15.0011),
83 cvb.Point3D(15.9994, 25.0079, 15.0016),
84 cvb.Point3D(16.0000, 39.9919, 15.0010),
85 cvb.Point3D(20.0095, 59.9985, 4.9902),
86 cvb.Point3D(32.0093, 44.9958, 4.9909),
87 cvb.Point3D(32.0052, 19.9925, 4.9920),
88 cvb.Point3D(20.0021, 4.9961, 4.9939),
89 cvb.Point3D(8.0024, 19.9980, 5.0009),
90 cvb.Point3D(8.0065, 45.0009, 4.9984)]
91 return cvb.foundation.AQS12Piece(points, 0)
92
93
94def check_accuracy(residuals, desired_accuracy):
95 for point in residuals:
96 if (abs(point.x) > desired_accuracy or
97 abs(point.y) > desired_accuracy or
98 abs(point.z) > desired_accuracy):
99 return False
100 return True
101
102
103# If you like to save intermediate and final results, turn this flag on:
104save = False
105
106print("Estimation of an affine transformation (correcting an inclined laser "
107 "plane)")
108
109# load range map of the calibration target AQS12
110print("Loading range map and calibration file.")
111range_map_file = os.path.join(cvb.install_path(),
112 "tutorial", "Metric", "Images",
113 "RangeMapCalibrationPattern.tif")
114
115range_map = cvb.Image(range_map_file)
116
117print(f"Range map loaded with size of {range_map.width} x {range_map.height} "
118 f"from {range_map_file}.")
119
120# create calibration configuration object
121aqs12 = create_aqs12()
123config.is_homography_calculated = False
124
125# create (intrinsically) calibrated dense point cloud
126calibrator_file = os.path.join(cvb.install_path(),
127 "tutorial", "Metric", "Images",
128 "SICalibration.json")
129calibrator = cvb.Calibrator3D.load(calibrator_file)
130calibrator.range_map_ignore_value = 0
131cloud_intrinsic = cvb.PointCloudFactory.create_dense(
132 range_map.planes[0], calibrator,
133 cvb.PointCloudFlags.Float)
134
135print("Dense point cloud created from range map and calibration file "
136 f"with {cloud_intrinsic.num_points} points.")
137
138# create AQS12 object with known reference coordinates of corner points
139aqs12 = create_aqs12()
140
141# create segmentor (segmenting AQS12 faces on dense point cloud)
143 cvb.foundation.SegmentationMethod.KmeansClustering)
144
145# estimate calibration parameters
146print("Estimating affine transformation.")
147transformation_, residuals_, transformation_parameters_ = \
149 cloud_intrinsic, segmentor, config)
150
151calibrator.correction_of_laser_plane_inclination = \
152 transformation_, transformation_parameters_
153
154# show results
155if transformation_:
156 print_trafo(transformation_)
157
158if transformation_parameters_:
159 print_trafo_parameters(transformation_parameters_)
160
161# check residuals
162desired_accuracy_ = 0.05 # mm
163if residuals_:
164 print_residuals(residuals_)
165 if check_accuracy(residuals_, desired_accuracy_):
166 print("The calibration was successful and accuracy is < "
167 f"{desired_accuracy_} mm.")
168
169 # create calibrated cloud
170 print("Creating calibrated point cloud.")
171 calibrator_cloud = cvb.PointCloudFactory.create(
172 range_map.planes[0], calibrator,
173 cvb.PointCloudFlags.Float | cvb.PointCloudFlags.XYZConfidence)
174
175 # save calibrated point cloud
176 if save:
177 calibrator_cloud.save("cloud.ply")
178 else:
179 print(
180 "Results do not have desired accuracy. Check face segmentation and "
181 "extracted AQS12 points...")
182
183 # segment AQS12 faces map
184 print("Extracting AQ12 faces on intrinsically calibrated point cloud.")
185 faces_aqs12 = segmentor.face_segmentation_from_piece(cloud_intrinsic)
186
187 # save image with segmented faces:
188 if save:
189 faces_aqs12.save("AQS12faces.bmp")
190
191 # extract AQS12 points on range map (might take some time...)
192 print("Extracting AQ12 corner points on intrinsically calibrated "
193 "point cloud.")
194 points_aqs12 = segmentor.extract_projected_points_from_piece(
195 cloud_intrinsic)
196 print_aqs12_points(points_aqs12)
197
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
cvb.foundation.CalibrationConfiguration create(cvb.foundation.AQS12Piece aqs12)
Creates a calibration configuration object.
Definition: __init__.py:272
Common Vision Blox Foundation module for Python.
Definition: __init__.py:1
Tuple[cvb.AffineMatrix3D, Optional[List[cvb.Point3D]], Optional[cvb.AffineTransformationParameters]] calculate_correction_of_laser_plane_inclination_from_aqs12_piece(cvb.DensePointCloud cloud, cvb.foundation.AQS12DensePointCloudSegmentor segmentor, cvb.foundation.CalibrationConfiguration config, Optional[cvb.Rect] aoi=None)
Calculates an extrinsic calibration and the correction for the laser plane inclination (affine transf...
Definition: __init__.py:2212
str install_path()
Directory Common Vision Blox has been installed to.
Definition: __init__.py:8318