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 #pragma once
00036
00037 #include "PointMatcher.h"
00038
00040 template<typename T>
00041 struct SamplingSurfaceNormalDataPointsFilter: public PointMatcher<T>::DataPointsFilter
00042 {
00043 typedef PointMatcherSupport::Parametrizable Parametrizable;
00044 typedef PointMatcherSupport::Parametrizable P;
00045 typedef Parametrizable::Parameters Parameters;
00046 typedef Parametrizable::ParameterDoc ParameterDoc;
00047 typedef Parametrizable::ParametersDoc ParametersDoc;
00048 typedef Parametrizable::InvalidParameter InvalidParameter;
00049
00050 typedef typename PointMatcher<T>::Vector Vector;
00051 typedef typename PointMatcher<T>::Matrix Matrix;
00052 typedef typename PointMatcher<T>::DataPoints DataPoints;
00053 typedef typename PointMatcher<T>::DataPoints::InvalidField InvalidField;
00054
00055
00056 inline static const std::string description()
00057 {
00058 return "Subsampling, Normals. This filter decomposes the point-cloud space in boxes, by recursively splitting the cloud through axis-aligned hyperplanes such as to maximize the evenness of the aspect ratio of the box. When the number of points in a box reaches a value knn or lower, the filter computes the center of mass of these points and its normal by taking the eigenvector corresponding to the smallest eigenvalue of all points in the box.";
00059 }
00060 inline static const ParametersDoc availableParameters()
00061 {
00062 return {
00063 {"ratio", "ratio of points to keep with random subsampling. Matrix (normal, density, etc.) will be associated to all points in the same bin.", "0.5", "0.0000001", "1.0", &P::Comp<T>},
00064 {"knn", "determined how many points are used to compute the normals. Direct link with the rapidity of the computation (large = fast). Technically, limit over which a box is splitted in two", "7", "3", "2147483647", &P::Comp<unsigned>},
00065 {"samplingMethod", "if set to 0, random subsampling using the parameter ratio. If set to 1, bin subsampling with the resulting number of points being 1/knn.", "0", "0", "1", &P::Comp<unsigned>},
00066 {"maxBoxDim", "maximum length of a box above which the box is discarded", "inf"},
00067 {"averageExistingDescriptors", "whether the filter keep the existing point descriptors and average them or should it drop them", "1"},
00068 {"keepNormals", "whether the normals should be added as descriptors to the resulting cloud", "1"},
00069 {"keepDensities", "whether the point densities should be added as descriptors to the resulting cloud", "0"},
00070 {"keepEigenValues", "whether the eigen values should be added as descriptors to the resulting cloud", "0"},
00071 {"keepEigenVectors", "whether the eigen vectors should be added as descriptors to the resulting cloud", "0"}
00072 };
00073 }
00074
00075 const T ratio;
00076 const unsigned knn;
00077 const unsigned samplingMethod;
00078 const T maxBoxDim;
00079 const bool averageExistingDescriptors;
00080 const bool keepNormals;
00081 const bool keepDensities;
00082 const bool keepEigenValues;
00083 const bool keepEigenVectors;
00084
00085 public:
00086 SamplingSurfaceNormalDataPointsFilter(const Parameters& params = Parameters());
00087 virtual ~SamplingSurfaceNormalDataPointsFilter() {}
00088 virtual DataPoints filter(const DataPoints& input);
00089 virtual void inPlaceFilter(DataPoints& cloud);
00090
00091 protected:
00092 struct BuildData
00093 {
00094 typedef std::vector<int> Indices;
00095 typedef typename DataPoints::View View;
00096
00097 Indices indices;
00098 Indices indicesToKeep;
00099 Matrix& features;
00100 Matrix& descriptors;
00101 boost::optional<View> normals;
00102 boost::optional<View> densities;
00103 boost::optional<View> eigenValues;
00104 boost::optional<View> eigenVectors;
00105 int outputInsertionPoint;
00106 int unfitPointsCount;
00107
00108 BuildData(Matrix& features, Matrix& descriptors):
00109 features(features),
00110 descriptors(descriptors),
00111 unfitPointsCount(0)
00112 {
00113 const int pointsCount(features.cols());
00114 indices.reserve(pointsCount);
00115 for (int i = 0; i < pointsCount; ++i)
00116 indices.push_back(i);
00117 }
00118 };
00119
00120 struct CompareDim
00121 {
00122 const int dim;
00123 const BuildData& buildData;
00124 CompareDim(const int dim, const BuildData& buildData):dim(dim),buildData(buildData){}
00125 bool operator() (const int& p0, const int& p1)
00126 {
00127 return buildData.features(dim, p0) <
00128 buildData.features(dim, p1);
00129 }
00130 };
00131
00132 protected:
00133 void buildNew(BuildData& data, const int first, const int last, Vector&& minValues, Vector&& maxValues) const;
00134 void fuseRange(BuildData& data, const int first, const int last) const;
00135 };
00136