40 #include "Eigen/Eigenvalues"
53 PointMatcher<T>::DataPointsFilter(
"SamplingSurfaceNormalDataPointsFilter",
59 averageExistingDescriptors(
Parametrizable::
get<bool>(
"averageExistingDescriptors")),
74 inPlaceFilter(output);
87 const int pointsCount(cloud.
features.cols());
88 const int featDim(cloud.
features.rows());
93 if (averageExistingDescriptors)
97 for(
unsigned int i = 0; i < labelDim ; ++i)
99 if (insertDim != descDim)
100 throw InvalidField(
"SamplingSurfaceNormalDataPointsFilter: Error, descriptor labels do not match descriptor data");
104 const int dimNormals(featDim-1);
105 const int dimDensities(1);
106 const int dimEigValues(featDim-1);
107 const int dimEigVectors((featDim-1)*(featDim-1));
112 cloudLabels.push_back(Label(
"normals", dimNormals));
114 cloudLabels.push_back(Label(
"densities", dimDensities));
116 cloudLabels.push_back(Label(
"eigValues", dimEigValues));
117 if (keepEigenVectors)
118 cloudLabels.push_back(Label(
"eigVectors", dimEigVectors));
132 if (keepEigenVectors)
139 cloud.
features.rowwise().minCoeff(),
147 for (
int i = 0; i < ptsOut; ++i)
163 cloud.
features.conservativeResize(Eigen::NoChange, ptsOut);
164 cloud.
descriptors.conservativeResize(Eigen::NoChange, ptsOut);
173 BuildData& data,
const int first,
const int last,
178 const int count(last - first);
179 if (count <=
int(knn))
182 fuseRange(data, first, last);
190 const int cutDim = argMax<T>(maxValues - minValues);
193 const int rightCount(count/2);
194 const int leftCount(count - rightCount);
195 assert(last - rightCount == first + leftCount);
200 data.
indices.begin() + first + leftCount,
206 const int cutIndex(data.
indices[first+leftCount]);
207 const T cutVal(data.
features(cutDim, cutIndex));
210 Vector leftMaxValues(maxValues);
211 leftMaxValues[cutDim] = cutVal;
213 Vector rightMinValues(minValues);
214 rightMinValues[cutDim] = cutVal;
217 buildNew(data, first, first + leftCount,
218 std::forward<Vector>(minValues), std::move(leftMaxValues));
219 buildNew(data, first + leftCount, last,
220 std::move(rightMinValues), std::forward<Vector>(maxValues));
225 BuildData& data,
const int first,
const int last)
const
229 const int colCount(last-first);
230 const int featDim(data.
features.rows());
234 for (
int i = 0; i < colCount; ++i)
236 const Vector box =
d.rowwise().maxCoeff() -
d.rowwise().minCoeff();
237 const T boxDim(box.maxCoeff());
239 if (boxDim > maxBoxDim)
244 const Vector mean =
d.rowwise().sum() / T(colCount);
245 const Matrix NN = (
d.colwise() - mean);
248 const Matrix C(NN * NN.transpose());
249 Vector eigenVa = Vector::Identity(featDim-1, 1);
250 Matrix eigenVe = Matrix::Identity(featDim-1, featDim-1);
252 if(keepNormals || keepEigenValues || keepEigenVectors)
254 if(C.fullPivHouseholderQr().rank()+1 >= featDim-1)
256 const Eigen::EigenSolver<Matrix> solver(C);
257 eigenVa = solver.eigenvalues().real();
258 eigenVe = solver.eigenvectors().real();
269 normal = computeNormal<T>(eigenVa, eigenVe);
273 densitie = computeDensity<T>(NN);
279 serialEigVector = serializeEigVec<T>(eigenVe);
286 if(samplingMethod == 0)
288 for(
int i=0; i<colCount; ++i)
290 const float r = (float)std::rand()/(float)RAND_MAX;
294 const int k = data.
indices[first+i];
312 const int k = data.
indices[first];
315 data.
features.col(k).topRows(featDim-1) = mean;
321 if (averageExistingDescriptors)
324 for (
int i = 0; i < colCount; ++i)
326 mergedDesc /= T(colCount);