cpp-toolbox  0.0.1
A toolbox library for C++
Loading...
Searching...
No Matches
random_downsampling_impl.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <numeric>
5#include <vector>
6
8
9namespace toolbox::pcl
10{
11
12template<typename DataType>
14 const point_cloud& cloud)
15{
16 m_cloud = std::make_shared<point_cloud>(cloud);
17 return m_cloud->size();
18}
19
20template<typename DataType>
22 const point_cloud_ptr& cloud)
23{
24 m_cloud = cloud;
25 return m_cloud ? m_cloud->size() : 0U;
26}
27
28template<typename DataType>
30{
31 m_enable_parallel = enable;
32}
33
34template<typename DataType>
37{
38 auto output = std::make_shared<point_cloud>();
39 filter_impl(output);
40 return *output;
41}
42
43template<typename DataType>
45{
46 if (!output)
47 return;
48 if (!m_cloud || m_cloud->empty()) {
49 output->clear();
50 return;
51 }
52
53 const std::size_t input_size = m_cloud->size();
54 std::size_t sample_count =
55 static_cast<std::size_t>(std::floor(input_size * m_ration));
56 sample_count = std::min(sample_count, input_size);
57 if (sample_count == 0) {
58 output->clear();
59 return;
60 }
61
62 // 使用蓄水池采样算法(Reservoir Sampling)代替全数组洗牌
63 std::vector<std::size_t> indices;
64 indices.reserve(sample_count);
65
66 // 如果采样率很高或点云较小,使用传统方法可能更快
67 if (sample_count > input_size / 2 || input_size < 10000) {
68 // 传统方法:生成所有索引并洗牌
69 indices.resize(input_size);
70 std::iota(indices.begin(), indices.end(), 0);
72 indices.resize(sample_count);
73 } else {
74 // 蓄水池采样算法
76
77 // 第1步:填充初始蓄水池
78 indices.resize(sample_count);
79 for (std::size_t i = 0; i < sample_count; ++i) {
80 indices[i] = i;
81 }
82
83 // 第2步:处理剩余元素
84 for (std::size_t i = sample_count; i < input_size; ++i) {
85 // 以 k/i 的概率选择第i个元素
86 std::size_t j = rng.random_int<std::size_t>(0, i);
87 if (j < sample_count) {
88 indices[j] = i;
89 }
90 }
91
92 // 可选:打乱结果以避免顺序偏差
93 if (sample_count > 1) {
94 rng.shuffle(indices);
95 }
96 }
97
98 // 预分配输出点云内存
99 output->points.resize(sample_count);
100 if (!m_cloud->normals.empty()) {
101 output->normals.resize(sample_count);
102 }
103 if (!m_cloud->colors.empty()) {
104 output->colors.resize(sample_count);
105 }
106 output->intensity = m_cloud->intensity;
107
108 // 并行处理逻辑保持不变
109 if (m_enable_parallel && sample_count > 1024) {
111 indices.cend(),
112 output->points.begin(),
113 [this](std::size_t idx)
114 { return m_cloud->points[idx]; });
115 if (!m_cloud->normals.empty()) {
117 indices.cbegin(),
118 indices.cend(),
119 output->normals.begin(),
120 [this](std::size_t idx) { return m_cloud->normals[idx]; });
121 }
122 if (!m_cloud->colors.empty()) {
124 indices.cend(),
125 output->colors.begin(),
126 [this](std::size_t idx)
127 { return m_cloud->colors[idx]; });
128 }
129 } else {
130 for (std::size_t i = 0; i < sample_count; ++i) {
131 std::size_t idx = indices[i];
132 output->points[i] = m_cloud->points[idx];
133 if (!m_cloud->normals.empty()) {
134 output->normals[i] = m_cloud->normals[idx];
135 }
136 if (!m_cloud->colors.empty()) {
137 output->colors[i] = m_cloud->colors[idx];
138 }
139 }
140 }
141}
142
143} // namespace toolbox::pcl
std::shared_ptr< toolbox::types::point_cloud_t< data_type > > point_cloud_ptr
Definition random_downsampling.hpp:19
point_cloud filter_impl()
Definition random_downsampling_impl.hpp:36
void enable_parallel_impl(bool enable)
Definition random_downsampling_impl.hpp:29
std::size_t set_input_impl(const point_cloud &cloud)
Definition random_downsampling_impl.hpp:13
包含点和相关数据的点云类 / A point cloud class containing points and associated data
Definition point.hpp:268
void clear()
清除点云中的所有数据 / Clear all data from cloud
Definition point_impl.hpp:305
void shuffle(TContainer &container)
随机打乱容器/Shuffle the container randomly
Definition random.hpp:309
static random_t & instance()
获取单例实例/Get singleton instance
Definition random.hpp:67
void parallel_transform(InputIt first1, InputIt last1, OutputIt d_first, UnaryOperation unary_op)
使用TBB并行转换范围[first1, last1)中的元素并存储到从d_first开始的范围
Definition parallel_raw.hpp:70
Definition base_correspondence_generator.hpp:18