40 #include "Eigen/Eigenvalues"
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)
154 if (cloud.
times.rows() != 0)
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);
199 data.indices.begin() + first,
200 data.indices.begin() + first + leftCount,
201 data.indices.begin() + last,
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));
229 const int colCount(last-first);
230 const int featDim(
data.features.rows());
233 Matrix d(featDim-1, colCount);
234 for (
int i = 0; i < colCount; ++i)
235 d.col(i) =
data.features.block(0,
data.indices[first+i],featDim-1, 1);
236 const Vector box = d.rowwise().maxCoeff() - d.rowwise().minCoeff();
237 const T boxDim(
box.maxCoeff());
239 if (boxDim > maxBoxDim)
241 data.unfitPointsCount += colCount;
244 const Vector mean = d.rowwise().sum() /
T(colCount);
245 const Matrix NN = (d.colwise() - mean);
248 const Matrix C((NN * NN.transpose()) /
T(colCount));
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();
262 data.unfitPointsCount += colCount;
269 normal = computeNormal<T>(eigenVa, eigenVe);
273 densitie = computeDensity<T>(NN);
279 serialEigVector = serializeEigVec<T>(eigenVe);
282 if(
data.descriptors.rows() != 0)
283 assert(
data.descriptors.cols() != 0);
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];
296 data.indicesToKeep.push_back(k);
300 data.normals->col(k) = normal;
302 (*
data.densities)(0,k) = densitie;
304 data.eigenValues->col(k) = eigenVa;
306 data.eigenVectors->col(k) = serialEigVector;
312 const int k =
data.indices[first];
314 data.indicesToKeep.push_back(k);
315 data.features.col(k).topRows(featDim-1) = mean;
316 data.features(featDim-1, k) = 1;
318 if(
data.descriptors.rows() != 0)
321 if (averageExistingDescriptors)
323 Vector mergedDesc(Vector::Zero(
data.descriptors.rows()));
324 for (
int i = 0; i < colCount; ++i)
325 mergedDesc +=
data.descriptors.col(
data.indices[first+i]);
326 mergedDesc /=
T(colCount);
327 data.descriptors.col(k) = mergedDesc;
334 data.normals->col(k) = normal;
336 (*
data.densities)(0,k) = densitie;
338 data.eigenValues->col(k) = eigenVa;
340 data.eigenVectors->col(k) = serialEigVector;