cpp-toolbox  0.0.1
A toolbox library for C++
Loading...
Searching...
No Matches
geometric_consistency_sorter.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <cmath>
5#include <random>
6#include <vector>
7
10#include <cpp-toolbox/cpp-toolbox_export.hpp>
12
13namespace toolbox::pcl
14{
15
32template<typename DataType>
33class CPP_TOOLBOX_EXPORT geometric_consistency_sorter_t
35 geometric_consistency_sorter_t<DataType>, DataType>
36{
37public:
38 using base_type =
40 DataType>;
41 using typename base_type::point_cloud;
42 using typename base_type::quality_scores_t;
43
46
52 void set_neighborhood_size(std::size_t size)
53 {
54 m_neighborhood_size = size;
55 this->m_cached = false;
56 }
57
62 [[nodiscard]] std::size_t get_neighborhood_size() const
63 {
64 return m_neighborhood_size;
65 }
66
72 void set_distance_ratio_threshold(DataType threshold)
73 {
74 m_distance_ratio_threshold = threshold;
75 this->m_cached = false;
76 }
77
82 [[nodiscard]] DataType get_distance_ratio_threshold() const
83 {
84 return m_distance_ratio_threshold;
85 }
86
92 void set_random_sampling(bool random)
93 {
94 m_random_sampling = random;
95 this->m_cached = false;
96 }
97
102 [[nodiscard]] bool get_random_sampling() const { return m_random_sampling; }
103
104protected:
105 // Friend declaration to allow base class access
106 friend class base_correspondence_sorter_t<
107 geometric_consistency_sorter_t<DataType>, DataType>;
108
113 [[nodiscard]] bool validate_input_impl() const
114 {
115 if (!this->m_source_cloud || !this->m_target_cloud) {
116 LOG_ERROR_S << "错误:几何一致性排序器需要点云数据 / Error: Geometric "
117 "consistency sorter requires point cloud data";
118 return false;
119 }
120 return true;
121 }
122
128 {
129 const auto& corrs = *this->m_correspondences;
130 const auto& src_cloud = *this->m_source_cloud;
131 const auto& tgt_cloud = *this->m_target_cloud;
132
133 if (this->m_parallel_enabled &&
134 corrs.size() > 100) // 只有足够多的对应关系才并行 / Parallelize only
135 // with enough correspondences
136 {
137 // 使用线程池并行计算 / Use thread pool for parallel computation
139 std::vector<std::future<void>> futures;
140 futures.reserve(corrs.size());
141
142 for (std::size_t i = 0; i < corrs.size(); ++i) {
143 futures.emplace_back(thread_pool.submit([this, i, &scores, &corrs,
144 &src_cloud, &tgt_cloud]() {
145 scores[i] = compute_single_consistency(i, corrs, src_cloud, tgt_cloud);
146 }));
147 }
148
149 // 等待所有任务完成 / Wait for all tasks to complete
150 for (auto& future : futures) {
151 future.get();
152 }
153 } else {
154 // 串行计算 / Serial computation
155 for (std::size_t i = 0; i < corrs.size(); ++i) {
156 scores[i] = compute_single_consistency(i, corrs, src_cloud, tgt_cloud);
157 }
158 }
159 }
160
165 [[nodiscard]] std::string get_sorter_name_impl() const
166 {
167 return "GeometricConsistency";
168 }
169
170private:
180 DataType compute_single_consistency(
181 std::size_t idx, const std::vector<correspondence_t>& corrs,
182 const point_cloud& src_cloud, const point_cloud& tgt_cloud) const
183 {
184 const auto& corr = corrs[idx];
185 DataType consistency_score = 0;
186 std::size_t valid_pairs = 0;
187
188 // 确定要检查的对应关系 / Determine correspondences to check
189 std::vector<std::size_t> indices_to_check;
190
191 if (m_random_sampling) {
192 // 随机选择其他对应关系 / Randomly select other correspondences
193 indices_to_check = get_random_indices(idx, corrs.size(),
194 m_neighborhood_size);
195 } else {
196 // 选择最近的对应关系(基于描述子距离) / Select nearest correspondences
197 // (based on descriptor distance)
198 indices_to_check = get_nearest_indices(idx, corrs, m_neighborhood_size);
199 }
200
201 // 计算与其他对应关系的几何一致性 / Compute geometric consistency with
202 // other correspondences
203 for (std::size_t j : indices_to_check) {
204 // 计算源点对之间的距离 / Compute distance between source point pair
205 const auto& src_p1 = src_cloud.points[corr.src_idx];
206 const auto& src_p2 = src_cloud.points[corrs[j].src_idx];
207 DataType src_dist = compute_distance(src_p1, src_p2);
208
209 // 计算目标点对之间的距离 / Compute distance between target point pair
210 const auto& tgt_p1 = tgt_cloud.points[corr.dst_idx];
211 const auto& tgt_p2 = tgt_cloud.points[corrs[j].dst_idx];
212 DataType tgt_dist = compute_distance(tgt_p1, tgt_p2);
213
214 // 检查距离比率 / Check distance ratio
215 if (src_dist > m_min_distance && tgt_dist > m_min_distance) {
216 DataType ratio = src_dist / tgt_dist;
217 if (ratio > (1.0 - m_distance_ratio_threshold) &&
218 ratio < (1.0 + m_distance_ratio_threshold)) {
219 consistency_score += 1.0;
220 }
221 valid_pairs++;
222 }
223 }
224
225 return valid_pairs > 0 ? consistency_score / valid_pairs : 0;
226 }
227
236 template<typename PointT>
237 DataType compute_distance(const PointT& p1, const PointT& p2) const
238 {
239 return std::sqrt((p1.x - p2.x) * (p1.x - p2.x) +
240 (p1.y - p2.y) * (p1.y - p2.y) +
241 (p1.z - p2.z) * (p1.z - p2.z));
242 }
243
252 std::vector<std::size_t> get_random_indices(std::size_t exclude_idx,
253 std::size_t total_size,
254 std::size_t num_samples) const
255 {
256 std::vector<std::size_t> indices;
257 indices.reserve(num_samples);
258
259 // 创建所有可能的索引(排除当前索引) / Create all possible indices
260 // (excluding current)
261 std::vector<std::size_t> all_indices;
262 all_indices.reserve(total_size - 1);
263 for (std::size_t i = 0; i < total_size; ++i) {
264 if (i != exclude_idx) {
265 all_indices.push_back(i);
266 }
267 }
268
269 // 随机打乱并选择前num_samples个 / Shuffle randomly and select first
270 // num_samples
271 std::random_device rd;
272 std::mt19937 gen(rd());
273 std::shuffle(all_indices.begin(), all_indices.end(), gen);
274
275 std::size_t actual_samples = std::min(num_samples, all_indices.size());
276 indices.insert(indices.end(), all_indices.begin(),
277 all_indices.begin() + actual_samples);
278
279 return indices;
280 }
281
290 std::vector<std::size_t> get_nearest_indices(
291 std::size_t current_idx, const std::vector<correspondence_t>& corrs,
292 std::size_t num_neighbors) const
293 {
294 // 创建索引-距离对 / Create index-distance pairs
295 std::vector<std::pair<std::size_t, float>> index_distance_pairs;
296 index_distance_pairs.reserve(corrs.size() - 1);
297
298 float current_distance = corrs[current_idx].distance;
299
300 for (std::size_t i = 0; i < corrs.size(); ++i) {
301 if (i != current_idx) {
302 float dist_diff = std::abs(corrs[i].distance - current_distance);
303 index_distance_pairs.emplace_back(i, dist_diff);
304 }
305 }
306
307 // 按距离差排序 / Sort by distance difference
308 std::sort(index_distance_pairs.begin(), index_distance_pairs.end(),
309 [](const auto& a, const auto& b) { return a.second < b.second; });
310
311 // 提取前num_neighbors个索引 / Extract first num_neighbors indices
312 std::vector<std::size_t> indices;
313 indices.reserve(num_neighbors);
314 std::size_t actual_neighbors =
315 std::min(num_neighbors, index_distance_pairs.size());
316
317 for (std::size_t i = 0; i < actual_neighbors; ++i) {
318 indices.push_back(index_distance_pairs[i].first);
319 }
320
321 return indices;
322 }
323
324 // 参数 / Parameters
325 std::size_t m_neighborhood_size = 10;
326 DataType m_distance_ratio_threshold =
327 static_cast<DataType>(0.2);
329 bool m_random_sampling = true;
331 DataType m_min_distance =
332 static_cast<DataType>(0.001);
335};
336
337} // namespace toolbox::pcl
static thread_pool_singleton_t & instance()
获取单例实例/Get the singleton instance
Definition thread_pool_singleton.hpp:23
对应关系排序器的基类(CRTP模式) / Base class for correspondence sorters (CRTP pattern)
Definition base_correspondence_sorter.hpp:51
std::vector< DataType > quality_scores_t
Definition base_correspondence_sorter.hpp:56
基于几何一致性的对应关系排序器 / Geometric consistency-based correspondence sorter
Definition geometric_consistency_sorter.hpp:36
bool validate_input_impl() const
验证输入数据的实现 / Implementation of input validation
Definition geometric_consistency_sorter.hpp:113
void set_neighborhood_size(std::size_t size)
设置用于评估的邻域大小 / Set neighborhood size for evaluation
Definition geometric_consistency_sorter.hpp:52
std::string get_sorter_name_impl() const
获取排序器名称实现 / Get sorter name implementation
Definition geometric_consistency_sorter.hpp:165
void compute_quality_scores_impl(quality_scores_t &scores)
计算质量分数的实现 / Implementation of quality score computation
Definition geometric_consistency_sorter.hpp:127
void set_distance_ratio_threshold(DataType threshold)
设置距离比率阈值 / Set distance ratio threshold
Definition geometric_consistency_sorter.hpp:72
void set_random_sampling(bool random)
设置采样策略 / Set sampling strategy
Definition geometric_consistency_sorter.hpp:92
std::size_t get_neighborhood_size() const
获取邻域大小 / Get neighborhood size
Definition geometric_consistency_sorter.hpp:62
DataType get_distance_ratio_threshold() const
获取距离比率阈值 / Get distance ratio threshold
Definition geometric_consistency_sorter.hpp:82
#define LOG_ERROR_S
ERROR级别流式日志的宏 / Macro for ERROR level stream logging.
Definition thread_logger.hpp:1332
Definition base_correspondence_generator.hpp:18