40 #ifndef PCL_SEGMENTATION_IMPL_ORGANIZED_MULTI_PLANE_SEGMENTATION_H_
41 #define PCL_SEGMENTATION_IMPL_ORGANIZED_MULTI_PLANE_SEGMENTATION_H_
47 #include <boost/make_shared.hpp>
50 Eigen::Vector3f
linePlaneIntersection (Eigen::Vector3f& p1, Eigen::Vector3f& p2, Eigen::Vector3f& norm, Eigen::Vector3f& p3)
52 float u = norm.dot ((p3 - p1)) / norm.dot ((p2 - p1));
53 Eigen::Vector3f intersection (p1 + u * (p2 - p1));
54 return (intersection);
61 Eigen::Vector3f norm (normal[0], normal[1], normal[2]);
64 for (
size_t i = 0; i < cloud.
points.size (); i++)
68 projected_cloud[i].x = intersection[0];
69 projected_cloud[i].y = intersection[1];
70 projected_cloud[i].z = intersection[2];
73 return (projected_cloud);
77 template<
typename Po
intT,
typename Po
intNT,
typename Po
intLT>
void
79 std::vector<PointIndices>& inlier_indices)
82 std::vector<pcl::PointIndices> label_indices;
83 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > centroids;
84 std::vector <Eigen::Matrix3f, Eigen::aligned_allocator<Eigen::Matrix3f> > covariances;
85 segment (model_coefficients, inlier_indices, centroids, covariances, labels, label_indices);
89 template<
typename Po
intT,
typename Po
intNT,
typename Po
intLT>
void
91 std::vector<PointIndices>& inlier_indices,
92 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >& centroids,
93 std::vector <Eigen::Matrix3f, Eigen::aligned_allocator<Eigen::Matrix3f> >& covariances,
95 std::vector<pcl::PointIndices>& label_indices)
101 if (static_cast<int> (normals_->points.size ()) != static_cast<int> (input_->points.size ()))
103 PCL_ERROR (
"[pcl::%s::segment] Number of points in input cloud (%zu) and normal cloud (%zu) do not match!\n",
104 getClassName ().c_str (), input_->points.size (),
105 normals_->points.size ());
110 if (!input_->isOrganized ())
112 PCL_ERROR (
"[pcl::%s::segment] Organized point cloud is required for this plane extraction method!\n",
113 getClassName ().c_str ());
118 std::vector<float> plane_d (input_->points.size ());
120 for (
unsigned int i = 0; i < input_->size (); ++i)
121 plane_d[i] = input_->points[i].getVector3fMap ().dot (normals_->points[i].getNormalVector3fMap ());
125 compare_->setPlaneCoeffD (plane_d);
126 compare_->setInputCloud (input_);
127 compare_->setInputNormals (normals_);
128 compare_->setAngularThreshold (static_cast<float> (angular_threshold_));
129 compare_->setDistanceThreshold (static_cast<float> (distance_threshold_),
true);
134 connected_component.
segment (labels, label_indices);
136 Eigen::Vector4f clust_centroid = Eigen::Vector4f::Zero ();
137 Eigen::Vector4f vp = Eigen::Vector4f::Zero ();
138 Eigen::Matrix3f clust_cov;
143 for (
size_t i = 0; i < label_indices.size (); i++)
145 if (static_cast<unsigned> (label_indices[i].indices.size ()) > min_inliers_)
148 Eigen::Vector4f plane_params;
153 plane_params[0] = eigen_vector[0];
154 plane_params[1] = eigen_vector[1];
155 plane_params[2] = eigen_vector[2];
157 plane_params[3] = -1 * plane_params.dot (clust_centroid);
159 vp -= clust_centroid;
160 float cos_theta = vp.dot (plane_params);
165 plane_params[3] = -1 * plane_params.dot (clust_centroid);
170 float eig_sum = clust_cov.coeff (0) + clust_cov.coeff (4) + clust_cov.coeff (8);
172 curvature = fabsf (eigen_value / eig_sum);
176 if (curvature < maximum_curvature_)
178 model.
values[0] = plane_params[0];
179 model.
values[1] = plane_params[1];
180 model.
values[2] = plane_params[2];
181 model.
values[3] = plane_params[3];
182 model_coefficients.push_back (model);
183 inlier_indices.push_back (label_indices[i]);
184 centroids.push_back (clust_centroid);
185 covariances.push_back (clust_cov);
193 template<
typename Po
intT,
typename Po
intNT,
typename Po
intLT>
void
196 std::vector<ModelCoefficients> model_coefficients;
197 std::vector<PointIndices> inlier_indices;
199 std::vector<pcl::PointIndices> label_indices;
200 std::vector<pcl::PointIndices> boundary_indices;
202 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > centroids;
203 std::vector <Eigen::Matrix3f, Eigen::aligned_allocator<Eigen::Matrix3f> > covariances;
204 segment (model_coefficients, inlier_indices, centroids, covariances, *labels, label_indices);
205 regions.resize (model_coefficients.size ());
206 boundary_indices.resize (model_coefficients.size ());
208 for (
size_t i = 0; i < model_coefficients.size (); i++)
210 boundary_cloud.
resize (0);
212 boundary_cloud.
points.resize (boundary_indices[i].indices.size ());
213 for (
unsigned j = 0; j < boundary_indices[i].indices.size (); j++)
214 boundary_cloud.
points[j] = input_->points[boundary_indices[i].indices[j]];
216 Eigen::Vector3f centroid = Eigen::Vector3f (centroids[i][0],centroids[i][1],centroids[i][2]);
217 Eigen::Vector4f model = Eigen::Vector4f (model_coefficients[i].values[0],
218 model_coefficients[i].values[1],
219 model_coefficients[i].values[2],
220 model_coefficients[i].values[3]);
223 static_cast<unsigned int> (inlier_indices[i].indices.size ()),
230 template<
typename Po
intT,
typename Po
intNT,
typename Po
intLT>
void
233 std::vector<ModelCoefficients> model_coefficients;
234 std::vector<PointIndices> inlier_indices;
236 std::vector<pcl::PointIndices> label_indices;
237 std::vector<pcl::PointIndices> boundary_indices;
239 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > centroids;
240 std::vector <Eigen::Matrix3f, Eigen::aligned_allocator<Eigen::Matrix3f> > covariances;
241 segment (model_coefficients, inlier_indices, centroids, covariances, *labels, label_indices);
242 refine (model_coefficients, inlier_indices, centroids, covariances, labels, label_indices);
243 regions.resize (model_coefficients.size ());
244 boundary_indices.resize (model_coefficients.size ());
246 for (
size_t i = 0; i < model_coefficients.size (); i++)
248 boundary_cloud.
resize (0);
249 int max_inlier_idx =
static_cast<int> (inlier_indices[i].indices.size ()) - 1;
251 boundary_cloud.
points.resize (boundary_indices[i].indices.size ());
252 for (
unsigned j = 0; j < boundary_indices[i].indices.size (); j++)
253 boundary_cloud.
points[j] = input_->points[boundary_indices[i].indices[j]];
255 Eigen::Vector3f centroid = Eigen::Vector3f (centroids[i][0],centroids[i][1],centroids[i][2]);
256 Eigen::Vector4f model = Eigen::Vector4f (model_coefficients[i].values[0],
257 model_coefficients[i].values[1],
258 model_coefficients[i].values[2],
259 model_coefficients[i].values[3]);
261 Eigen::Vector3f vp (0.0, 0.0, 0.0);
267 static_cast<unsigned int> (inlier_indices[i].indices.size ()),
274 template<
typename Po
intT,
typename Po
intNT,
typename Po
intLT>
void
276 std::vector<ModelCoefficients>& model_coefficients,
277 std::vector<PointIndices>& inlier_indices,
279 std::vector<pcl::PointIndices>& label_indices,
280 std::vector<pcl::PointIndices>& boundary_indices)
283 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > centroids;
284 std::vector <Eigen::Matrix3f, Eigen::aligned_allocator<Eigen::Matrix3f> > covariances;
285 segment (model_coefficients, inlier_indices, centroids, covariances, *labels, label_indices);
286 refine (model_coefficients, inlier_indices, centroids, covariances, labels, label_indices);
287 regions.resize (model_coefficients.size ());
288 boundary_indices.resize (model_coefficients.size ());
290 for (
size_t i = 0; i < model_coefficients.size (); i++)
292 boundary_cloud.
resize (0);
293 int max_inlier_idx =
static_cast<int> (inlier_indices[i].indices.size ()) - 1;
295 boundary_cloud.
points.resize (boundary_indices[i].indices.size ());
296 for (
unsigned j = 0; j < boundary_indices[i].indices.size (); j++)
297 boundary_cloud.
points[j] = input_->points[boundary_indices[i].indices[j]];
299 Eigen::Vector3f centroid = Eigen::Vector3f (centroids[i][0],centroids[i][1],centroids[i][2]);
300 Eigen::Vector4f model = Eigen::Vector4f (model_coefficients[i].values[0],
301 model_coefficients[i].values[1],
302 model_coefficients[i].values[2],
303 model_coefficients[i].values[3]);
305 Eigen::Vector3f vp (0.0, 0.0, 0.0);
306 if (project_points_ && boundary_cloud.
points.size () > 0)
311 static_cast<unsigned int> (inlier_indices[i].indices.size ()),
318 template<
typename Po
intT,
typename Po
intNT,
typename Po
intLT>
void
320 std::vector<PointIndices>& inlier_indices,
321 std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> >&,
322 std::vector <Eigen::Matrix3f, Eigen::aligned_allocator<Eigen::Matrix3f> >&,
324 std::vector<pcl::PointIndices>& label_indices)
327 std::vector<bool> grow_labels;
328 std::vector<int> label_to_model;
329 grow_labels.resize (label_indices.size (),
false);
330 label_to_model.resize (label_indices.size (), 0);
332 for (
size_t i = 0; i < model_coefficients.size (); i++)
334 int model_label = (*labels)[inlier_indices[i].indices[0]].label;
335 label_to_model[model_label] =
static_cast<int> (i);
336 grow_labels[model_label] =
true;
340 refinement_compare_->setInputCloud (input_);
341 refinement_compare_->setLabels (labels);
342 refinement_compare_->setModelCoefficients (model_coefficients);
343 refinement_compare_->setRefineLabels (grow_labels);
344 refinement_compare_->setLabelToModel (label_to_model);
347 unsigned int current_row = 0;
348 unsigned int next_row = labels->width;
349 for (
size_t rowIdx = 0; rowIdx < labels->height - 1; ++rowIdx, current_row = next_row, next_row += labels->width)
352 for (
unsigned colIdx = 0; colIdx < labels->width - 1; ++colIdx)
354 int current_label = (*labels)[current_row+colIdx].label;
355 int right_label = (*labels)[current_row+colIdx+1].label;
356 if (current_label < 0 || right_label < 0)
361 if (refinement_compare_->compare (current_row+colIdx, current_row+colIdx+1))
364 labels->points[current_row+colIdx+1].label = current_label;
365 label_indices[label_to_model[current_label]].indices.push_back (current_row+colIdx+1);
366 inlier_indices[label_to_model[current_label]].indices.push_back (current_row+colIdx+1);
369 int lower_label = (*labels)[next_row+colIdx].label;
374 if (refinement_compare_->compare (current_row+colIdx, next_row+colIdx))
376 labels->points[next_row+colIdx].label = current_label;
377 label_indices[label_to_model[current_label]].indices.push_back (next_row+colIdx);
378 inlier_indices[label_to_model[current_label]].indices.push_back (next_row+colIdx);
385 current_row = labels->width * (labels->height - 1);
386 unsigned int prev_row = current_row - labels->width;
387 for (
size_t rowIdx = 0; rowIdx < labels->height - 1; ++rowIdx, current_row = prev_row, prev_row -= labels->width)
389 for (
int colIdx = labels->width - 1; colIdx >= 0; --colIdx)
391 int current_label = (*labels)[current_row+colIdx].label;
392 int left_label = (*labels)[current_row+colIdx-1].label;
393 if (current_label < 0 || left_label < 0)
397 if (refinement_compare_->compare (current_row+colIdx, current_row+colIdx-1))
399 labels->points[current_row+colIdx-1].label = current_label;
400 label_indices[label_to_model[current_label]].indices.push_back (current_row+colIdx-1);
401 inlier_indices[label_to_model[current_label]].indices.push_back (current_row+colIdx-1);
404 int upper_label = (*labels)[prev_row+colIdx].label;
408 if (refinement_compare_->compare (current_row+colIdx, prev_row+colIdx))
410 labels->points[prev_row+colIdx].label = current_label;
411 label_indices[label_to_model[current_label]].indices.push_back (prev_row+colIdx);
412 inlier_indices[label_to_model[current_label]].indices.push_back (prev_row+colIdx);
418 #define PCL_INSTANTIATE_OrganizedMultiPlaneSegmentation(T,NT,LT) template class PCL_EXPORTS pcl::OrganizedMultiPlaneSegmentation<T,NT,LT>;
420 #endif // PCL_SEGMENTATION_IMPL_MULTI_PLANE_SEGMENTATION_H_