cpp-toolbox  0.0.1
A toolbox library for C++
Loading...
Searching...
No Matches
base_correspondence_generator.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4#include <vector>
5#include <sstream>
6#include <algorithm>
7#include <limits>
8#include <cmath>
10#include <cpp-toolbox/cpp-toolbox_export.hpp>
12
13// Logger macros
14#define LOG_ERROR_S toolbox::logger::thread_logger_t::instance().error_s()
15#define LOG_WARN_S toolbox::logger::thread_logger_t::instance().warn_s()
16
17namespace toolbox::pcl
18{
19
27{
28 std::size_t src_idx;
29 std::size_t dst_idx;
30 float distance;
31};
32
59template<typename Derived, typename DataType, typename Signature>
60class CPP_TOOLBOX_EXPORT base_correspondence_generator_t
61{
62public:
64 using point_cloud_ptr = std::shared_ptr<point_cloud>;
65 using signatures_ptr = std::shared_ptr<std::vector<Signature>>;
66 using keypoint_indices_ptr = std::shared_ptr<std::vector<std::size_t>>;
67
70
71 // 删除拷贝和移动操作 / Delete copy and move operations
76
83 void set_source(const point_cloud_ptr& src_cloud,
84 const signatures_ptr& src_descriptors,
85 const keypoint_indices_ptr& src_keypoint_indices)
86 {
87 m_src_cloud = src_cloud;
88 m_src_descriptors = src_descriptors;
89 m_src_keypoint_indices = src_keypoint_indices;
90 }
91
98 void set_destination(const point_cloud_ptr& dst_cloud,
99 const signatures_ptr& dst_descriptors,
100 const keypoint_indices_ptr& dst_keypoint_indices)
101 {
102 m_dst_cloud = dst_cloud;
103 m_dst_descriptors = dst_descriptors;
104 m_dst_keypoint_indices = dst_keypoint_indices;
105 }
106
111 void set_ratio(float ratio) { m_ratio = ratio; }
112
117 float get_ratio() const { return m_ratio; }
118
123 void set_mutual_verification(bool mutual_verification)
124 {
125 m_mutual_verification = mutual_verification;
126 }
127
132 bool get_mutual_verification() const { return m_mutual_verification; }
133
138 void set_distance_threshold(float distance_threshold)
139 {
140 m_distance_threshold = distance_threshold;
141 }
142
147 float get_distance_threshold() const { return m_distance_threshold; }
148
153 void compute(std::vector<correspondence_t>& correspondences)
154 {
155 // 清空输出和统计信息 / Clear output and statistics
156 correspondences.clear();
157 reset_statistics();
158
159 // 验证输入 / Validate input
160 if (!validate_input()) {
161 return;
162 }
163
164 // 调用派生类的实现 / Call derived class implementation
165 static_cast<Derived*>(this)->compute_impl(correspondences);
166 }
167
172 std::string get_statistics() const
173 {
174 std::stringstream ss;
175 ss << "对应点生成统计 / Correspondence Generation Statistics:\n";
176 ss << " 候选对应点总数 / Total candidates: " << m_total_candidates << "\n";
177 ss << " 通过比率测试 / Passed ratio test: " << m_ratio_test_passed << "\n";
178 if (m_mutual_verification) {
179 ss << " 通过双向验证 / Passed mutual verification: " << m_mutual_test_passed << "\n";
180 }
181 ss << " 通过距离阈值 / Passed distance threshold: " << m_distance_test_passed << "\n";
182
183 if (m_src_descriptors) {
184 float match_rate = static_cast<float>(m_distance_test_passed) / m_src_descriptors->size();
185 ss << " 匹配率 / Match rate: " << (match_rate * 100) << "%\n";
186 }
187
188 return ss.str();
189 }
190
191protected:
196 bool validate_input() const
197 {
198 // 检查源数据 / Check source data
199 if (!m_src_cloud || !m_src_descriptors || !m_src_keypoint_indices) {
200 LOG_ERROR_S << "错误:源数据不完整 / Error: Source data incomplete";
201 return false;
202 }
203
204 // 检查目标数据 / Check target data
205 if (!m_dst_cloud || !m_dst_descriptors || !m_dst_keypoint_indices) {
206 LOG_ERROR_S << "错误:目标数据不完整 / Error: Target data incomplete";
207 return false;
208 }
209
210 // 检查描述子和关键点数量是否匹配 / Check if descriptors and keypoints match
211 if (m_src_descriptors->size() != m_src_keypoint_indices->size()) {
212 LOG_ERROR_S << "错误:源描述子数量与关键点数量不匹配 / Error: Source descriptor count doesn't match keypoint count";
213 return false;
214 }
215
216 if (m_dst_descriptors->size() != m_dst_keypoint_indices->size()) {
217 LOG_ERROR_S << "错误:目标描述子数量与关键点数量不匹配 / Error: Target descriptor count doesn't match keypoint count";
218 return false;
219 }
220
221 // 检查参数有效性 / Check parameter validity
222 if (m_ratio <= 0.0f || m_ratio >= 1.0f) {
223 LOG_WARN_S << "警告:比率测试阈值应在(0,1)之间 / Warning: Ratio test threshold should be in (0,1)";
224 }
225
226 return true;
227 }
228
234 bool apply_ratio_test(const std::vector<correspondence_t>& candidates) const
235 {
236 // Lowe's ratio test: 检查最佳匹配是否显著优于次佳匹配 / Check if best match is significantly better than second best
237 if (candidates.size() < 2) {
238 return true; // 如果只有一个匹配,默认通过 / If only one match, pass by default
239 }
240
241 return (candidates[0].distance < m_ratio * candidates[1].distance);
242 }
243
248 void apply_distance_threshold(std::vector<correspondence_t>& correspondences) const
249 {
250 // 移除距离超过阈值的对应关系 / Remove correspondences exceeding distance threshold
251 correspondences.erase(
252 std::remove_if(correspondences.begin(), correspondences.end(),
253 [this](const correspondence_t& corr) {
254 return corr.distance > m_distance_threshold;
255 }),
256 correspondences.end());
257 }
258
264 float compute_geometric_consistency(const std::vector<correspondence_t>& correspondences) const
265 {
266 if (correspondences.size() < 3) {
267 return 0.0f;
268 }
269
270 // 简单的几何一致性检查:比较点对之间的距离比率 / Simple geometric consistency: compare distance ratios between point pairs
271 float consistency_score = 0.0f;
272 std::size_t valid_pairs = 0;
273
274 for (std::size_t i = 0; i < correspondences.size() - 1; ++i) {
275 for (std::size_t j = i + 1; j < correspondences.size(); ++j) {
276 // 计算源点对之间的距离 / Compute distance between source point pair
277 const auto& src_p1 = m_src_cloud->points[correspondences[i].src_idx];
278 const auto& src_p2 = m_src_cloud->points[correspondences[j].src_idx];
279 DataType src_dist = std::sqrt(
280 (src_p1.x - src_p2.x) * (src_p1.x - src_p2.x) +
281 (src_p1.y - src_p2.y) * (src_p1.y - src_p2.y) +
282 (src_p1.z - src_p2.z) * (src_p1.z - src_p2.z));
283
284 // 计算目标点对之间的距离 / Compute distance between target point pair
285 const auto& dst_p1 = m_dst_cloud->points[correspondences[i].dst_idx];
286 const auto& dst_p2 = m_dst_cloud->points[correspondences[j].dst_idx];
287 DataType dst_dist = std::sqrt(
288 (dst_p1.x - dst_p2.x) * (dst_p1.x - dst_p2.x) +
289 (dst_p1.y - dst_p2.y) * (dst_p1.y - dst_p2.y) +
290 (dst_p1.z - dst_p2.z) * (dst_p1.z - dst_p2.z));
291
292 // 避免除零 / Avoid division by zero
293 if (src_dist > 0.001 && dst_dist > 0.001) {
294 DataType ratio = src_dist / dst_dist;
295 // 如果比率接近1,说明几何关系保持良好 / If ratio is close to 1, geometry is well preserved
296 if (ratio > 0.8 && ratio < 1.2) {
297 consistency_score += 1.0f;
298 }
299 valid_pairs++;
300 }
301 }
302 }
303
304 return valid_pairs > 0 ? consistency_score / valid_pairs : 0.0f;
305 }
306
311 {
312 m_total_candidates = 0;
313 m_ratio_test_passed = 0;
314 m_mutual_test_passed = 0;
315 m_distance_test_passed = 0;
316 }
317
318 // 数据成员 / Data members
325
326 float m_ratio = 0.8F;
327 float m_distance_threshold = std::numeric_limits<float>::max();
328 bool m_mutual_verification = true;
329
330 // 统计信息 / Statistics
331 mutable std::size_t m_total_candidates = 0;
332 mutable std::size_t m_ratio_test_passed = 0;
333 mutable std::size_t m_mutual_test_passed = 0;
334 mutable std::size_t m_distance_test_passed = 0;
335};
336
337} // namespace toolbox::pcl
对应点生成器的基类(CRTP模式) / Base class for correspondence generators (CRTP pattern)
Definition base_correspondence_generator.hpp:61
void set_destination(const point_cloud_ptr &dst_cloud, const signatures_ptr &dst_descriptors, const keypoint_indices_ptr &dst_keypoint_indices)
设置目标数据 / Set destination data
Definition base_correspondence_generator.hpp:98
base_correspondence_generator_t(base_correspondence_generator_t &&)=default
float get_distance_threshold() const
获取距离阈值 / Get distance threshold
Definition base_correspondence_generator.hpp:147
std::shared_ptr< std::vector< std::size_t > > keypoint_indices_ptr
Definition base_correspondence_generator.hpp:66
bool get_mutual_verification() const
获取是否启用双向验证 / Get whether mutual verification is enabled
Definition base_correspondence_generator.hpp:132
signatures_ptr m_src_descriptors
Definition base_correspondence_generator.hpp:321
void set_ratio(float ratio)
设置比率测试阈值 / Set ratio test threshold
Definition base_correspondence_generator.hpp:111
void set_source(const point_cloud_ptr &src_cloud, const signatures_ptr &src_descriptors, const keypoint_indices_ptr &src_keypoint_indices)
设置源数据 / Set source data
Definition base_correspondence_generator.hpp:83
keypoint_indices_ptr m_dst_keypoint_indices
Definition base_correspondence_generator.hpp:324
bool apply_ratio_test(const std::vector< correspondence_t > &candidates) const
应用比率测试 / Apply ratio test
Definition base_correspondence_generator.hpp:234
point_cloud_ptr m_src_cloud
Definition base_correspondence_generator.hpp:319
bool validate_input() const
验证输入数据的有效性 / Validate input data
Definition base_correspondence_generator.hpp:196
std::shared_ptr< std::vector< Signature > > signatures_ptr
Definition base_correspondence_generator.hpp:65
void set_distance_threshold(float distance_threshold)
设置距离阈值 / Set distance threshold
Definition base_correspondence_generator.hpp:138
base_correspondence_generator_t(const base_correspondence_generator_t &)=delete
std::shared_ptr< point_cloud > point_cloud_ptr
Definition base_correspondence_generator.hpp:64
point_cloud_ptr m_dst_cloud
Definition base_correspondence_generator.hpp:320
std::string get_statistics() const
获取最后一次计算的统计信息 / Get statistics from last computation
Definition base_correspondence_generator.hpp:172
signatures_ptr m_dst_descriptors
Definition base_correspondence_generator.hpp:322
void reset_statistics()
重置统计信息 / Reset statistics
Definition base_correspondence_generator.hpp:310
void compute(std::vector< correspondence_t > &correspondences)
计算对应关系 / Compute correspondences
Definition base_correspondence_generator.hpp:153
void set_mutual_verification(bool mutual_verification)
设置是否启用双向验证 / Set whether to enable mutual verification
Definition base_correspondence_generator.hpp:123
base_correspondence_generator_t & operator=(const base_correspondence_generator_t &)=delete
void apply_distance_threshold(std::vector< correspondence_t > &correspondences) const
应用距离阈值过滤 / Apply distance threshold filtering
Definition base_correspondence_generator.hpp:248
keypoint_indices_ptr m_src_keypoint_indices
Definition base_correspondence_generator.hpp:323
float get_ratio() const
获取比率测试阈值 / Get ratio test threshold
Definition base_correspondence_generator.hpp:117
base_correspondence_generator_t & operator=(base_correspondence_generator_t &&)=default
float compute_geometric_consistency(const std::vector< correspondence_t > &correspondences) const
计算几何一致性分数(简单验证) / Compute geometric consistency score (simple verification)
Definition base_correspondence_generator.hpp:264
#define LOG_ERROR_S
ERROR级别流式日志的宏 / Macro for ERROR level stream logging.
Definition thread_logger.hpp:1332
#define LOG_WARN_S
WARN级别流式日志的宏 / Macro for WARN level stream logging.
Definition thread_logger.hpp:1331
Definition base_correspondence_generator.hpp:18
对应关系结构体 / Correspondence structure
Definition base_correspondence_generator.hpp:27
std::size_t src_idx
源点索引 / Source point index
Definition base_correspondence_generator.hpp:28
float distance
描述子间的距离 / Distance between descriptors
Definition base_correspondence_generator.hpp:30
std::size_t dst_idx
目标点索引 / Destination point index
Definition base_correspondence_generator.hpp:29