Program Listing for File OctreeReduction.hpp
↰ Return to documentation for file (include/lvr2/registration/OctreeReduction.hpp)
#ifndef __OCTREE_REDUCTION__
#define __OCTREE_REDUCTION__
#include "lvr2/types/MatrixTypes.hpp"
#include "lvr2/types/PointBuffer.hpp"
#include "lvr2/util/Timestamp.hpp"
#include "lvr2/registration/ReductionAlgorithm.hpp"
#include "lvr2/util/Logging.hpp"
#include <vector>
namespace lvr2
{
enum OctreeType {RANDOM_SAMPLE, NEAREST_CENTER, CENTER};
class OctreeReductionBase
{
public:
OctreeReductionBase() = delete;
OctreeReductionBase(PointBufferPtr pointBuffer, float voxelSize, size_t minPointsPerVoxel)
: m_voxelSize(voxelSize),
m_minPointsPerVoxel(minPointsPerVoxel),
m_numPoints(pointBuffer->numPoints()),
m_pointBuffer(pointBuffer) {}
virtual PointBufferPtr getReducedPoints() = 0;
protected:
OctreeReductionBase(size_t numPoints, float voxelSize, size_t minPointsPerVoxel)
: m_voxelSize(voxelSize),
m_minPointsPerVoxel(minPointsPerVoxel),
m_numPoints(numPoints),
m_pointBuffer(nullptr) {}
std::vector<size_t> m_pointIndices;
PointBufferPtr m_pointBuffer;
float m_voxelSize;
size_t m_minPointsPerVoxel;
size_t m_numPoints;
};
class RandomSampleOctreeReduction : public OctreeReductionBase
{
public:
RandomSampleOctreeReduction(PointBufferPtr pointBuffer, float voxelSize, size_t minPointsPerVoxel);
RandomSampleOctreeReduction(Vector3f* points, size_t& n, float voxelSize, size_t minPointsPerVoxel);
PointBufferPtr getReducedPoints() override;
private:
void init();
void createOctree(size_t start, size_t n, const Vector3f& min, const Vector3f& max, unsigned int level = 0);
size_t splitPoints(size_t start, size_t n, unsigned int axis, float splitValue);
bool* m_flags;
Vector3f* m_points;
};
class NearestCenterOctreeReduction : public OctreeReductionBase
{
public:
NearestCenterOctreeReduction(PointBufferPtr pointBuffer, float voxelSize, size_t minPointsPerVoxel);
PointBufferPtr getReducedPoints() override;
private:
void createOctree(size_t* start, size_t* end, const Vector3f& min, const Vector3f& max, unsigned int level = 0);
size_t* splitPoints(size_t* start, size_t* end, unsigned int axis, float splitValue);
floatArr m_points;
std::vector<size_t> m_samplePointIndices;
};
class OctreeReductionAlgorithm : public ReductionAlgorithm
{
public:
OctreeReductionAlgorithm(float voxelSize, size_t minPoints, OctreeType type = RANDOM_SAMPLE) :
m_octree(nullptr), m_voxelSize(voxelSize), m_minPoints(minPoints), m_reductionType(type) {};
void setPointBuffer(PointBufferPtr ptr) override
{
// Create octree
switch(m_reductionType)
{
case RANDOM_SAMPLE:
m_octree.reset(new RandomSampleOctreeReduction(ptr, m_voxelSize, m_minPoints));
break;
case NEAREST_CENTER:
m_octree.reset(new NearestCenterOctreeReduction(ptr, m_voxelSize, m_minPoints));
break;
default:
m_octree.reset(new RandomSampleOctreeReduction(ptr, m_voxelSize, m_minPoints));
}
m_octree.reset(new RandomSampleOctreeReduction(ptr, m_voxelSize, m_minPoints));
}
PointBufferPtr getReducedPoints() override
{
// Check if an octree instance exists
// Otherwise return empty point buffer
if(m_octree)
{
return m_octree->getReducedPoints();
}
lvr2::logout::get()
<< lvr2::warning << "[OctreeReduction] Cannot get reduced points without point buffer." << lvr2::endl;
return PointBufferPtr(new PointBuffer());
}
private:
std::shared_ptr<OctreeReductionBase> m_octree;
float m_voxelSize;
size_t m_minPoints;
OctreeType m_reductionType;
};
using OctreeReductionAlgorithmPtr = std::shared_ptr<OctreeReductionAlgorithm>;
} // namespace lvr2
#endif