Loading...
Searching...
No Matches
region_growing.hpp
/*
* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holder(s) nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Author : Sergey Ushakov
* Email : mine_all_mine@bk.ru
*
*/
#pragma once
#include <pcl/segmentation/region_growing.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/point_tests.h> // for pcl::isFinite
#include <pcl/console/print.h> // for PCL_ERROR
#include <pcl/search/search.h>
#include <pcl/search/kdtree.h>
#include <queue>
#include <cmath>
#include <ctime>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT>
pcl::RegionGrowing<PointT, NormalT>::RegionGrowing() = default;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT>
pcl::RegionGrowing<PointT, NormalT>::~RegionGrowing ()
{
point_neighbours_.clear ();
point_labels_.clear ();
num_pts_in_segment_.clear ();
clusters_.clear ();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> pcl::uindex_t
pcl::RegionGrowing<PointT, NormalT>::getMinClusterSize ()
{
return (min_pts_per_cluster_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setMinClusterSize (pcl::uindex_t min_cluster_size)
{
min_pts_per_cluster_ = min_cluster_size;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> pcl::uindex_t
pcl::RegionGrowing<PointT, NormalT>::getMaxClusterSize ()
{
return (max_pts_per_cluster_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setMaxClusterSize (pcl::uindex_t max_cluster_size)
{
max_pts_per_cluster_ = max_cluster_size;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> bool
pcl::RegionGrowing<PointT, NormalT>::getSmoothModeFlag () const
{
return (smooth_mode_flag_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setSmoothModeFlag (bool value)
{
smooth_mode_flag_ = value;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> bool
pcl::RegionGrowing<PointT, NormalT>::getCurvatureTestFlag () const
{
return (curvature_flag_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setCurvatureTestFlag (bool value)
{
curvature_flag_ = value;
if (!curvature_flag_ && !residual_flag_)
residual_flag_ = true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> bool
pcl::RegionGrowing<PointT, NormalT>::getResidualTestFlag () const
{
return (residual_flag_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setResidualTestFlag (bool value)
{
residual_flag_ = value;
if (!curvature_flag_ && !residual_flag_)
curvature_flag_ = true;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> float
pcl::RegionGrowing<PointT, NormalT>::getSmoothnessThreshold () const
{
return (theta_threshold_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setSmoothnessThreshold (float theta)
{
theta_threshold_ = theta;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> float
pcl::RegionGrowing<PointT, NormalT>::getResidualThreshold () const
{
return (residual_threshold_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setResidualThreshold (float residual)
{
residual_threshold_ = residual;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> float
pcl::RegionGrowing<PointT, NormalT>::getCurvatureThreshold () const
{
return (curvature_threshold_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setCurvatureThreshold (float curvature)
{
curvature_threshold_ = curvature;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> unsigned int
pcl::RegionGrowing<PointT, NormalT>::getNumberOfNeighbours () const
{
return (neighbour_number_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setNumberOfNeighbours (unsigned int neighbour_number)
{
neighbour_number_ = neighbour_number;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> typename pcl::RegionGrowing<PointT, NormalT>::KdTreePtr
pcl::RegionGrowing<PointT, NormalT>::getSearchMethod () const
{
return (search_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setSearchMethod (const KdTreePtr& tree)
{
search_ = tree;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> typename pcl::RegionGrowing<PointT, NormalT>::NormalPtr
pcl::RegionGrowing<PointT, NormalT>::getInputNormals () const
{
return (normals_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::setInputNormals (const NormalPtr& norm)
{
normals_ = norm;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::extract (std::vector <pcl::PointIndices>& clusters)
{
clusters_.clear ();
clusters.clear ();
point_neighbours_.clear ();
point_labels_.clear ();
num_pts_in_segment_.clear ();
number_of_segments_ = 0;
bool segmentation_is_possible = initCompute ();
if ( !segmentation_is_possible )
{
deinitCompute ();
return;
}
segmentation_is_possible = prepareForSegmentation ();
if ( !segmentation_is_possible )
{
deinitCompute ();
return;
}
findPointNeighbours ();
applySmoothRegionGrowingAlgorithm ();
assembleRegions ();
clusters.resize (clusters_.size ());
auto cluster_iter_input = clusters.begin ();
for (const auto& cluster : clusters_)
{
if ((cluster.indices.size () >= min_pts_per_cluster_) &&
(cluster.indices.size () <= max_pts_per_cluster_))
{
*cluster_iter_input = cluster;
++cluster_iter_input;
}
}
clusters_ = std::vector<pcl::PointIndices> (clusters.begin (), cluster_iter_input);
clusters.resize(clusters_.size());
deinitCompute ();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> bool
pcl::RegionGrowing<PointT, NormalT>::prepareForSegmentation ()
{
// if user forgot to pass point cloud or if it is empty
if ( input_->points.empty () )
return (false);
// if user forgot to pass normals or the sizes of point and normal cloud are different
if ( !normals_ || input_->size () != normals_->size () )
return (false);
// if residual test is on then we need to check if all needed parameters were correctly initialized
if (residual_flag_)
{
if (residual_threshold_ <= 0.0f)
return (false);
}
// if curvature test is on ...
// if (curvature_flag_)
// {
// in this case we do not need to check anything that related to it
// so we simply commented it
// }
// from here we check those parameters that are always valuable
if (neighbour_number_ == 0)
return (false);
// if user didn't set search method
if (!search_)
search_.reset (new pcl::search::KdTree<PointT>);
if (indices_)
{
if (indices_->empty ())
PCL_ERROR ("[pcl::RegionGrowing::prepareForSegmentation] Empty given indices!\n");
search_->setInputCloud (input_, indices_);
}
else
search_->setInputCloud (input_);
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::findPointNeighbours ()
{
pcl::Indices neighbours;
std::vector<float> distances;
point_neighbours_.resize (input_->size (), neighbours);
if (input_->is_dense)
{
for (const auto& point_index: (*indices_))
{
neighbours.clear ();
search_->nearestKSearch (point_index, neighbour_number_, neighbours, distances);
point_neighbours_[point_index].swap (neighbours);
}
}
else
{
for (const auto& point_index: (*indices_))
{
if (!pcl::isFinite ((*input_)[point_index]))
continue;
neighbours.clear ();
search_->nearestKSearch (point_index, neighbour_number_, neighbours, distances);
point_neighbours_[point_index].swap (neighbours);
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::applySmoothRegionGrowingAlgorithm ()
{
int num_of_pts = static_cast<int> (indices_->size ());
point_labels_.resize (input_->size (), -1);
std::vector< std::pair<float, int> > point_residual;
std::pair<float, int> pair;
point_residual.resize (num_of_pts, pair);
if (normal_flag_)
{
for (int i_point = 0; i_point < num_of_pts; i_point++)
{
const auto point_index = (*indices_)[i_point];
point_residual[i_point].first = (*normals_)[point_index].curvature;
point_residual[i_point].second = point_index;
}
std::sort (point_residual.begin (), point_residual.end (), comparePair);
}
else
{
for (int i_point = 0; i_point < num_of_pts; i_point++)
{
const auto point_index = (*indices_)[i_point];
point_residual[i_point].first = 0;
point_residual[i_point].second = point_index;
}
}
int seed_counter = 0;
int seed = point_residual[seed_counter].second;
int segmented_pts_num = 0;
int number_of_segments = 0;
while (segmented_pts_num < num_of_pts)
{
int pts_in_segment;
pts_in_segment = growRegion (seed, number_of_segments);
segmented_pts_num += pts_in_segment;
num_pts_in_segment_.push_back (pts_in_segment);
number_of_segments++;
//find next point that is not segmented yet
for (int i_seed = seed_counter + 1; i_seed < num_of_pts; i_seed++)
{
int index = point_residual[i_seed].second;
if (point_labels_[index] == -1)
{
seed = index;
seed_counter = i_seed;
break;
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> int
pcl::RegionGrowing<PointT, NormalT>::growRegion (int initial_seed, int segment_number)
{
std::queue<int> seeds;
seeds.push (initial_seed);
point_labels_[initial_seed] = segment_number;
int num_pts_in_segment = 1;
while (!seeds.empty ())
{
int curr_seed;
curr_seed = seeds.front ();
seeds.pop ();
std::size_t i_nghbr = 0;
while ( i_nghbr < neighbour_number_ && i_nghbr < point_neighbours_[curr_seed].size () )
{
int index = point_neighbours_[curr_seed][i_nghbr];
if (point_labels_[index] != -1)
{
i_nghbr++;
continue;
}
bool is_a_seed = false;
bool belongs_to_segment = validatePoint (initial_seed, curr_seed, index, is_a_seed);
if (!belongs_to_segment)
{
i_nghbr++;
continue;
}
point_labels_[index] = segment_number;
num_pts_in_segment++;
if (is_a_seed)
{
seeds.push (index);
}
i_nghbr++;
}// next neighbour
}// next seed
return (num_pts_in_segment);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> bool
pcl::RegionGrowing<PointT, NormalT>::validatePoint (pcl::index_t initial_seed, pcl::index_t point, pcl::index_t nghbr, bool& is_a_seed) const
{
is_a_seed = true;
float cosine_threshold = std::cos (theta_threshold_);
float data[4];
data[0] = (*input_)[point].data[0];
data[1] = (*input_)[point].data[1];
data[2] = (*input_)[point].data[2];
data[3] = (*input_)[point].data[3];
Eigen::Map<Eigen::Vector3f> initial_point (static_cast<float*> (data));
Eigen::Map<Eigen::Vector3f> initial_normal (static_cast<float*> ((*normals_)[point].normal));
//check the angle between normals
if (smooth_mode_flag_)
{
Eigen::Map<Eigen::Vector3f> nghbr_normal (static_cast<float*> ((*normals_)[nghbr].normal));
float dot_product = std::abs (nghbr_normal.dot (initial_normal));
if (dot_product < cosine_threshold)
{
return (false);
}
}
else
{
Eigen::Map<Eigen::Vector3f> nghbr_normal (static_cast<float*> ((*normals_)[nghbr].normal));
Eigen::Map<Eigen::Vector3f> initial_seed_normal (static_cast<float*> ((*normals_)[initial_seed].normal));
float dot_product = std::abs (nghbr_normal.dot (initial_seed_normal));
if (dot_product < cosine_threshold)
return (false);
}
// check the curvature if needed
if (curvature_flag_ && (*normals_)[nghbr].curvature > curvature_threshold_)
{
is_a_seed = false;
}
// check the residual if needed
float data_1[4];
data_1[0] = (*input_)[nghbr].data[0];
data_1[1] = (*input_)[nghbr].data[1];
data_1[2] = (*input_)[nghbr].data[2];
data_1[3] = (*input_)[nghbr].data[3];
Eigen::Map<Eigen::Vector3f> nghbr_point (static_cast<float*> (data_1));
float residual = std::abs (initial_normal.dot (initial_point - nghbr_point));
if (residual_flag_ && residual > residual_threshold_)
is_a_seed = false;
return (true);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::assembleRegions ()
{
const auto number_of_segments = num_pts_in_segment_.size ();
const auto number_of_points = input_->size ();
pcl::PointIndices segment;
clusters_.resize (number_of_segments, segment);
for (std::size_t i_seg = 0; i_seg < number_of_segments; i_seg++)
{
clusters_[i_seg].indices.resize ( num_pts_in_segment_[i_seg], 0);
}
std::vector<int> counter(number_of_segments, 0);
for (std::size_t i_point = 0; i_point < number_of_points; i_point++)
{
const auto segment_index = point_labels_[i_point];
if (segment_index != -1)
{
const auto point_index = counter[segment_index];
clusters_[segment_index].indices[point_index] = i_point;
counter[segment_index] = point_index + 1;
}
}
number_of_segments_ = number_of_segments;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> void
pcl::RegionGrowing<PointT, NormalT>::getSegmentFromPoint (pcl::index_t index, pcl::PointIndices& cluster)
{
cluster.indices.clear ();
bool segmentation_is_possible = initCompute ();
if ( !segmentation_is_possible )
{
deinitCompute ();
return;
}
// first of all we need to find out if this point belongs to cloud
bool point_was_found = false;
for (const auto& point : (*indices_))
if (point == index)
{
point_was_found = true;
break;
}
if (point_was_found)
{
if (clusters_.empty ())
{
point_neighbours_.clear ();
point_labels_.clear ();
num_pts_in_segment_.clear ();
number_of_segments_ = 0;
segmentation_is_possible = prepareForSegmentation ();
if ( !segmentation_is_possible )
{
deinitCompute ();
return;
}
findPointNeighbours ();
applySmoothRegionGrowingAlgorithm ();
assembleRegions ();
}
// if we have already made the segmentation, then find the segment
// to which this point belongs
for (const auto& i_segment : clusters_)
{
const auto it = std::find (i_segment.indices.cbegin (), i_segment.indices.cend (), index);
if (it != i_segment.indices.cend())
{
// if segment was found
cluster.indices.clear ();
cluster.indices.reserve (i_segment.indices.size ());
std::copy (i_segment.indices.begin (), i_segment.indices.end (), std::back_inserter (cluster.indices));
break;
}
}// next segment
}// end if point was found
deinitCompute ();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> pcl::PointCloud<pcl::PointXYZRGB>::Ptr
pcl::RegionGrowing<PointT, NormalT>::getColoredCloud ()
{
pcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud;
if (!clusters_.empty ())
{
colored_cloud.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
srand (static_cast<unsigned int> (time (nullptr)));
std::vector<unsigned char> colors;
for (std::size_t i_segment = 0; i_segment < clusters_.size (); i_segment++)
{
colors.push_back (static_cast<unsigned char> (rand () % 256));
colors.push_back (static_cast<unsigned char> (rand () % 256));
colors.push_back (static_cast<unsigned char> (rand () % 256));
}
colored_cloud->width = input_->width;
colored_cloud->height = input_->height;
colored_cloud->is_dense = input_->is_dense;
for (const auto& i_point: *input_)
{
pcl::PointXYZRGB point;
point.x = *(i_point.data);
point.y = *(i_point.data + 1);
point.z = *(i_point.data + 2);
point.r = 255;
point.g = 0;
point.b = 0;
colored_cloud->points.push_back (point);
}
int next_color = 0;
for (const auto& i_segment : clusters_)
{
for (const auto& index : (i_segment.indices))
{
(*colored_cloud)[index].r = colors[3 * next_color];
(*colored_cloud)[index].g = colors[3 * next_color + 1];
(*colored_cloud)[index].b = colors[3 * next_color + 2];
}
next_color++;
}
}
return (colored_cloud);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT, typename NormalT> pcl::PointCloud<pcl::PointXYZRGBA>::Ptr
pcl::RegionGrowing<PointT, NormalT>::getColoredCloudRGBA ()
{
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr colored_cloud;
if (!clusters_.empty ())
{
colored_cloud.reset(new pcl::PointCloud<pcl::PointXYZRGBA>);
srand (static_cast<unsigned int> (time (nullptr)));
std::vector<unsigned char> colors;
for (std::size_t i_segment = 0; i_segment < clusters_.size (); i_segment++)
{
colors.push_back (static_cast<unsigned char> (rand () % 256));
colors.push_back (static_cast<unsigned char> (rand () % 256));
colors.push_back (static_cast<unsigned char> (rand () % 256));
}
colored_cloud->width = input_->width;
colored_cloud->height = input_->height;
colored_cloud->is_dense = input_->is_dense;
for (const auto& i_point: *input_)
{
pcl::PointXYZRGBA point;
point.x = *(i_point.data);
point.y = *(i_point.data + 1);
point.z = *(i_point.data + 2);
point.r = 255;
point.g = 0;
point.b = 0;
point.a = 0;
colored_cloud->points.push_back (point);
}
int next_color = 0;
for (const auto& i_segment : clusters_)
{
for (const auto& index : (i_segment.indices))
{
(*colored_cloud)[index].r = colors[3 * next_color];
(*colored_cloud)[index].g = colors[3 * next_color + 1];
(*colored_cloud)[index].b = colors[3 * next_color + 2];
}
next_color++;
}
}
return (colored_cloud);
}
#define PCL_INSTANTIATE_RegionGrowing(T) template class PCL_EXPORTS pcl::RegionGrowing<T, pcl::Normal>;
pcl::PointCloud
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition point_cloud.h:173
pcl::PointCloud::is_dense
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields).
Definition point_cloud.h:403
pcl::PointCloud::width
std::uint32_t width
The point cloud width (if organized as an image-structure).
Definition point_cloud.h:398
pcl::PointCloud::height
std::uint32_t height
The point cloud height (if organized as an image-structure).
Definition point_cloud.h:400
pcl::PointCloud::Ptr
shared_ptr< PointCloud< PointT > > Ptr
Definition point_cloud.h:413
pcl::PointCloud::points
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
Definition point_cloud.h:395
pcl::RegionGrowing::getResidualTestFlag
bool getResidualTestFlag() const
Returns the flag that signalize if the residual test is turned on/off.
Definition region_growing.hpp:130
pcl::RegionGrowing::getColoredCloudRGBA
pcl::PointCloud< pcl::PointXYZRGBA >::Ptr getColoredCloudRGBA()
If the cloud was successfully segmented, then function returns colored cloud.
Definition region_growing.hpp:659
pcl::RegionGrowing::setResidualThreshold
void setResidualThreshold(float residual)
Allows to set residual threshold used for testing the points.
Definition region_growing.hpp:168
pcl::RegionGrowing::~RegionGrowing
~RegionGrowing() override
This destructor destroys the cloud, normals and search method used for finding KNN.
Definition region_growing.hpp:61
pcl::RegionGrowing::setCurvatureTestFlag
virtual void setCurvatureTestFlag(bool value)
Allows to turn on/off the curvature test.
Definition region_growing.hpp:120
pcl::RegionGrowing::KdTreePtr
typename KdTree::Ptr KdTreePtr
Definition region_growing.h:65
pcl::RegionGrowing::setSearchMethod
void setSearchMethod(const KdTreePtr &tree)
Allows to set search method that will be used for finding KNN.
Definition region_growing.hpp:210
pcl::RegionGrowing::setInputNormals
void setInputNormals(const NormalPtr &norm)
This method sets the normals.
Definition region_growing.hpp:224
pcl::RegionGrowing::getMinClusterSize
pcl::uindex_t getMinClusterSize()
Get the minimum number of points that a cluster needs to contain in order to be considered valid.
Definition region_growing.hpp:71
pcl::RegionGrowing::RegionGrowing
RegionGrowing()
Constructor that sets default values for member variables.
pcl::RegionGrowing::growRegion
int growRegion(int initial_seed, int segment_number)
This method grows a segment for the given seed point.
Definition region_growing.hpp:411
pcl::RegionGrowing::setNumberOfNeighbours
void setNumberOfNeighbours(unsigned int neighbour_number)
Allows to set the number of neighbours.
Definition region_growing.hpp:196
pcl::RegionGrowing::prepareForSegmentation
virtual bool prepareForSegmentation()
This method simply checks if it is possible to execute the segmentation algorithm with the current se...
Definition region_growing.hpp:278
pcl::RegionGrowing::findPointNeighbours
virtual void findPointNeighbours()
This method finds KNN for each point and saves them to the array because the algorithm needs to find ...
Definition region_growing.hpp:324
pcl::RegionGrowing::getInputNormals
NormalPtr getInputNormals() const
Returns normals.
Definition region_growing.hpp:217
pcl::RegionGrowing::getCurvatureThreshold
float getCurvatureThreshold() const
Returns curvature threshold.
Definition region_growing.hpp:175
pcl::RegionGrowing::setMinClusterSize
void setMinClusterSize(pcl::uindex_t min_cluster_size)
Set the minimum number of points that a cluster needs to contain in order to be considered valid.
Definition region_growing.hpp:78
pcl::RegionGrowing::getResidualThreshold
float getResidualThreshold() const
Returns residual threshold.
Definition region_growing.hpp:161
pcl::RegionGrowing::getSmoothnessThreshold
float getSmoothnessThreshold() const
Returns smoothness threshold.
Definition region_growing.hpp:147
pcl::RegionGrowing::getSearchMethod
KdTreePtr getSearchMethod() const
Returns the pointer to the search method that is used for KNN.
Definition region_growing.hpp:203
pcl::RegionGrowing::extract
virtual void extract(std::vector< pcl::PointIndices > &clusters)
This method launches the segmentation algorithm and returns the clusters that were obtained during th...
Definition region_growing.hpp:231
pcl::RegionGrowing::getNumberOfNeighbours
unsigned int getNumberOfNeighbours() const
Returns the number of nearest neighbours used for KNN.
Definition region_growing.hpp:189
pcl::RegionGrowing::getCurvatureTestFlag
bool getCurvatureTestFlag() const
Returns the flag that signalize if the curvature test is turned on/off.
Definition region_growing.hpp:113
pcl::RegionGrowing::setSmoothnessThreshold
void setSmoothnessThreshold(float theta)
Allows to set smoothness threshold used for testing the points.
Definition region_growing.hpp:154
pcl::RegionGrowing::getMaxClusterSize
pcl::uindex_t getMaxClusterSize()
Get the maximum number of points that a cluster needs to contain in order to be considered valid.
Definition region_growing.hpp:85
pcl::RegionGrowing::getSegmentFromPoint
virtual void getSegmentFromPoint(pcl::index_t index, pcl::PointIndices &cluster)
For a given point this function builds a segment to which it belongs and returns this segment.
Definition region_growing.hpp:548
pcl::RegionGrowing::setResidualTestFlag
virtual void setResidualTestFlag(bool value)
Allows to turn on/off the residual test.
Definition region_growing.hpp:137
pcl::RegionGrowing::setMaxClusterSize
void setMaxClusterSize(pcl::uindex_t max_cluster_size)
Set the maximum number of points that a cluster needs to contain in order to be considered valid.
Definition region_growing.hpp:92
pcl::RegionGrowing::setCurvatureThreshold
void setCurvatureThreshold(float curvature)
Allows to set curvature threshold used for testing the points.
Definition region_growing.hpp:182
pcl::RegionGrowing::applySmoothRegionGrowingAlgorithm
void applySmoothRegionGrowingAlgorithm()
This function implements the algorithm described in the article "Segmentation of point clouds using s...
Definition region_growing.hpp:354
pcl::RegionGrowing::getSmoothModeFlag
bool getSmoothModeFlag() const
Returns the flag value.
Definition region_growing.hpp:99
pcl::RegionGrowing::getColoredCloud
pcl::PointCloud< pcl::PointXYZRGB >::Ptr getColoredCloud()
If the cloud was successfully segmented, then function returns colored cloud.
Definition region_growing.hpp:609
pcl::RegionGrowing::validatePoint
virtual bool validatePoint(pcl::index_t initial_seed, pcl::index_t point, pcl::index_t nghbr, bool &is_a_seed) const
This function is checking if the point with index 'nghbr' belongs to the segment.
Definition region_growing.hpp:461
pcl::RegionGrowing::setSmoothModeFlag
void setSmoothModeFlag(bool value)
This function allows to turn on/off the smoothness constraint.
Definition region_growing.hpp:106
pcl::RegionGrowing::NormalPtr
typename Normal::Ptr NormalPtr
Definition region_growing.h:67
pcl::RegionGrowing::assembleRegions
void assembleRegions()
This function simply assembles the regions from list of point labels.
Definition region_growing.hpp:517
pcl::search::KdTree
search::KdTree is a wrapper class which inherits the pcl::KdTree class for performing search function...
Definition kdtree.h:62
point_types.h
Defines all the PCL implemented PointT point type structures.
pcl::uindex_t
detail::int_type_t< detail::index_type_size, false > uindex_t
Type used for an unsigned index in PCL.
Definition types.h:120
pcl::comparePair
bool comparePair(std::pair< float, int > i, std::pair< float, int > j)
This function is used as a comparator for sorting.
Definition region_growing.h:340
pcl::isFinite
bool isFinite(const PointT &pt)
Tests if the 3D components of a point are all finite param[in] pt point to be tested return true if f...
Definition point_tests.h:55
pcl::index_t
detail::int_type_t< detail::index_type_size, detail::index_type_signed > index_t
Type used for an index in PCL.
Definition types.h:112
pcl::Indices
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition types.h:133
pcl::PointIndices
Definition PointIndices.h:12
pcl::PointIndices::indices
Indices indices
Definition PointIndices.h:20
pcl::PointXYZRGBA
A point structure representing Euclidean xyz coordinates, and the RGBA color.
Definition point_types.hpp:528
pcl::PointXYZRGB
A point structure representing Euclidean xyz coordinates, and the RGB color.
Definition point_types.hpp:594