14 #include <mrpt/containers/yaml.h>
15 #include <mrpt/maps/CSimplePointsMap.h>
16 #include <mrpt/math/ops_containers.h>
17 #include <mrpt/obs/CObservation2DRangeScan.h>
25 const mrpt::containers::yaml& c)
52 MRPT_LOG_DEBUG_STREAM(
"Loading these params:\n" << c);
73 "Input point cloud layer '%s' was not found.",
76 const auto& pc = *pcPtr;
79 auto pc_edges = mrpt::maps::CSimplePointsMap::Create();
80 auto pc_planes = mrpt::maps::CSimplePointsMap::Create();
81 auto pc_full_decim = mrpt::maps::CSimplePointsMap::Create();
82 auto pc_plane_centroids = mrpt::maps::CSimplePointsMap::Create();
84 inOut.
layers[
"edge_points"] = pc_edges;
85 inOut.
layers[
"plane_points"] = pc_planes;
86 inOut.
layers[
"full_decim"] = pc_full_decim;
87 inOut.
layers[
"plane_centroids"] = pc_plane_centroids;
89 pc_edges->reserve(pc.size() / 10);
90 pc_planes->reserve(pc.size() / 10);
91 pc_full_decim->reserve(pc.size() / 10);
92 pc_plane_centroids->reserve(pc.size() / 1000);
97 const auto& xs = pc.getPointsBufferRef_x();
98 const auto& ys = pc.getPointsBufferRef_y();
99 const auto& zs = pc.getPointsBufferRef_z();
107 std::size_t nEdgeVoxels = 0, nPlaneVoxels = 0, nTotalVoxels = 0;
110 if (!vxl_pts.indices.empty()) nTotalVoxels++;
111 if (vxl_pts.indices.size() < 5)
continue;
114 mrpt::math::TPoint3Df mean{0, 0, 0};
115 const float inv_n = (1.0f / vxl_pts.indices.size());
116 for (
size_t i = 0; i < vxl_pts.indices.size(); i++)
118 const auto pt_idx = vxl_pts.indices[i];
119 mean.x += xs[pt_idx];
120 mean.y += ys[pt_idx];
121 mean.z += zs[pt_idx];
127 mrpt::math::CMatrixFixed<double, 3, 3> mat_a;
129 for (
size_t i = 0; i < vxl_pts.indices.size(); i++)
131 const auto pt_idx = vxl_pts.indices[i];
132 const mrpt::math::TPoint3Df a(
133 xs[pt_idx] - mean.x, ys[pt_idx] - mean.y, zs[pt_idx] - mean.z);
134 mat_a(0, 0) += a.x * a.x;
135 mat_a(1, 0) += a.x * a.y;
136 mat_a(2, 0) += a.x * a.z;
137 mat_a(1, 1) += a.y * a.y;
138 mat_a(2, 1) += a.y * a.z;
139 mat_a(2, 2) += a.z * a.z;
145 mrpt::math::CMatrixFixed<double, 3, 3> eig_vectors;
146 std::vector<double> eig_vals;
147 mat_a.eig_symmetric(eig_vectors, eig_vals);
149 const float e0 = eig_vals[0], e1 = eig_vals[1], e2 = eig_vals[2];
151 mrpt::maps::CPointsMap* dest =
nullptr;
152 if (e2 < max_e20 * e0 && e1 < max_e10 * e0)
157 dest = pc_edges.get();
159 else if (e2 > min_e20 * e0 && e1 > min_e10 * e0 && e1 > min_e1)
166 const auto pl_c = mrpt::math::TPoint3D(mean);
170 eig_vectors.extractColumn<mrpt::math::TVector3D>(0);
171 auto pl_n = mrpt::math::TVector3D(ev0.x, ev0.y, ev0.z);
178 ASSERT_GT_(pl_c.norm(), 1e-3);
179 const auto u = pl_c * (1.0 / pl_c.norm());
180 const auto dot_prod =
181 mrpt::math::dotProduct<3, double>(u, pl_n);
185 if (dot_prod > 0) pl_n = -pl_n;
189 const auto pl = mrpt::math::TPlane3D(pl_c, pl_n);
190 inOut.
planes.emplace_back(pl, pl_c);
193 pc_plane_centroids->insertPointFast(pl_c.x, pl_c.y, pl_c.z);
198 if (std::abs(ev0.z) < 0.9f) { dest = pc_planes.get(); }
202 for (
size_t i = 0; i < vxl_pts.indices.size();
205 const auto pt_idx = vxl_pts.indices[i];
206 dest->insertPointFast(xs[pt_idx], ys[pt_idx], zs[pt_idx]);
212 for (
size_t i = 0; i < vxl_pts.indices.size();
215 const auto pt_idx = vxl_pts.indices[i];
216 pc_full_decim->insertPointFast(
217 xs[pt_idx], ys[pt_idx], zs[pt_idx]);
221 MRPT_LOG_DEBUG_STREAM(
222 "[VoxelGridFilter] Voxel counts: total=" << nTotalVoxels
223 <<
" edges=" << nEdgeVoxels
224 <<
" planes=" << nPlaneVoxels);