8 #include <unordered_map>
22 template <
typename InputPo
intCloud,
typename OutputPo
intCloud = InputPo
intCloud>
23 std::shared_ptr<OutputPointCloud>
voxelgrid_sampling(
const InputPointCloud& points,
double leaf_size) {
25 return std::make_shared<OutputPointCloud>();
28 const double inv_leaf_size = 1.0 / leaf_size;
30 constexpr std::uint64_t invalid_coord = std::numeric_limits<std::uint64_t>::max();
31 constexpr
int coord_bit_size = 21;
32 constexpr
size_t coord_bit_mask = (1 << 21) - 1;
33 constexpr
int coord_offset = 1 << (coord_bit_size - 1);
35 std::vector<std::pair<std::uint64_t, size_t>> coord_pt(
traits::size(points));
38 if ((coord < 0).any() || (coord > coord_bit_mask).any()) {
39 std::cerr <<
"warning: voxel coord is out of range!!" << std::endl;
40 coord_pt[i] = {invalid_coord, i};
45 const std::uint64_t bits =
46 (
static_cast<std::uint64_t
>(coord[0] & coord_bit_mask) << (coord_bit_size * 0)) |
47 (
static_cast<std::uint64_t
>(coord[1] & coord_bit_mask) << (coord_bit_size * 1)) |
48 (
static_cast<std::uint64_t
>(coord[2] & coord_bit_mask) << (coord_bit_size * 2));
49 coord_pt[i] = {bits, i};
53 const auto compare = [](
const auto& lhs,
const auto& rhs) {
return lhs.first < rhs.first; };
54 std::sort(coord_pt.begin(), coord_pt.end(), compare);
56 auto downsampled = std::make_shared<OutputPointCloud>();
59 size_t num_points = 0;
60 Eigen::Vector4d sum_pt =
traits::point(points, coord_pt.front().second);
62 if (coord_pt[i].first == invalid_coord) {
66 if (coord_pt[i - 1].first != coord_pt[i].first) {
84 template <
typename InputPo
intCloud,
typename OutputPo
intCloud = InputPo
intCloud,
typename RNG = std::mt19937>
85 std::shared_ptr<OutputPointCloud>
random_sampling(
const InputPointCloud& points,
size_t num_samples, RNG& rng) {
87 std::cerr <<
"warning: empty input points!!" << std::endl;
88 return std::make_shared<OutputPointCloud>();
92 std::iota(indices.begin(), indices.end(), 0);
94 if (num_samples >= indices.size()) {
95 std::cerr <<
"warning: num_samples >= points.size()!! (" << num_samples <<
" vs " <<
traits::size(points) <<
")" << std::endl;
96 num_samples = indices.size();
99 std::vector<size_t> samples(num_samples);
100 std::sample(indices.begin(), indices.end(), samples.begin(), num_samples, rng);
102 auto downsampled = std::make_shared<OutputPointCloud>();
105 for (
size_t i = 0; i < num_samples; i++) {
size_t size(const T &points)
Get the number of points.
Definition: traits.hpp:16
auto point(const T &points, size_t i)
Get i-th point. 4D vector is used to take advantage of SIMD intrinsics. The last element must be fill...
Definition: traits.hpp:40
void set_point(T &points, size_t i, const Eigen::Vector4d &pt)
Set i-th point. (x, y, z, 1)
Definition: traits.hpp:64
void resize(T &points, size_t n)
Resize the point cloud (this function should resize all attributes)
Definition: traits.hpp:58
Definition: flat_container.hpp:12
std::shared_ptr< OutputPointCloud > voxelgrid_sampling(const InputPointCloud &points, double leaf_size)
Voxelgrid downsampling. This function computes exact average of points in each voxel,...
Definition: downsampling.hpp:23
std::shared_ptr< OutputPointCloud > random_sampling(const InputPointCloud &points, size_t num_samples, RNG &rng)
Random downsampling.
Definition: downsampling.hpp:85
Eigen::Array4i fast_floor(const Eigen::Array4d &pt)
Fast floor (https://stackoverflow.com/questions/824118/why-is-floor-so-slow).
Definition: fast_floor.hpp:12