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
00039
00040 #ifndef PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_
00041 #define PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_
00042
00043 #include <pcl/filters/statistical_outlier_removal.h>
00044 #include <pcl/common/io.h>
00045
00047 template <typename PointT> void
00048 pcl::StatisticalOutlierRemoval<PointT>::applyFilter (PointCloud &output)
00049 {
00050 std::vector<int> indices;
00051 if (keep_organized_)
00052 {
00053 bool temp = extract_removed_indices_;
00054 extract_removed_indices_ = true;
00055 applyFilterIndices (indices);
00056 extract_removed_indices_ = temp;
00057
00058 output = *input_;
00059 for (int rii = 0; rii < static_cast<int> (removed_indices_->size ()); ++rii)
00060 output.points[(*removed_indices_)[rii]].x = output.points[(*removed_indices_)[rii]].y = output.points[(*removed_indices_)[rii]].z = user_filter_value_;
00061 if (!pcl_isfinite (user_filter_value_))
00062 output.is_dense = false;
00063 }
00064 else
00065 {
00066 applyFilterIndices (indices);
00067 copyPointCloud (*input_, indices, output);
00068 }
00069 }
00070
00072 template <typename PointT> void
00073 pcl::StatisticalOutlierRemoval<PointT>::applyFilterIndices (std::vector<int> &indices)
00074 {
00075
00076 if (!searcher_)
00077 {
00078 if (input_->isOrganized ())
00079 searcher_.reset (new pcl::search::OrganizedNeighbor<PointT> ());
00080 else
00081 searcher_.reset (new pcl::search::KdTree<PointT> (false));
00082 }
00083 searcher_->setInputCloud (input_);
00084
00085
00086 std::vector<int> nn_indices (mean_k_);
00087 std::vector<float> nn_dists (mean_k_);
00088 std::vector<float> distances (indices_->size ());
00089 indices.resize (indices_->size ());
00090 removed_indices_->resize (indices_->size ());
00091 int oii = 0, rii = 0;
00092
00093
00094 int valid_distances = 0;
00095 for (int iii = 0; iii < static_cast<int> (indices_->size ()); ++iii)
00096 {
00097 if (!pcl_isfinite (input_->points[(*indices_)[iii]].x) ||
00098 !pcl_isfinite (input_->points[(*indices_)[iii]].y) ||
00099 !pcl_isfinite (input_->points[(*indices_)[iii]].z))
00100 {
00101 distances[iii] = 0.0;
00102 continue;
00103 }
00104
00105
00106 if (searcher_->nearestKSearch ((*indices_)[iii], mean_k_ + 1, nn_indices, nn_dists) == 0)
00107 {
00108 distances[iii] = 0.0;
00109 PCL_WARN ("[pcl::%s::applyFilter] Searching for the closest %d neighbors failed.\n", getClassName ().c_str (), mean_k_);
00110 continue;
00111 }
00112
00113
00114 double dist_sum = 0.0;
00115 for (int k = 1; k < mean_k_ + 1; ++k)
00116 dist_sum += sqrt (nn_dists[k]);
00117 distances[iii] = static_cast<float> (dist_sum / mean_k_);
00118 valid_distances++;
00119 }
00120
00121
00122 double sum = 0, sq_sum = 0;
00123 for (size_t i = 0; i < distances.size (); ++i)
00124 {
00125 sum += distances[i];
00126 sq_sum += distances[i] * distances[i];
00127 }
00128 double mean = sum / static_cast<double>(valid_distances);
00129 double variance = (sq_sum - sum * sum / static_cast<double>(valid_distances)) / (static_cast<double>(valid_distances) - 1);
00130 double stddev = sqrt (variance);
00131
00132
00133 double distance_threshold = mean + std_mul_ * stddev;
00134
00135
00136 for (int iii = 0; iii < static_cast<int> (indices_->size ()); ++iii)
00137 {
00138
00139
00140 if ((!negative_ && distances[iii] > distance_threshold) || (negative_ && distances[iii] <= distance_threshold))
00141 {
00142 if (extract_removed_indices_)
00143 (*removed_indices_)[rii++] = (*indices_)[iii];
00144 continue;
00145 }
00146
00147
00148 indices[oii++] = (*indices_)[iii];
00149 }
00150
00151
00152 indices.resize (oii);
00153 removed_indices_->resize (rii);
00154 }
00155
00156 #define PCL_INSTANTIATE_StatisticalOutlierRemoval(T) template class PCL_EXPORTS pcl::StatisticalOutlierRemoval<T>;
00157
00158 #endif // PCL_FILTERS_IMPL_STATISTICAL_OUTLIER_REMOVAL_H_
00159