164 point_neighbours_.clear ();
165 point_labels_.clear ();
166 num_pts_in_segment_.clear ();
167 point_distances_.clear ();
168 segment_neighbours_.clear ();
169 segment_distances_.clear ();
170 segment_labels_.clear ();
171 number_of_segments_ = 0;
173 bool segmentation_is_possible = initCompute ();
174 if ( !segmentation_is_possible )
180 segmentation_is_possible = prepareForSegmentation ();
181 if ( !segmentation_is_possible )
187 findPointNeighbours ();
188 applySmoothRegionGrowingAlgorithm ();
191 findSegmentNeighbours ();
192 applyRegionMergingAlgorithm ();
194 auto cluster_iter = clusters_.begin ();
195 while (cluster_iter != clusters_.end ())
197 if (cluster_iter->indices.size () < min_pts_per_cluster_ ||
198 cluster_iter->indices.size () > max_pts_per_cluster_)
200 cluster_iter = clusters_.erase (cluster_iter);
206 clusters.reserve (clusters_.size ());
207 std::copy (clusters_.cbegin (), clusters_.cend (), std::back_inserter (clusters));
314 std::vector<float> distances;
315 float max_dist = std::numeric_limits<float>::max ();
316 distances.resize (clusters_.size (), max_dist);
318 const auto number_of_points = num_pts_in_segment_[index];
320 for (
pcl::uindex_t i_point = 0; i_point < number_of_points; i_point++)
322 const auto point_index = clusters_[index].indices[i_point];
323 const auto number_of_neighbours = point_neighbours_[point_index].size ();
326 for (std::size_t i_nghbr = 0; i_nghbr < number_of_neighbours; i_nghbr++)
329 const pcl::index_t segment_index = point_labels_[ point_neighbours_[point_index][i_nghbr] ];
331 if ( segment_index != index )
334 if (distances[segment_index] > point_distances_[point_index][i_nghbr])
335 distances[segment_index] = point_distances_[point_index][i_nghbr];
340 std::priority_queue<std::pair<float, int> > segment_neighbours;
341 for (
int i_seg = 0; i_seg < number_of_segments_; i_seg++)
343 if (distances[i_seg] < max_dist)
345 segment_neighbours.emplace (distances[i_seg], i_seg);
346 if (segment_neighbours.size () > nghbr_number)
347 segment_neighbours.pop ();
351 const std::size_t size = std::min<std::size_t> (segment_neighbours.size (),
static_cast<std::size_t
>(nghbr_number));
352 nghbrs.resize (size, 0);
353 dist.resize (size, 0);
355 while ( !segment_neighbours.empty () && counter < nghbr_number )
357 dist[counter] = segment_neighbours.top ().first;
358 nghbrs[counter] = segment_neighbours.top ().second;
359 segment_neighbours.pop ();
369 std::vector< std::vector<unsigned int> > segment_color;
370 std::vector<unsigned int> color;
372 segment_color.resize (number_of_segments_, color);
374 for (
const auto& point_index : (*indices_))
376 int segment_index = point_labels_[point_index];
377 segment_color[segment_index][0] += (*input_)[point_index].r;
378 segment_color[segment_index][1] += (*input_)[point_index].g;
379 segment_color[segment_index][2] += (*input_)[point_index].b;
381 for (
int i_seg = 0; i_seg < number_of_segments_; i_seg++)
383 segment_color[i_seg][0] =
static_cast<unsigned int> (
static_cast<float> (segment_color[i_seg][0]) /
static_cast<float> (num_pts_in_segment_[i_seg]));
384 segment_color[i_seg][1] =
static_cast<unsigned int> (
static_cast<float> (segment_color[i_seg][1]) /
static_cast<float> (num_pts_in_segment_[i_seg]));
385 segment_color[i_seg][2] =
static_cast<unsigned int> (
static_cast<float> (segment_color[i_seg][2]) /
static_cast<float> (num_pts_in_segment_[i_seg]));
390 std::vector<unsigned int> num_pts_in_homogeneous_region;
391 std::vector<int> num_seg_in_homogeneous_region;
393 segment_labels_.resize (number_of_segments_, -1);
395 float dist_thresh = distance_threshold_;
396 int homogeneous_region_number = 0;
397 for (
int i_seg = 0; i_seg < number_of_segments_; i_seg++)
399 int curr_homogeneous_region = 0;
400 if (segment_labels_[i_seg] == -1)
402 segment_labels_[i_seg] = homogeneous_region_number;
403 curr_homogeneous_region = homogeneous_region_number;
404 num_pts_in_homogeneous_region.push_back (num_pts_in_segment_[i_seg]);
405 num_seg_in_homogeneous_region.push_back (1);
406 homogeneous_region_number++;
409 curr_homogeneous_region = segment_labels_[i_seg];
411 unsigned int i_nghbr = 0;
412 while ( i_nghbr < region_neighbour_number_ && i_nghbr < segment_neighbours_[i_seg].size () )
414 int index = segment_neighbours_[i_seg][i_nghbr];
415 if (segment_distances_[i_seg][i_nghbr] > dist_thresh)
420 if ( segment_labels_[index] == -1 )
422 float difference = calculateColorimetricalDifference (segment_color[i_seg], segment_color[index]);
423 if (difference < color_r2r_threshold_)
425 segment_labels_[index] = curr_homogeneous_region;
426 num_pts_in_homogeneous_region[curr_homogeneous_region] += num_pts_in_segment_[index];
427 num_seg_in_homogeneous_region[curr_homogeneous_region] += 1;
434 segment_color.clear ();
437 std::vector< std::vector<int> > final_segments;
438 std::vector<int> region;
439 final_segments.resize (homogeneous_region_number, region);
440 for (
int i_reg = 0; i_reg < homogeneous_region_number; i_reg++)
442 final_segments[i_reg].resize (num_seg_in_homogeneous_region[i_reg], 0);
445 std::vector<int> counter;
446 counter.resize (homogeneous_region_number, 0);
447 for (
int i_seg = 0; i_seg < number_of_segments_; i_seg++)
449 int index = segment_labels_[i_seg];
450 final_segments[ index ][ counter[index] ] = i_seg;
454 std::vector< std::vector< std::pair<float, pcl::index_t> > > region_neighbours;
455 findRegionNeighbours (region_neighbours, final_segments);
457 int final_segment_number = homogeneous_region_number;
458 for (
int i_reg = 0; i_reg < homogeneous_region_number; i_reg++)
460 if (num_pts_in_homogeneous_region[i_reg] < min_pts_per_cluster_)
462 if ( region_neighbours[i_reg].empty () )
464 int nearest_neighbour = region_neighbours[i_reg][0].second;
465 if ( region_neighbours[i_reg][0].first == std::numeric_limits<float>::max () )
467 int reg_index = segment_labels_[nearest_neighbour];
468 int num_seg_in_reg = num_seg_in_homogeneous_region[i_reg];
469 for (
int i_seg = 0; i_seg < num_seg_in_reg; i_seg++)
471 int segment_index = final_segments[i_reg][i_seg];
472 final_segments[reg_index].push_back (segment_index);
473 segment_labels_[segment_index] = reg_index;
475 final_segments[i_reg].clear ();
476 num_pts_in_homogeneous_region[reg_index] += num_pts_in_homogeneous_region[i_reg];
477 num_pts_in_homogeneous_region[i_reg] = 0;
478 num_seg_in_homogeneous_region[reg_index] += num_seg_in_homogeneous_region[i_reg];
479 num_seg_in_homogeneous_region[i_reg] = 0;
480 final_segment_number -= 1;
482 const auto filtered_region_neighbours_reg_index_end = std::remove_if (
483 region_neighbours[reg_index].begin (),
484 region_neighbours[reg_index].end (),
485 [
this, reg_index] (
const auto& nghbr) {
return segment_labels_[ nghbr.second ] == reg_index; });
486 const auto filtered_region_neighbours_reg_index_size = std::distance (
487 region_neighbours[reg_index].begin (), filtered_region_neighbours_reg_index_end);
488 region_neighbours[reg_index].resize (filtered_region_neighbours_reg_index_size);
490 for (
const auto& nghbr : region_neighbours[i_reg])
492 if ( segment_labels_[ nghbr.second ] != reg_index )
494 region_neighbours[reg_index].push_back (nghbr);
497 region_neighbours[i_reg].clear ();
499 region_neighbours[reg_index].begin (),
500 std::next (region_neighbours[reg_index].begin (), filtered_region_neighbours_reg_index_size),
501 region_neighbours[reg_index].end (),
506 assembleRegions (num_pts_in_homogeneous_region,
static_cast<int> (num_pts_in_homogeneous_region.size ()));
508 number_of_segments_ = final_segment_number;
526 int region_number =
static_cast<int> (regions_in.size ());
527 neighbours_out.clear ();
528 neighbours_out.resize (region_number);
530 for (
int i_reg = 0; i_reg < region_number; i_reg++)
532 neighbours_out[i_reg].reserve (regions_in[i_reg].size () * region_neighbour_number_);
533 for (
const auto& curr_segment : regions_in[i_reg])
535 const std::size_t nghbr_number = segment_neighbours_[curr_segment].size ();
536 std::pair<float, pcl::index_t> pair;
537 for (std::size_t i_nghbr = 0; i_nghbr < nghbr_number; i_nghbr++)
539 const auto segment_index = segment_neighbours_[curr_segment][i_nghbr];
540 if ( segment_distances_[curr_segment][i_nghbr] == std::numeric_limits<float>::max () )
542 if (segment_labels_[segment_index] != i_reg)
544 pair.first = segment_distances_[curr_segment][i_nghbr];
545 pair.second = segment_index;
546 neighbours_out[i_reg].push_back (pair);
550 std::sort (neighbours_out[i_reg].begin (), neighbours_out[i_reg].end (),
comparePair);
560 clusters_.resize (num_regions, segment);
561 for (
int i_seg = 0; i_seg < num_regions; i_seg++)
563 clusters_[i_seg].
indices.resize (num_pts_in_region[i_seg]);
566 std::vector<int> counter;
567 counter.resize (num_regions, 0);
568 for (
const auto& point_index : (*indices_))
570 int index = point_labels_[point_index];
571 index = segment_labels_[index];
572 clusters_[index].indices[ counter[index] ] = point_index;
577 if (clusters_.empty ())
580 std::vector<pcl::PointIndices>::iterator itr1, itr2;
581 itr1 = clusters_.begin ();
582 itr2 = clusters_.end () - 1;
586 while (!(itr1->indices.empty ()) && itr1 < itr2)
588 while ( itr2->indices.empty () && itr1 < itr2)
592 itr1->indices.swap (itr2->indices);
595 if (itr2->indices.empty ())
596 clusters_.erase (itr2, clusters_.end ());
606 std::vector<unsigned int> point_color;
607 point_color.resize (3, 0);
608 std::vector<unsigned int> nghbr_color;
609 nghbr_color.resize (3, 0);
610 point_color[0] = (*input_)[point].r;
611 point_color[1] = (*input_)[point].g;
612 point_color[2] = (*input_)[point].b;
613 nghbr_color[0] = (*input_)[nghbr].r;
614 nghbr_color[1] = (*input_)[nghbr].g;
615 nghbr_color[2] = (*input_)[nghbr].b;
616 float difference = calculateColorimetricalDifference (point_color, nghbr_color);
617 if (difference > color_p2p_threshold_)
620 float cosine_threshold = std::cos (theta_threshold_);
626 data[0] = (*input_)[point].data[0];
627 data[1] = (*input_)[point].data[1];
628 data[2] = (*input_)[point].data[2];
629 data[3] = (*input_)[point].data[3];
631 Eigen::Map<Eigen::Vector3f> initial_point (
static_cast<float*
> (data));
632 Eigen::Map<Eigen::Vector3f> initial_normal (
static_cast<float*
> ((*normals_)[point].normal));
633 if (smooth_mode_flag_ ==
true)
635 Eigen::Map<Eigen::Vector3f> nghbr_normal (
static_cast<float*
> ((*normals_)[nghbr].normal));
636 float dot_product = std::abs (nghbr_normal.dot (initial_normal));
637 if (dot_product < cosine_threshold)
642 Eigen::Map<Eigen::Vector3f> nghbr_normal (
static_cast<float*
> ((*normals_)[nghbr].normal));
643 Eigen::Map<Eigen::Vector3f> initial_seed_normal (
static_cast<float*
> ((*normals_)[initial_seed].normal));
644 float dot_product = std::abs (nghbr_normal.dot (initial_seed_normal));
645 if (dot_product < cosine_threshold)
651 if (curvature_flag_ && (*normals_)[nghbr].curvature > curvature_threshold_)
658 data_p[0] = (*input_)[point].data[0];
659 data_p[1] = (*input_)[point].data[1];
660 data_p[2] = (*input_)[point].data[2];
661 data_p[3] = (*input_)[point].data[3];
663 data_n[0] = (*input_)[nghbr].data[0];
664 data_n[1] = (*input_)[nghbr].data[1];
665 data_n[2] = (*input_)[nghbr].data[2];
666 data_n[3] = (*input_)[nghbr].data[3];
667 Eigen::Map<Eigen::Vector3f> nghbr_point (
static_cast<float*
> (data_n));
668 Eigen::Map<Eigen::Vector3f> initial_point (
static_cast<float*
> (data_p));
669 Eigen::Map<Eigen::Vector3f> initial_normal (
static_cast<float*
> ((*normals_)[point].normal));
670 float residual = std::abs (initial_normal.dot (initial_point - nghbr_point));
671 if (residual > residual_threshold_)
684 bool segmentation_is_possible = initCompute ();
685 if ( !segmentation_is_possible )
692 bool point_was_found =
false;
693 for (
const auto& point : (*indices_))
696 point_was_found =
true;
702 if (clusters_.empty ())
705 point_neighbours_.clear ();
706 point_labels_.clear ();
707 num_pts_in_segment_.clear ();
708 point_distances_.clear ();
709 segment_neighbours_.clear ();
710 segment_distances_.clear ();
711 segment_labels_.clear ();
712 number_of_segments_ = 0;
714 segmentation_is_possible = prepareForSegmentation ();
715 if ( !segmentation_is_possible )
721 findPointNeighbours ();
722 applySmoothRegionGrowingAlgorithm ();
725 findSegmentNeighbours ();
726 applyRegionMergingAlgorithm ();
730 for (
const auto& i_segment : clusters_)
732 const auto it = std::find (i_segment.indices.cbegin (), i_segment.indices.cend (), index);
733 if (it != i_segment.indices.cend())
737 cluster.
indices.reserve (i_segment.indices.size ());
738 std::copy (i_segment.indices.begin (), i_segment.indices.end (), std::back_inserter (cluster.
indices));