41 #ifndef PCL_FEATURES_IMPL_GFPFH_H_
42 #define PCL_FEATURES_IMPL_GFPFH_H_
44 #include <pcl/features/gfpfh.h>
45 #include <pcl/octree/octree_search.h>
52 template<
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
void
62 output.
header = input_->header;
73 computeFeature (output);
79 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
void
91 std::vector< std::vector<int> > line_histograms;
92 for (std::size_t i = 0; i < occupied_cells.
size (); ++i)
94 Eigen::Vector3f origin = occupied_cells[i].getVector3fMap ();
96 for (std::size_t j = i+1; j < occupied_cells.
size (); ++j)
99 Eigen::Vector3f end = occupied_cells[j].getVector3fMap ();
103 std::vector<int> histogram;
104 for (std::size_t k = 0; k < intersected_cells.
size (); ++k)
107 octree.
voxelSearch (intersected_cells[k], indices);
108 int label = emptyLabel ();
109 if (!indices.empty ())
111 label = getDominantLabel (indices);
113 histogram.push_back (label);
116 line_histograms.push_back(histogram);
120 std::vector< std::vector<int> > transition_histograms;
121 computeTransitionHistograms (line_histograms, transition_histograms);
123 std::vector<float> distances;
124 computeDistancesToMean (transition_histograms, distances);
126 std::vector<float> gfpfh_histogram;
127 computeDistanceHistogram (distances, gfpfh_histogram);
133 std::copy (gfpfh_histogram.cbegin (), gfpfh_histogram.cend (), output[0].histogram);
137 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
void
139 std::vector< std::vector<int> >& transition_histograms)
141 transition_histograms.resize (label_histograms.size ());
143 for (std::size_t i = 0; i < label_histograms.size (); ++i)
145 transition_histograms[i].resize ((getNumberOfClasses () + 2) * (getNumberOfClasses () + 1) / 2, 0);
147 std::vector< std::vector <int> > transitions (getNumberOfClasses () + 1);
148 for (
auto &transition : transitions)
150 transition.resize (getNumberOfClasses () + 1, 0);
153 for (std::size_t k = 1; k < label_histograms[i].size (); ++k)
155 std::uint32_t first_class = label_histograms[i][k-1];
156 std::uint32_t second_class = label_histograms[i][k];
158 if (second_class < first_class)
159 std::swap (first_class, second_class);
161 transitions[first_class][second_class] += 1;
165 std::size_t flat_index = 0;
166 for (std::size_t m = 0; m < transitions.size (); ++m)
167 for (std::size_t n = m; n < transitions[m].size (); ++n)
169 transition_histograms[i][flat_index] = transitions[m][n];
173 assert (flat_index == transition_histograms[i].size ());
178 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
void
180 std::vector<float>& distances)
182 distances.resize (transition_histograms.size ());
184 std::vector<float> mean_histogram;
185 computeMeanHistogram (transition_histograms, mean_histogram);
187 for (std::size_t i = 0; i < transition_histograms.size (); ++i)
189 float d = computeHIKDistance (transition_histograms[i], mean_histogram);
195 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
void
197 std::vector<float>& histogram)
199 std::vector<float>::const_iterator min_it, max_it;
200 std::tie (min_it, max_it) = std::minmax_element (distances.cbegin (), distances.cend ());
201 assert (min_it != distances.cend ());
202 assert (max_it != distances.cend ());
204 const float min_value = *min_it;
205 const float max_value = *max_it;
207 histogram.resize (descriptorSize (), 0);
209 const float range = max_value - min_value;
211 using binSizeT = decltype(descriptorSize());
212 const binSizeT max_bin = descriptorSize () - 1;
213 for (
const float &
distance : distances)
215 const auto raw_bin = descriptorSize () * (
distance - min_value) / range;
216 const auto bin = std::min<binSizeT> (max_bin,
static_cast<binSizeT
> (std::floor (raw_bin)));
222 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
void
224 std::vector<float>& mean_histogram)
226 assert (histograms.size () > 0);
228 mean_histogram.resize (histograms[0].size (), 0);
229 for (
const auto &histogram : histograms)
230 for (std::size_t j = 0; j < histogram.size (); ++j)
231 mean_histogram[j] +=
static_cast<float> (histogram[j]);
233 for (
float &i : mean_histogram)
234 i /=
static_cast<float> (histograms.size ());
238 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT>
float
240 const std::vector<float>& mean_histogram)
242 assert (histogram.size () == mean_histogram.size ());
245 for (std::size_t i = 0; i < histogram.size (); ++i)
246 norm += std::min (
static_cast<float> (histogram[i]), mean_histogram[i]);
248 norm /=
static_cast<float> (histogram.size ());
253 template <
typename Po
intInT,
typename Po
intNT,
typename Po
intOutT> std::uint32_t
256 std::vector<std::uint32_t> counts (getNumberOfClasses () + 1, 0);
257 for (
const auto &nn_index : indices)
259 std::uint32_t label = (*labels_)[nn_index].label;
263 const auto max_it = std::max_element (counts.cbegin (), counts.cend ());
264 if (max_it == counts.end ())
265 return (emptyLabel ());
270 #define PCL_INSTANTIATE_GFPFHEstimation(T,NT,OutT) template class PCL_EXPORTS pcl::GFPFHEstimation<T,NT,OutT>;
Feature represents the base feature class.
void computeDistancesToMean(const std::vector< std::vector< int > > &transition_histograms, std::vector< float > &distances)
Compute the distance of each transition histogram to the mean.
void computeTransitionHistograms(const std::vector< std::vector< int > > &label_histograms, std::vector< std::vector< int > > &transition_histograms)
Compute the fixed-length histograms of transitions.
std::uint32_t getDominantLabel(const pcl::Indices &indices)
Return the dominant label of a set of points.
void compute(PointCloudOut &output)
Overloaded computed method from pcl::Feature.
void computeMeanHistogram(const std::vector< std::vector< int > > &histograms, std::vector< float > &mean_histogram)
Compute the mean histogram of the given set of histograms.
float computeHIKDistance(const std::vector< int > &histogram, const std::vector< float > &mean_histogram)
Return the Intersection Kernel distance between two histograms.
void computeDistanceHistogram(const std::vector< float > &distances, std::vector< float > &histogram)
Compute the binned histogram of distance values.
void computeFeature(PointCloudOut &output) override
Estimate the Point Feature Histograms (PFH) descriptors at a set of points given by <setInputCloud ()...
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields).
void resize(std::size_t count)
Resizes the container to contain count elements.
std::uint32_t width
The point cloud width (if organized as an image-structure).
pcl::PCLHeader header
The point cloud header.
std::uint32_t height
The point cloud height (if organized as an image-structure).
void clear()
Removes all points in a cloud and sets the width and height to 0.
std::vector< PointT, Eigen::aligned_allocator< PointT > > VectorType
uindex_t getOccupiedVoxelCenters(AlignedPointTVector &voxel_center_list_arg) const
Get a PointT vector of centers of all occupied voxels.
void setInputCloud(const PointCloudConstPtr &cloud_arg, const IndicesConstPtr &indices_arg=IndicesConstPtr())
Provide a pointer to the input data set.
void addPointsFromInputCloud()
Add points from input point cloud to octree.
uindex_t getApproxIntersectedVoxelCentersBySegment(const Eigen::Vector3f &origin, const Eigen::Vector3f &end, AlignedPointTVector &voxel_center_list, float precision=0.2)
Get a PointT vector of centers of voxels intersected by a line segment.
Octree pointcloud search class
bool voxelSearch(const PointT &point, Indices &point_idx_data)
Search for neighbors within a voxel at given point.
float distance(const PointT &p1, const PointT &p2)
IndicesAllocator<> Indices
Type used for indices in PCL.