9 from pypointmatcher
import pointmatcher
as pm, pointmatchersupport
as pms
10 from utils
import parse_translation, parse_rotation
14 Parameters = pms.Parametrizable.Parameters
21 is_transfo_saved =
False
27 config_file =
"../data/default.yaml"
32 output_base_directory =
"tests/icp_advance_api/"
35 output_base_file =
"test"
42 init_translation =
"0,0,0" if is_3D
else "0,0"
45 init_rotation =
"1,0,0;0,1,0;0,0,1" if is_3D
else "1,0;0,1"
49 ref = DP.load(
'../data/car_cloud400.csv')
50 data = DP.load(
'../data/car_cloud401.csv')
54 ref = DP.load(
'../data/2D_twoBoxes.csv')
55 data = DP.load(
'../data/2D_oneBox.csv')
61 if len(config_file) == 0:
66 icp.loadFromYaml(config_file)
68 cloud_dimension = ref.getEuclideanDim()
70 assert cloud_dimension == 2
or cloud_dimension == 3,
"Invalid input point clouds dimension"
76 init_transfo = np.matmul(translation, rotation)
78 rigid_trans = PM.get().TransformationRegistrar.create(
"RigidTransformation")
80 if not rigid_trans.checkParameters(init_transfo):
81 print(
"Initial transformations is not rigid, identiy will be used")
82 init_transfo = np.identity(cloud_dimension + 1)
84 initialized_data = rigid_trans.compute(data, init_transfo)
87 T =
icp(initialized_data, ref)
88 match_ratio = icp.errorMinimizer.getWeightedPointUsedRatio()
89 print(f
"match ratio: {match_ratio:.6}")
92 data_out =
DP(initialized_data)
93 icp.transformations.apply(data_out, T)
95 print(
"\n------------------")
106 params = Parameters()
109 params[
"epsilon"] =
"0"
110 matcher_Hausdorff = PM.get().MatcherRegistrar.create(
"KDTreeMatcher", params)
113 matcher_Hausdorff.init(ref)
114 matches = matcher_Hausdorff.findClosests(data_out)
115 max_dist1 = matches.getDistsQuantile(1.0)
116 max_dist_robust1 = matches.getDistsQuantile(0.85)
119 matcher_Hausdorff.init(data_out)
120 matches = matcher_Hausdorff.findClosests(ref)
121 max_dist2 = matches.getDistsQuantile(1.0)
122 max_dist_robust2 = matches.getDistsQuantile(0.85)
124 haussdorff_dist = max(max_dist1, max_dist2)
125 haussdorff_quantile_dist = max(max_dist_robust1, max_dist_robust2)
127 print(f
"Haussdorff distance: {sqrt(haussdorff_dist):.6} m")
128 print(f
"Haussdorff quantile distance: {sqrt(haussdorff_quantile_dist):.6} m")
140 icp.matcher.init(ref)
143 matches = icp.matcher.findClosests(data_out)
146 outlier_weights = icp.outlierFilters.compute(data_out, ref, matches)
149 matched_points = PM.ErrorMinimizer.ErrorElements(data_out, ref, outlier_weights, matches)
152 dim = matched_points.reading.getEuclideanDim()
153 nb_matched_points = matched_points.reading.getNbPoints()
154 matched_read = matched_points.reading.features[:dim]
155 matched_ref = matched_points.reference.features[:dim]
158 dist = np.linalg.norm(matched_read - matched_ref, axis=0)
159 mean_dist = dist.sum() / nb_matched_points
160 print(f
"Robust mean distance: {mean_dist:.6} m")
164 print(
"------------------\n")
167 ref.save(f
"{output_base_directory + test_base}_{output_base_file}_ref.vtk")
168 data.save(f
"{output_base_directory + test_base}_{output_base_file}_data_in.vtk")
169 data_out.save(f
"{output_base_directory + test_base}_{output_base_file}_data_out.vtk")
172 init_file_name = f
"{output_base_directory + test_base}_{output_base_file}_init_transfo.txt"
173 icp_file_name = f
"{output_base_directory + test_base}_{output_base_file}_icp.transfo.txt"
174 complete_file_name = f
"{output_base_directory + test_base}_{output_base_file}_complete_transfo.txt"
176 with open(init_file_name,
"w")
as f:
177 f.write(f
"{init_transfo}".replace(
"[",
" ").replace(
"]",
" "))
179 with open(icp_file_name,
"w")
as f:
180 f.write(f
"{T}".replace(
"[",
" ").replace(
"]",
" "))
182 with open(complete_file_name,
"w")
as f:
183 f.write(f
"{np.matmul(T, init_transfo)}".replace(
"[",
" ").replace(
"]",
" "))
187 print(f
"{test_base} ICP transformation:\n{T}".replace(
"[",
" ").replace(
"]",
" "))