38 #ifndef PCL_FEATURES_IMPL_MULTISCALE_FEATURE_PERSISTENCE_H_
39 #define PCL_FEATURES_IMPL_MULTISCALE_FEATURE_PERSISTENCE_H_
44 template <
typename Po
intSource,
typename Po
intFeature>
48 distance_metric_ (
L1),
49 feature_estimator_ (),
50 features_at_scale_ (),
51 features_at_scale_vectorized_ (),
53 feature_representation_ (),
54 unique_features_indices_ (),
55 unique_features_table_ ()
64 template <
typename Po
intSource,
typename Po
intFeature>
bool
69 PCL_ERROR (
"[pcl::MultiscaleFeaturePersistence::initCompute] PCLBase::initCompute () failed - no input cloud was given.\n");
72 if (!feature_estimator_)
74 PCL_ERROR (
"[pcl::MultiscaleFeaturePersistence::initCompute] No feature estimator was set\n");
77 if (scale_values_.empty ())
79 PCL_ERROR (
"[pcl::MultiscaleFeaturePersistence::initCompute] No scale values were given\n");
83 mean_feature_.resize (feature_representation_->getNumberOfDimensions ());
90 template <
typename Po
intSource,
typename Po
intFeature>
void
93 features_at_scale_.resize (scale_values_.size ());
94 features_at_scale_vectorized_.resize (scale_values_.size ());
95 for (
size_t scale_i = 0; scale_i < scale_values_.size (); ++scale_i)
98 computeFeatureAtScale (scale_values_[scale_i], feature_cloud);
99 features_at_scale_[scale_i] = feature_cloud;
102 std::vector<std::vector<float> > feature_cloud_vectorized (feature_cloud->points.size ());
103 for (
size_t feature_i = 0; feature_i < feature_cloud->points.size (); ++feature_i)
105 std::vector<float> feature_vectorized (feature_representation_->getNumberOfDimensions ());
106 feature_representation_->vectorize (feature_cloud->points[feature_i], feature_vectorized);
107 feature_cloud_vectorized[feature_i] = feature_vectorized;
109 features_at_scale_vectorized_[scale_i] = 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, static_cast<int> (a.size ()), distance_metric_));
134 template <
typename Po
intSource,
typename Po
intFeature>
void
138 for (
int i = 0; i < feature_representation_->getNumberOfDimensions (); ++i)
139 mean_feature_[i] = 0.0f;
141 float normalization_factor = 0.0f;
142 for (std::vector<std::vector<std::vector<float> > >::iterator scale_it = features_at_scale_vectorized_.begin (); scale_it != features_at_scale_vectorized_.end(); ++scale_it) {
143 normalization_factor +=
static_cast<float> (scale_it->size ());
144 for (std::vector<std::vector<float> >::iterator feature_it = scale_it->begin (); feature_it != scale_it->end (); ++feature_it)
145 for (
int dim_i = 0; dim_i < feature_representation_->getNumberOfDimensions (); ++dim_i)
146 mean_feature_[dim_i] += (*feature_it)[dim_i];
149 for (
int dim_i = 0; dim_i < feature_representation_->getNumberOfDimensions (); ++dim_i)
150 mean_feature_[dim_i] /= normalization_factor;
155 template <
typename Po
intSource,
typename Po
intFeature>
void
158 unique_features_indices_.resize (scale_values_.size ());
159 unique_features_table_.resize (scale_values_.size ());
160 for (
size_t scale_i = 0; scale_i < features_at_scale_vectorized_.size (); ++scale_i)
163 float standard_dev = 0.0;
164 std::vector<float> diff_vector (features_at_scale_vectorized_[scale_i].size ());
165 for (
size_t point_i = 0; point_i < features_at_scale_vectorized_[scale_i].size (); ++point_i)
167 float diff = distanceBetweenFeatures (features_at_scale_vectorized_[scale_i][point_i], mean_feature_);
168 standard_dev += diff * diff;
169 diff_vector[point_i] = diff;
171 standard_dev = sqrtf (standard_dev / static_cast<float> (features_at_scale_vectorized_[scale_i].size ()));
172 PCL_DEBUG (
"[pcl::MultiscaleFeaturePersistence::extractUniqueFeatures] Standard deviation for scale %f is %f\n", scale_values_[scale_i], standard_dev);
175 std::list<size_t> indices_per_scale;
176 std::vector<bool> indices_table_per_scale (features_at_scale_[scale_i]->points.size (),
false);
177 for (
size_t point_i = 0; point_i < features_at_scale_[scale_i]->points.size (); ++point_i)
179 if (diff_vector[point_i] > alpha_ * standard_dev)
181 indices_per_scale.push_back (point_i);
182 indices_table_per_scale[point_i] =
true;
185 unique_features_indices_[scale_i] = indices_per_scale;
186 unique_features_table_[scale_i] = indices_table_per_scale;
192 template <
typename Po
intSource,
typename Po
intFeature>
void
194 boost::shared_ptr<std::vector<int> > &output_indices)
200 PCL_DEBUG (
"[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Computing features ...\n");
201 computeFeaturesAtAllScales ();
204 PCL_DEBUG (
"[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Calculating mean feature ...\n");
205 calculateMeanFeature ();
208 PCL_DEBUG (
"[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Extracting unique features ...\n");
209 extractUniqueFeatures ();
211 PCL_DEBUG (
"[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Determining persistent features between scales ...\n");
227 for (std::list<size_t>::iterator feature_it = unique_features_indices_.front ().begin (); feature_it != unique_features_indices_.front ().end (); ++feature_it)
229 bool present_in_all =
true;
230 for (
size_t scale_i = 0; scale_i < features_at_scale_.size (); ++scale_i)
231 present_in_all = present_in_all && unique_features_table_[scale_i][*feature_it];
235 output_features.
points.push_back (features_at_scale_.front ()->points[*feature_it]);
236 output_indices->push_back (feature_estimator_->getIndices ()->at (*feature_it));
241 output_features.
header = feature_estimator_->getInputCloud ()->header;
242 output_features.
is_dense = feature_estimator_->getInputCloud ()->is_dense;
243 output_features.
width =
static_cast<uint32_t
> (output_features.
points.size ());
244 output_features.
height = 1;
248 #define PCL_INSTANTIATE_MultiscaleFeaturePersistence(InT, Feature) template class PCL_EXPORTS pcl::MultiscaleFeaturePersistence<InT, Feature>;