Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef PCL_FEATURES_IMPL_MULTISCALE_FEATURE_PERSISTENCE_H_
00039 #define PCL_FEATURES_IMPL_MULTISCALE_FEATURE_PERSISTENCE_H_
00040
00041 #include <pcl/features/multiscale_feature_persistence.h>
00042
00044 template <typename PointSource, typename PointFeature>
00045 pcl::MultiscaleFeaturePersistence<PointSource, PointFeature>::MultiscaleFeaturePersistence () :
00046 scale_values_ (),
00047 alpha_ (0),
00048 distance_metric_ (L1),
00049 feature_estimator_ (),
00050 features_at_scale_ (),
00051 features_at_scale_vectorized_ (),
00052 mean_feature_ (),
00053 feature_representation_ (),
00054 unique_features_indices_ (),
00055 unique_features_table_ ()
00056 {
00057 feature_representation_.reset (new DefaultPointRepresentation<PointFeature>);
00058
00059 input_.reset (new pcl::PointCloud<PointSource> ());
00060 }
00061
00062
00064 template <typename PointSource, typename PointFeature> bool
00065 pcl::MultiscaleFeaturePersistence<PointSource, PointFeature>::initCompute ()
00066 {
00067 if (!PCLBase<PointSource>::initCompute ())
00068 {
00069 PCL_ERROR ("[pcl::MultiscaleFeaturePersistence::initCompute] PCLBase::initCompute () failed - no input cloud was given.\n");
00070 return false;
00071 }
00072 if (!feature_estimator_)
00073 {
00074 PCL_ERROR ("[pcl::MultiscaleFeaturePersistence::initCompute] No feature estimator was set\n");
00075 return false;
00076 }
00077 if (scale_values_.empty ())
00078 {
00079 PCL_ERROR ("[pcl::MultiscaleFeaturePersistence::initCompute] No scale values were given\n");
00080 return false;
00081 }
00082
00083 mean_feature_.resize (feature_representation_->getNumberOfDimensions ());
00084
00085 return true;
00086 }
00087
00088
00090 template <typename PointSource, typename PointFeature> void
00091 pcl::MultiscaleFeaturePersistence<PointSource, PointFeature>::computeFeaturesAtAllScales ()
00092 {
00093 features_at_scale_.resize (scale_values_.size ());
00094 features_at_scale_vectorized_.resize (scale_values_.size ());
00095 for (size_t scale_i = 0; scale_i < scale_values_.size (); ++scale_i)
00096 {
00097 FeatureCloudPtr feature_cloud (new FeatureCloud ());
00098 computeFeatureAtScale (scale_values_[scale_i], feature_cloud);
00099 features_at_scale_[scale_i] = feature_cloud;
00100
00101
00102 std::vector<std::vector<float> > feature_cloud_vectorized (feature_cloud->points.size ());
00103 for (size_t feature_i = 0; feature_i < feature_cloud->points.size (); ++feature_i)
00104 {
00105 std::vector<float> feature_vectorized (feature_representation_->getNumberOfDimensions ());
00106 feature_representation_->vectorize (feature_cloud->points[feature_i], feature_vectorized);
00107 feature_cloud_vectorized[feature_i] = feature_vectorized;
00108 }
00109 features_at_scale_vectorized_[scale_i] = feature_cloud_vectorized;
00110 }
00111 }
00112
00113
00115 template <typename PointSource, typename PointFeature> void
00116 pcl::MultiscaleFeaturePersistence<PointSource, PointFeature>::computeFeatureAtScale (float &scale,
00117 FeatureCloudPtr &features)
00118 {
00119 feature_estimator_->setRadiusSearch (scale);
00120 feature_estimator_->compute (*features);
00121 }
00122
00123
00125 template <typename PointSource, typename PointFeature> float
00126 pcl::MultiscaleFeaturePersistence<PointSource, PointFeature>::distanceBetweenFeatures (const std::vector<float> &a,
00127 const std::vector<float> &b)
00128 {
00129 return (pcl::selectNorm<std::vector<float> > (a, b, static_cast<int> (a.size ()), distance_metric_));
00130 }
00131
00132
00134 template <typename PointSource, typename PointFeature> void
00135 pcl::MultiscaleFeaturePersistence<PointSource, PointFeature>::calculateMeanFeature ()
00136 {
00137
00138 for (int i = 0; i < feature_representation_->getNumberOfDimensions (); ++i)
00139 mean_feature_[i] = 0.0f;
00140
00141 float normalization_factor = 0.0f;
00142 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) {
00143 normalization_factor += static_cast<float> (scale_it->size ());
00144 for (std::vector<std::vector<float> >::iterator feature_it = scale_it->begin (); feature_it != scale_it->end (); ++feature_it)
00145 for (int dim_i = 0; dim_i < feature_representation_->getNumberOfDimensions (); ++dim_i)
00146 mean_feature_[dim_i] += (*feature_it)[dim_i];
00147 }
00148
00149 for (int dim_i = 0; dim_i < feature_representation_->getNumberOfDimensions (); ++dim_i)
00150 mean_feature_[dim_i] /= normalization_factor;
00151 }
00152
00153
00155 template <typename PointSource, typename PointFeature> void
00156 pcl::MultiscaleFeaturePersistence<PointSource, PointFeature>::extractUniqueFeatures ()
00157 {
00158 unique_features_indices_.resize (scale_values_.size ());
00159 unique_features_table_.resize (scale_values_.size ());
00160 for (size_t scale_i = 0; scale_i < features_at_scale_vectorized_.size (); ++scale_i)
00161 {
00162
00163 float standard_dev = 0.0;
00164 std::vector<float> diff_vector (features_at_scale_vectorized_[scale_i].size ());
00165 for (size_t point_i = 0; point_i < features_at_scale_vectorized_[scale_i].size (); ++point_i)
00166 {
00167 float diff = distanceBetweenFeatures (features_at_scale_vectorized_[scale_i][point_i], mean_feature_);
00168 standard_dev += diff * diff;
00169 diff_vector[point_i] = diff;
00170 }
00171 standard_dev = sqrtf (standard_dev / static_cast<float> (features_at_scale_vectorized_[scale_i].size ()));
00172 PCL_DEBUG ("[pcl::MultiscaleFeaturePersistence::extractUniqueFeatures] Standard deviation for scale %f is %f\n", scale_values_[scale_i], standard_dev);
00173
00174
00175 std::list<size_t> indices_per_scale;
00176 std::vector<bool> indices_table_per_scale (features_at_scale_[scale_i]->points.size (), false);
00177 for (size_t point_i = 0; point_i < features_at_scale_[scale_i]->points.size (); ++point_i)
00178 {
00179 if (diff_vector[point_i] > alpha_ * standard_dev)
00180 {
00181 indices_per_scale.push_back (point_i);
00182 indices_table_per_scale[point_i] = true;
00183 }
00184 }
00185 unique_features_indices_[scale_i] = indices_per_scale;
00186 unique_features_table_[scale_i] = indices_table_per_scale;
00187 }
00188 }
00189
00190
00192 template <typename PointSource, typename PointFeature> void
00193 pcl::MultiscaleFeaturePersistence<PointSource, PointFeature>::determinePersistentFeatures (FeatureCloud &output_features,
00194 boost::shared_ptr<std::vector<int> > &output_indices)
00195 {
00196 if (!initCompute ())
00197 return;
00198
00199
00200 PCL_DEBUG ("[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Computing features ...\n");
00201 computeFeaturesAtAllScales ();
00202
00203
00204 PCL_DEBUG ("[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Calculating mean feature ...\n");
00205 calculateMeanFeature ();
00206
00207
00208 PCL_DEBUG ("[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Extracting unique features ...\n");
00209 extractUniqueFeatures ();
00210
00211 PCL_DEBUG ("[pcl::MultiscaleFeaturePersistence::determinePersistentFeatures] Determining persistent features between scales ...\n");
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 for (std::list<size_t>::iterator feature_it = unique_features_indices_.front ().begin (); feature_it != unique_features_indices_.front ().end (); ++feature_it)
00228 {
00229 bool present_in_all = true;
00230 for (size_t scale_i = 0; scale_i < features_at_scale_.size (); ++scale_i)
00231 present_in_all = present_in_all && unique_features_table_[scale_i][*feature_it];
00232
00233 if (present_in_all)
00234 {
00235 output_features.points.push_back (features_at_scale_.front ()->points[*feature_it]);
00236 output_indices->push_back (feature_estimator_->getIndices ()->at (*feature_it));
00237 }
00238 }
00239
00240
00241 output_features.header = feature_estimator_->getInputCloud ()->header;
00242 output_features.is_dense = feature_estimator_->getInputCloud ()->is_dense;
00243 output_features.width = static_cast<uint32_t> (output_features.points.size ());
00244 output_features.height = 1;
00245 }
00246
00247
00248 #define PCL_INSTANTIATE_MultiscaleFeaturePersistence(InT, Feature) template class PCL_EXPORTS pcl::MultiscaleFeaturePersistence<InT, Feature>;
00249
00250 #endif