29 int newNumberOfPoints,
43 unsigned char bestLevel =
47 inputCloud, bestLevel, resamplingMethod, progressCb,
octree);
49 if (!inputOctree)
delete octree;
75 if (!inputOctree)
delete octree;
81 void* additionalParameters[2] = {
82 reinterpret_cast<void*
>(cloud),
83 reinterpret_cast<void*
>(&resamplingMethod)};
88 progressCb,
"Cloud Resampling") == 0) {
94 if (!inputOctree)
delete octree;
101 int newNumberOfPoints,
115 unsigned char bestLevel =
119 inputCloud, bestLevel, subsamplingMethod, progressCb,
octree);
121 if (!inputOctree)
delete octree;
123 return subsampledCloud;
147 if (!inputOctree)
delete octree;
153 void* additionalParameters[2] = {
154 reinterpret_cast<void*
>(cloud),
155 reinterpret_cast<void*
>(&subsamplingMethod)};
160 progressCb,
"Cloud Subsampling") == 0) {
166 if (!inputOctree)
delete octree;
175 if (every_k_points <= 1) {
179 unsigned pointCount = inputCloud->
size();
181 unsigned newNumberOfPoints = pointCount / every_k_points + 2;
185 if (!newCloud->
reserve(newNumberOfPoints)) {
192 for (
unsigned i = 0; i < pointCount; i += every_k_points) {
204 unsigned newNumberOfPoints,
208 unsigned theCloudSize = inputCloud->
size();
218 if (theCloudSize <= newNumberOfPoints) {
222 unsigned pointsToRemove = theCloudSize - newNumberOfPoints;
223 std::random_device rd;
224 std::mt19937 gen(rd());
229 progressCb->
setInfo(
"Random subsampling");
237 unsigned lastPointIndex = theCloudSize - 1;
238 for (
unsigned i = 0; i < pointsToRemove; ++i) {
239 std::uniform_int_distribution<unsigned>
dist(0, lastPointIndex);
240 unsigned index =
dist(gen);
241 newCloud->
swap(index, lastPointIndex);
244 if (progressCb && !normProgress.
oneStep()) {
251 newCloud->
resize(newNumberOfPoints);
263 unsigned cloudSize = inputCloud->
size();
268 if (
octree->
build() <
static_cast<int>(cloudSize)) {
277 const unsigned c_reserveStep = 65536;
279 if (!inputOctree)
delete octree;
286 markers.resize(cloudSize, 1);
287 }
catch (
const std::bad_alloc&) {
288 if (!inputOctree)
delete octree;
295 std::vector<unsigned char> bestOctreeLevel;
296 bool modParamsEnabled = modParams.
enabled;
297 ScalarType sfMin = 0, sfMax = 0;
306 modParamsEnabled =
false;
310 sfMin * modParams.
a + modParams.
b);
312 sfMax * modParams.
a + modParams.
b);
313 unsigned char level0 =
316 unsigned char level1 =
320 bestOctreeLevel.push_back(level0);
321 if (level1 != level0) {
323 std::size_t levelCount =
324 (level1 < level0 ? level0 - level1
327 assert(levelCount != 0);
329 for (std::size_t i = 1; i < levelCount - 1;
333 sfMin + i * ((sfMax - sfMin) / levelCount);
336 sfVal * modParams.
a + modParams.
b);
337 unsigned char level =
340 bestOctreeLevel.push_back(level);
343 bestOctreeLevel.push_back(level1);
346 unsigned char defaultLevel =
349 bestOctreeLevel.push_back(defaultLevel);
351 }
catch (
const std::bad_alloc&) {
366 sprintf(buffer,
"Points: %u\nMin dist.: %f", cloudSize,
378 assert(!bestOctreeLevel.empty());
379 unsigned char octreeLevel = bestOctreeLevel.front();
382 for (
unsigned i = 0; i < cloudSize; i++) {
384 if (markers[i] != 0) {
389 if (modParamsEnabled) {
394 sfVal * modParams.
a + modParams.
b);
396 std::size_t levelIndex =
static_cast<std::size_t
>(
397 bestOctreeLevel.size() *
398 ((sfVal - sfMin) / (sfMax - sfMin)));
399 if (levelIndex == bestOctreeLevel.size()) --levelIndex;
402 minDistBetweenPoints = minDistance;
411 *P, minDistBetweenPoints, neighbours,
octreeLevel);
412 for (DgmOctree::NeighboursSet::iterator it = neighbours.begin();
413 it != neighbours.end(); ++it)
414 if (it->pointIndex != i) markers[it->pointIndex] = 0;
435 if (progressCb && !normProgress.
oneStep()) {
448 sampledCloud =
nullptr;
470 if (!inputCloud || knn <= 0 ||
471 inputCloud->
size() <=
static_cast<unsigned>(knn)) {
489 for (
unsigned step = 0; step < 1; ++step)
491 unsigned pointCount = inputCloud->
size();
493 std::vector<PointCoordinateType> meanDistances;
495 meanDistances.resize(pointCount, 0);
496 }
catch (
const std::bad_alloc&) {
500 double avgDist = 0, stdDev = 0;
505 void* additionalParameters[] = {
506 reinterpret_cast<void*
>(&knn),
507 reinterpret_cast<void*
>(&meanDistances)};
514 additionalParameters,
true, progressCb,
515 "SOR filter") == 0) {
522 double sumSquareDist = 0;
523 for (
unsigned i = 0; i < pointCount; ++i) {
524 sumDist += meanDistances[i];
525 sumSquareDist += meanDistances[i] * meanDistances[i];
527 avgDist = sumDist / pointCount;
529 std::abs(sumSquareDist / pointCount - avgDist * avgDist));
535 double maxDist = avgDist + nSigma * stdDev;
538 if (!filteredCloud->
reserve(pointCount)) {
540 delete filteredCloud;
541 filteredCloud =
nullptr;
545 for (
unsigned i = 0; i < pointCount; ++i) {
546 if (meanDistances[i] <= maxDist) {
560 return filteredCloud;
567 bool removeIsolatedPoints ,
570 bool useAbsoluteError ,
571 double absoluteError ,
574 if (!inputCloud || inputCloud->
size() < 2 || (useKnn && knn <= 0) ||
575 (!useKnn && kernelRadius <= 0)) {
592 unsigned pointCount = inputCloud->
size();
593 if (!filteredCloud->
reserve(pointCount)) {
595 if (!inputOctree)
delete octree;
596 delete filteredCloud;
601 void* additionalParameters[] = {
602 reinterpret_cast<void*
>(filteredCloud),
603 reinterpret_cast<void*
>(&kernelRadius),
604 reinterpret_cast<void*
>(&nSigma),
605 reinterpret_cast<void*
>(&removeIsolatedPoints),
606 reinterpret_cast<void*
>(&useKnn),
607 reinterpret_cast<void*
>(&knn),
608 reinterpret_cast<void*
>(&useAbsoluteError),
609 reinterpret_cast<void*
>(&absoluteError)};
620 true, progressCb,
"Noise filter") == 0) {
622 delete filteredCloud;
623 filteredCloud =
nullptr;
635 return filteredCloud;
640 void** additionalParameters,
648 if (!P)
return false;
667 void** additionalParameters,
674 unsigned selectedPointIndex = 0;
678 selectedPointIndex = (
static_cast<unsigned>(rand()) % pointsCount);
692 for (
unsigned i = 1; i < pointsCount; ++i) {
695 if (squareDist < minSquareDist) {
696 selectedPointIndex = i;
697 minSquareDist = squareDist;
712 void** additionalParameters,
718 double nSigma = *
static_cast<double*
>(additionalParameters[2]);
719 bool removeIsolatedPoints = *
static_cast<bool*
>(additionalParameters[3]);
720 bool useKnn = *
static_cast<bool*
>(additionalParameters[4]);
721 int knn = *
static_cast<int*
>(additionalParameters[5]);
722 bool useAbsoluteError = *
static_cast<bool*
>(additionalParameters[6]);
723 double absoluteError = *
static_cast<double*
>(additionalParameters[7]);
740 for (
unsigned i = 0; i < n; ++i) {
747 unsigned neighborCount = 0;
756 nNSS, kernelRadius,
false);
764 unsigned localIndex = 0;
765 while (localIndex < neighborCount &&
770 assert(localIndex < neighborCount);
779 unsigned realNeighborCount = neighborCount - 1;
788 double maxD = absoluteError;
789 if (!useAbsoluteError) {
793 for (
unsigned j = 0; j < realNeighborCount; ++j) {
809 computePoint2PlaneDistance(
820 if (!removeIsolatedPoints) {
837 void** additionalParameters,
839 int knn = *
static_cast<int*
>(additionalParameters[0]);
840 std::vector<PointCoordinateType>& meanDistances =
841 *
static_cast<std::vector<PointCoordinateType>*
>(
842 additionalParameters[1]);
847 nNSS.minNumberOfNeighbors =
859 for (
unsigned i = 0; i < n; ++i) {
867 for (
int j = 0; j < knn; ++j) {
868 if (nNSS.pointsInNeighbourhood[j].pointIndex != globalIndex) {
869 sumDist += sqrt(nNSS.pointsInNeighbourhood[j].squareDistd);
875 meanDistances[globalIndex] =
float PointCoordinateType
Type of the coordinates of a (N-D) point.
A kind of ReferenceCloud based on the DgmOctree::NeighboursSet structure.
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
The octree structure used throughout the library.
GenericIndexedCloudPersist * associatedCloud() const
Returns the associated cloud.
unsigned char findBestLevelForAGivenCellNumber(unsigned indicativeNumberOfCells) const
void getCellPos(CellCode code, unsigned char level, Tuple3i &cellPos, bool isCodeTruncated) const
unsigned findNearestNeighborsStartingFromCell(NearestNeighboursSearchStruct &nNSS, bool getOnlyPointsWithValidScalar=false) const
unsigned char findBestLevelForAGivenNeighbourhoodSizeExtraction(PointCoordinateType radius) const
int findNeighborsInASphereStartingFromCell(NearestNeighboursSearchStruct &nNSS, double radius, bool sortValues=true) const
Advanced form of the nearest neighbours search algorithm (in a sphere)
const PointCoordinateType & getCellSize(unsigned char level) const
Returns the octree cells length for a given level of subdivision.
int getPointsInSphericalNeighbourhood(const CCVector3 &sphereCenter, PointCoordinateType radius, NeighboursSet &neighbours, unsigned char level) const
Returns the points falling inside a sphere.
void computeCellCenter(CellCode code, unsigned char level, CCVector3 ¢er, bool isCodeTruncated=false) const
unsigned executeFunctionForAllCellsAtLevel(unsigned char level, octreeCellFunc func, void **additionalParameters, bool multiThread=false, GenericProgressCallback *progressCb=nullptr, const char *functionTitle=nullptr, int maxThreadCount=0)
int build(GenericProgressCallback *progressCb=nullptr)
Builds the structure.
const unsigned & getCellNumber(unsigned char level) const
Returns the number of cells for a given level of subdivision.
std::vector< PointDescriptor > NeighboursSet
A set of neighbours.
unsigned char findBestLevelForAGivenPopulationPerCell(unsigned indicativeNumberOfPointsPerCell) const
virtual unsigned size() const =0
Returns the number of points.
virtual ScalarType getPointScalarValue(unsigned pointIndex) const =0
Returns the ith point associated scalar value.
A generic 3D point cloud with index-based and presistent access to points.
A generic 3D point cloud with index-based point access.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
virtual void stop()=0
Notifies the fact that the process has ended.
virtual void setInfo(const char *infoStr)=0
Notifies some information about the ongoing process.
virtual void setMethodTitle(const char *methodTitle)=0
Notifies the algorithm title.
virtual bool textCanBeEdited() const
Returns whether the dialog title and info can be updated or not.
virtual void update(float percent)=0
Notifies the algorithm progress.
const PointCoordinateType * getLSPlane()
Returns best interpolating plane equation (Least-square)
const CCVector3 * getGravityCenter()
Returns gravity center.
bool steps(unsigned n)
Increments total progress value of more than a single unit.
bool oneStep()
Increments total progress value of a single unit.
virtual bool reserve(unsigned newCapacity)
Reserves memory for the point database.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
A very simple point cloud (no point duplication)
virtual void swap(unsigned i, unsigned j)
Swaps two point references.
virtual bool addPointIndex(unsigned globalIndex)
Point global index insertion mechanism.
unsigned size() const override
Returns the number of points.
virtual unsigned getPointGlobalIndex(unsigned localIndex) const
virtual bool resize(unsigned n)
Presets the size of the vector used to store point references.
virtual unsigned capacity() const
Returns max capacity.
virtual bool reserve(unsigned n)
Reserves some memory for hosting the point references.
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
static bool ValidValue(ScalarType value)
Returns whether a scalar value is valid or not.
__host__ __device__ int2 abs(int2 v)
static double dist(double x1, double y1, double x2, double y2)
static void error(char *msg)
::ccPointCloud PointCloud
Generic file read and write utility for python interface.
void swap(cloudViewer::core::SmallVectorImpl< T > &LHS, cloudViewer::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
double stddev(std::vector< double > const &func)
ReferenceCloud * points
Set of points lying inside this cell.
const DgmOctree * parentOctree
Octree to which the cell belongs.
unsigned char level
Cell level of subdivision.
CellCode truncatedCode
Truncated cell code.