14 #include <mrpt/containers/yaml.h>
15 #include <mrpt/maps/CSimplePointsMap.h>
16 #include <mrpt/math/ops_containers.h>
24 const mrpt::containers::yaml& c)
44 MRPT_LOG_DEBUG_STREAM(
"Loading these params:\n" << c);
60 "Input point cloud layer '%s' was not found.",
63 const auto& pc = *pcPtr;
66 auto pc_edges = mrpt::maps::CSimplePointsMap::Create();
67 auto pc_planes = mrpt::maps::CSimplePointsMap::Create();
68 auto pc_full_decim = mrpt::maps::CSimplePointsMap::Create();
69 auto pc_plane_centroids = mrpt::maps::CSimplePointsMap::Create();
71 inOut.
layers[
"edge_points"] = pc_edges;
72 inOut.
layers[
"plane_points"] = pc_planes;
73 inOut.
layers[
"full_decim"] = pc_full_decim;
74 inOut.
layers[
"plane_centroids"] = pc_plane_centroids;
76 pc_edges->reserve(pc.size() / 10);
77 pc_planes->reserve(pc.size() / 10);
78 pc_full_decim->reserve(pc.size() / 10);
79 pc_plane_centroids->reserve(pc.size() / 1000);
84 const auto& xs = pc.getPointsBufferRef_x();
85 const auto& ys = pc.getPointsBufferRef_y();
86 const auto& zs = pc.getPointsBufferRef_z();
94 std::size_t nEdgeVoxels = 0, nPlaneVoxels = 0, nTotalVoxels = 0;
100 if (!vxl.
indices.empty()) nTotalVoxels++;
101 if (vxl.
indices.size() < 5)
return;
104 mrpt::math::TPoint3Df mean{0, 0, 0};
105 const float inv_n = (1.0f / vxl.
indices.size());
106 for (
size_t i = 0; i < vxl.
indices.size(); i++)
108 const auto pt_idx = vxl.
indices[i];
109 mean.x += xs[pt_idx];
110 mean.y += ys[pt_idx];
111 mean.z += zs[pt_idx];
117 mrpt::math::CMatrixFixed<double, 3, 3> mat_a;
119 for (
size_t i = 0; i < vxl.
indices.size(); i++)
121 const auto pt_idx = vxl.
indices[i];
122 const mrpt::math::TPoint3Df a(
123 xs[pt_idx] - mean.x, ys[pt_idx] - mean.y,
124 zs[pt_idx] - mean.z);
125 mat_a(0, 0) += a.x * a.x;
126 mat_a(1, 0) += a.x * a.y;
127 mat_a(2, 0) += a.x * a.z;
128 mat_a(1, 1) += a.y * a.y;
129 mat_a(2, 1) += a.y * a.z;
130 mat_a(2, 2) += a.z * a.z;
136 mrpt::math::CMatrixFixed<double, 3, 3> eig_vectors;
137 std::vector<double> eig_vals;
138 mat_a.eig_symmetric(eig_vectors, eig_vals);
140 const float e0 = eig_vals[0], e1 = eig_vals[1], e2 = eig_vals[2];
142 mrpt::maps::CPointsMap* dest =
nullptr;
143 if (e2 < max_e20 * e0 && e1 < max_e10 * e0)
148 dest = pc_edges.get();
150 else if (e2 > min_e20 * e0 && e1 > min_e10 * e0 && e1 > min_e1)
157 const auto pl_c = mrpt::math::TPoint3D(mean);
161 eig_vectors.extractColumn<mrpt::math::TVector3D>(0);
162 auto pl_n = mrpt::math::TVector3D(ev0.x, ev0.y, ev0.z);
169 ASSERT_GT_(pl_c.norm(), 1e-3);
170 const auto u = pl_c * (1.0 / pl_c.norm());
171 const auto dot_prod =
172 mrpt::math::dotProduct<3, double>(u, pl_n);
176 if (dot_prod > 0) pl_n = -pl_n;
180 const auto pl = mrpt::math::TPlane3D(pl_c, pl_n);
181 inOut.
planes.emplace_back(pl, pl_c);
184 pc_plane_centroids->insertPointFast(pl_c.x, pl_c.y, pl_c.z);
189 if (std::abs(ev0.z) < 0.9f) { dest = pc_planes.get(); }
193 for (
size_t i = 0; i < vxl.
indices.size();
196 const auto pt_idx = vxl.
indices[i];
197 dest->insertPointFast(xs[pt_idx], ys[pt_idx], zs[pt_idx]);
203 for (
size_t i = 0; i < vxl.
indices.size();
206 const auto pt_idx = vxl.
indices[i];
207 pc_full_decim->insertPointFast(
208 xs[pt_idx], ys[pt_idx], zs[pt_idx]);
213 MRPT_LOG_DEBUG_STREAM(
214 "[VoxelGridFilter] Voxel counts: total=" << nTotalVoxels
215 <<
" edges=" << nEdgeVoxels
216 <<
" planes=" << nPlaneVoxels);