40 #ifndef PCL_FEATURES_IMPL_MULTISCALE_FEATURE_PERSISTENCE_H_
41 #define PCL_FEATURES_IMPL_MULTISCALE_FEATURE_PERSISTENCE_H_
43 #include <pcl/features/multiscale_feature_persistence.h>
46 template <
typename Po
intSource,
typename Po
intFeature>
49 feature_estimator_ (),
50 features_at_scale_ (),
51 feature_representation_ ()
60 template <
typename Po
intSource,
typename Po
intFeature>
bool
65 PCL_ERROR (
"[pcl::MultiscaleFeaturePersistence::initCompute] PCLBase::initCompute () failed - no input cloud was given.\n");
68 if (!feature_estimator_)
70 PCL_ERROR (
"[pcl::MultiscaleFeaturePersistence::initCompute] No feature estimator was set\n");
73 if (scale_values_.empty ())
75 PCL_ERROR (
"[pcl::MultiscaleFeaturePersistence::initCompute] No scale values were given\n");
79 mean_feature_.resize (feature_representation_->getNumberOfDimensions ());
86 template <
typename Po
intSource,
typename Po
intFeature>
void
89 features_at_scale_.clear ();
90 features_at_scale_.reserve (scale_values_.size ());
91 features_at_scale_vectorized_.clear ();
92 features_at_scale_vectorized_.reserve (scale_values_.size ());
93 for (
float & scale_value : scale_values_)
96 computeFeatureAtScale (scale_value, feature_cloud);
97 features_at_scale_.push_back(feature_cloud);
100 std::vector<std::vector<float> > feature_cloud_vectorized;
101 feature_cloud_vectorized.reserve (feature_cloud->size ());
103 for (
const auto& feature: feature_cloud->points)
105 std::vector<float> feature_vectorized (feature_representation_->getNumberOfDimensions ());
106 feature_representation_->vectorize (feature, feature_vectorized);
107 feature_cloud_vectorized.emplace_back (std::move(feature_vectorized));
109 features_at_scale_vectorized_.emplace_back (std::move(feature_cloud_vectorized));
115 template <
typename Po
intSource,
typename Po
intFeature>
void
117 FeatureCloudPtr &features)
119 feature_estimator_->setRadiusSearch (scale);
120 feature_estimator_->compute (*features);
125 template <
typename Po
intSource,
typename Po
intFeature>
float
127 const std::vector<float> &b)
129 return (
pcl::selectNorm<std::vector<float> > (a, b, a.size (), distance_metric_));
134 template <
typename Po
intSource,
typename Po
intFeature>
void
138 std::fill_n(mean_feature_.begin (), mean_feature_.size (), 0.f);
140 std::size_t normalization_factor = 0;
141 for (
const auto& scale: features_at_scale_vectorized_)
143 normalization_factor += scale.size ();
144 for (
const auto &feature : scale)
145 std::transform(mean_feature_.cbegin (), mean_feature_.cend (),
146 feature.cbegin (), mean_feature_.begin (), std::plus<>{});
149 const float factor = std::max<float>(1, normalization_factor);
150 std::transform(mean_feature_.cbegin(),
151 mean_feature_.cend(),
152 mean_feature_.begin(),
153 [factor](
const auto& mean) {
154 return mean / factor;
160 template <
typename Po
intSource,
typename Po
intFeature>
void
163 unique_features_indices_.clear ();
164 unique_features_table_.clear ();
165 unique_features_indices_.reserve (scale_values_.size ());
166 unique_features_table_.reserve (scale_values_.size ());
168 std::vector<float> diff_vector;
169 std::size_t size = 0;
170 for (
const auto& feature : features_at_scale_vectorized_)
172 size = std::max(size, feature.size());
174 diff_vector.reserve(size);
175 for (std::size_t scale_i = 0; scale_i < features_at_scale_vectorized_.size (); ++scale_i)
178 float standard_dev = 0.0;
181 for (
const auto& feature: features_at_scale_vectorized_[scale_i])
183 float diff = distanceBetweenFeatures (feature, mean_feature_);
184 standard_dev += diff * diff;
185 diff_vector.emplace_back (diff);
187 standard_dev = std::sqrt (standard_dev /
static_cast<float> (features_at_scale_vectorized_[scale_i].size ()));
188 PCL_DEBUG (
"[pcl::MultiscaleFeaturePersistence::extractUniqueFeatures] Standard deviation for scale %f is %f\n", scale_values_[scale_i], standard_dev);
191 std::list<std::size_t> indices_per_scale;
192 std::vector<bool> indices_table_per_scale (features_at_scale_vectorized_[scale_i].size (),
false);
193 for (std::size_t point_i = 0; point_i < features_at_scale_vectorized_[scale_i].size (); ++point_i)
195 if (diff_vector[point_i] > alpha_ * standard_dev)
197 indices_per_scale.emplace_back (point_i);
198 indices_table_per_scale[point_i] =
true;
201 unique_features_indices_.emplace_back (std::move(indices_per_scale));
202 unique_features_table_.emplace_back (std::move(indices_table_per_scale));
208 template <
typename Po
intSource,
typename Po
intFeature>
void
216 PCL_DEBUG (
"[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Computing features ...\n");
217 computeFeaturesAtAllScales ();
220 PCL_DEBUG (
"[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Calculating mean feature ...\n");
221 calculateMeanFeature ();
224 PCL_DEBUG (
"[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Extracting unique features ...\n");
225 extractUniqueFeatures ();
227 PCL_DEBUG (
"[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Determining persistent features between scales ...\n");
243 for (
const auto& feature: unique_features_indices_.front ())
245 bool present_in_all =
true;
246 for (std::size_t scale_i = 0; scale_i < features_at_scale_.size (); ++scale_i)
247 present_in_all = present_in_all && unique_features_table_[scale_i][feature];
251 output_features.
emplace_back ((*features_at_scale_.front ())[feature]);
252 output_indices->emplace_back (feature_estimator_->getIndices ()->at (feature));
257 output_features.
header = feature_estimator_->getInputCloud ()->header;
258 output_features.
is_dense = feature_estimator_->getInputCloud ()->is_dense;
259 output_features.
width = output_features.
size ();
260 output_features.
height = 1;
264 #define PCL_INSTANTIATE_MultiscaleFeaturePersistence(InT, Feature) template class PCL_EXPORTS pcl::MultiscaleFeaturePersistence<InT, Feature>;
DefaultPointRepresentation extends PointRepresentation to define default behavior for common point ty...
Generic class for extracting the persistent features from an input point cloud It can be given any Fe...
void determinePersistentFeatures(FeatureCloud &output_features, pcl::IndicesPtr &output_indices)
Central function that computes the persistent features.
void computeFeaturesAtAllScales()
Method that calls computeFeatureAtScale () for each scale parameter.
MultiscaleFeaturePersistence()
Empty constructor.
typename pcl::PointCloud< PointFeature >::Ptr FeatureCloudPtr
PointCloudConstPtr input_
The input point cloud dataset.
bool is_dense
True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields).
std::uint32_t width
The point cloud width (if organized as an image-structure).
reference emplace_back(Args &&...args)
Emplace a new point in the cloud, at the end of the container.
pcl::PCLHeader header
The point cloud header.
std::uint32_t height
The point cloud height (if organized as an image-structure).
float selectNorm(FloatVectorT a, FloatVectorT b, int dim, NormType norm_type)
Method that calculates any norm type available, based on the norm_type variable.
shared_ptr< Indices > IndicesPtr