Loading...
Searching...
No Matches
seeded_hue_segmentation.hpp
/*
* Software License Agreement (BSD License)
*
* Point Cloud Library (PCL) - www.pointclouds.org
* Copyright (c) 2010-2011, Willow Garage, Inc.
*
* 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.
*
* $id $
*/
#ifndef PCL_SEGMENTATION_IMPL_SEEDED_HUE_SEGMENTATION_H_
#define PCL_SEGMENTATION_IMPL_SEEDED_HUE_SEGMENTATION_H_
#include <pcl/segmentation/seeded_hue_segmentation.h>
#include <pcl/console/print.h> // for PCL_ERROR
#include <pcl/search/organized.h> // for OrganizedNeighbor
#include <pcl/search/kdtree.h> // for KdTree
//////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::seededHueSegmentation (const PointCloud<PointXYZRGB> &cloud,
const search::Search<PointXYZRGB>::Ptr &tree,
float tolerance,
PointIndices &indices_in,
PointIndices &indices_out,
float delta_hue)
{
if (tree->getInputCloud ()->size () != cloud.size ())
{
PCL_ERROR("[pcl::seededHueSegmentation] Tree built for a different point cloud "
"dataset (%zu) than the input cloud (%zu)!\n",
static_cast<std::size_t>(tree->getInputCloud()->size()),
static_cast<std::size_t>(cloud.size()));
return;
}
// Create a bool vector of processed point indices, and initialize it to false
std::vector<bool> processed (cloud.size (), false);
Indices nn_indices;
std::vector<float> nn_distances;
// Process all points in the indices vector
for (const auto &i : indices_in.indices)
{
if (processed[i])
continue;
processed[i] = true;
Indices seed_queue;
int sq_idx = 0;
seed_queue.push_back (i);
PointXYZRGB p;
p = cloud[i];
PointXYZHSV h;
PointXYZRGBtoXYZHSV(p, h);
while (sq_idx < static_cast<int> (seed_queue.size ()))
{
int ret = tree->radiusSearch (seed_queue[sq_idx], tolerance, nn_indices, nn_distances, std::numeric_limits<int>::max());
if(ret == -1)
PCL_ERROR("[pcl::seededHueSegmentation] radiusSearch returned error code -1\n");
// Search for sq_idx
if (!ret)
{
sq_idx++;
continue;
}
for (std::size_t j = 1; j < nn_indices.size (); ++j) // nn_indices[0] should be sq_idx
{
if (processed[nn_indices[j]]) // Has this point been processed before ?
continue;
PointXYZRGB p_l;
p_l = cloud[nn_indices[j]];
PointXYZHSV h_l;
PointXYZRGBtoXYZHSV(p_l, h_l);
if (std::fabs(h_l.h - h.h) < delta_hue)
{
seed_queue.push_back (nn_indices[j]);
processed[nn_indices[j]] = true;
}
}
sq_idx++;
}
// Copy the seed queue into the output indices
for (const auto &l : seed_queue)
indices_out.indices.push_back(l);
}
// This is purely esthetical, can be removed for speed purposes
std::sort (indices_out.indices.begin (), indices_out.indices.end ());
}
//////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::seededHueSegmentation (const PointCloud<PointXYZRGB> &cloud,
const search::Search<PointXYZRGBL>::Ptr &tree,
float tolerance,
PointIndices &indices_in,
PointIndices &indices_out,
float delta_hue)
{
if (tree->getInputCloud ()->size () != cloud.size ())
{
PCL_ERROR("[pcl::seededHueSegmentation] Tree built for a different point cloud "
"dataset (%zu) than the input cloud (%zu)!\n",
static_cast<std::size_t>(tree->getInputCloud()->size()),
static_cast<std::size_t>(cloud.size()));
return;
}
// Create a bool vector of processed point indices, and initialize it to false
std::vector<bool> processed (cloud.size (), false);
Indices nn_indices;
std::vector<float> nn_distances;
// Process all points in the indices vector
for (const auto &i : indices_in.indices)
{
if (processed[i])
continue;
processed[i] = true;
Indices seed_queue;
int sq_idx = 0;
seed_queue.push_back (i);
PointXYZRGB p;
p = cloud[i];
PointXYZHSV h;
PointXYZRGBtoXYZHSV(p, h);
while (sq_idx < static_cast<int> (seed_queue.size ()))
{
int ret = tree->radiusSearch (seed_queue[sq_idx], tolerance, nn_indices, nn_distances, std::numeric_limits<int>::max());
if(ret == -1)
PCL_ERROR("[pcl::seededHueSegmentation] radiusSearch returned error code -1\n");
// Search for sq_idx
if (!ret)
{
sq_idx++;
continue;
}
for (std::size_t j = 1; j < nn_indices.size (); ++j) // nn_indices[0] should be sq_idx
{
if (processed[nn_indices[j]]) // Has this point been processed before ?
continue;
PointXYZRGB p_l;
p_l = cloud[nn_indices[j]];
PointXYZHSV h_l;
PointXYZRGBtoXYZHSV(p_l, h_l);
if (std::fabs(h_l.h - h.h) < delta_hue)
{
seed_queue.push_back (nn_indices[j]);
processed[nn_indices[j]] = true;
}
}
sq_idx++;
}
// Copy the seed queue into the output indices
for (const auto &l : seed_queue)
indices_out.indices.push_back(l);
}
// This is purely esthetical, can be removed for speed purposes
std::sort (indices_out.indices.begin (), indices_out.indices.end ());
}
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::SeededHueSegmentation::segment (PointIndices &indices_in, PointIndices &indices_out)
{
if (!initCompute () ||
(input_ && input_->points.empty ()) ||
(indices_ && indices_->empty ()))
{
indices_out.indices.clear ();
return;
}
// Initialize the spatial locator
if (!tree_)
{
if (input_->isOrganized ())
tree_.reset (new pcl::search::OrganizedNeighbor<PointXYZRGB> ());
else
tree_.reset (new pcl::search::KdTree<PointXYZRGB> (false));
}
// Send the input dataset to the spatial locator
tree_->setInputCloud (input_);
seededHueSegmentation (*input_, tree_, static_cast<float> (cluster_tolerance_), indices_in, indices_out, delta_hue_);
deinitCompute ();
}
#endif // PCL_EXTRACT_CLUSTERS_IMPL_H_
pcl::PCLBase< PointXYZRGB >::input_
PointCloudConstPtr input_
The input point cloud dataset.
Definition pcl_base.h:147
pcl::PCLBase< PointXYZRGB >::indices_
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition pcl_base.h:150
pcl::PCLBase< PointXYZRGB >::initCompute
bool initCompute()
This method should get called before starting the actual computation.
Definition pcl_base.hpp:138
pcl::PCLBase< PointXYZRGB >::deinitCompute
bool deinitCompute()
This method should get called after finishing the actual computation.
Definition pcl_base.hpp:175
pcl::PointCloud
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition point_cloud.h:173
pcl::PointCloud::size
std::size_t size() const
Definition point_cloud.h:443
pcl::SeededHueSegmentation::tree_
KdTreePtr tree_
A pointer to the spatial search object.
Definition seeded_hue_segmentation.h:157
pcl::SeededHueSegmentation::delta_hue_
float delta_hue_
The allowed difference on the hue.
Definition seeded_hue_segmentation.h:163
pcl::SeededHueSegmentation::cluster_tolerance_
double cluster_tolerance_
The spatial cluster tolerance as a measure in the L2 Euclidean space.
Definition seeded_hue_segmentation.h:160
pcl::SeededHueSegmentation::segment
void segment(PointIndices &indices_in, PointIndices &indices_out)
Cluster extraction in a PointCloud given by <setInputCloud (), setIndices ()>
Definition seeded_hue_segmentation.hpp:206
pcl::search::KdTree
search::KdTree is a wrapper class which inherits the pcl::KdTree class for performing search function...
Definition kdtree.h:62
pcl::search::OrganizedNeighbor
OrganizedNeighbor is a class for optimized nearest neighbor search in organized projectable point clo...
Definition organized.h:65
pcl::search::Search::Ptr
shared_ptr< pcl::search::Search< PointT > > Ptr
Definition search.h:81
pcl::search::Search::getInputCloud
virtual PointCloudConstPtr getInputCloud() const
Get a pointer to the input point cloud dataset.
Definition search.h:124
pcl::search::Search::radiusSearch
virtual int radiusSearch(const PointT &point, double radius, Indices &k_indices, std::vector< float > &k_sqr_distances, unsigned int max_nn=0) const =0
Search for all the nearest neighbors of the query point in a given radius.
pcl::seededHueSegmentation
void seededHueSegmentation(const PointCloud< PointXYZRGB > &cloud, const search::Search< PointXYZRGB >::Ptr &tree, float tolerance, PointIndices &indices_in, PointIndices &indices_out, float delta_hue=0.0)
Decompose a region of space into clusters based on the Euclidean distance between points.
Definition seeded_hue_segmentation.hpp:49
pcl::PointXYZRGBtoXYZHSV
void PointXYZRGBtoXYZHSV(const PointXYZRGB &in, PointXYZHSV &out)
Convert a XYZRGB point type to a XYZHSV.
Definition point_types_conversion.h:107
pcl::Indices
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition types.h:133
pcl::_PointXYZHSV::h
float h
Definition point_types.hpp:709
pcl::PointIndices
Definition PointIndices.h:12
pcl::PointIndices::indices
Indices indices
Definition PointIndices.h:20
pcl::PointXYZHSV
Definition point_types.hpp:720
pcl::PointXYZRGB
A point structure representing Euclidean xyz coordinates, and the RGB color.
Definition point_types.hpp:623