cpp-toolbox  0.0.1
A toolbox library for C++
Loading...
Searching...
No Matches
knn_correspondence_generator_impl.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <unordered_map>
5
6// Logger macros
7#define LOG_ERROR_S toolbox::logger::thread_logger_t::instance().error_s()
8
9namespace toolbox::pcl
10{
11
12template<typename DataType, typename Signature, typename KNN>
14 std::vector<correspondence_t>& correspondences)
15{
16 // 检查KNN算法 / Check KNN algorithm
17 if (!m_knn) {
18 LOG_ERROR_S << "错误:未设置KNN算法 / Error: KNN algorithm not set";
19 return;
20 }
21
22 // 构建KNN数据集 / Build KNN dataset
23 build_knn_dataset();
24
25 // 第一步:为每个源描述子查找候选匹配 / Step 1: Find candidate matches for each source descriptor
26 std::vector<correspondence_t> all_candidates;
27 all_candidates.reserve(this->m_src_descriptors->size());
28
29 for (std::size_t i = 0; i < this->m_src_descriptors->size(); ++i) {
30 std::vector<correspondence_t> candidates;
31 find_candidates_for_descriptor(i, candidates);
32
33 this->m_total_candidates += candidates.size();
34
35 // 应用比率测试 / Apply ratio test
36 if (!candidates.empty() && this->apply_ratio_test(candidates)) {
37 this->m_ratio_test_passed++;
38 all_candidates.push_back(candidates[0]); // 只保留最佳匹配 / Keep only best match
39 }
40 }
41
42 // 第二步:双向验证(如果启用) / Step 2: Mutual verification (if enabled)
43 std::vector<correspondence_t> verified_corrs;
44 if (this->m_mutual_verification) {
45 perform_mutual_verification(all_candidates, verified_corrs);
46 this->m_mutual_test_passed = verified_corrs.size();
47 } else {
48 verified_corrs = std::move(all_candidates);
49 }
50
51 // 第三步:应用距离阈值 / Step 3: Apply distance threshold
52 correspondences = std::move(verified_corrs);
53 this->apply_distance_threshold(correspondences);
54 this->m_distance_test_passed = correspondences.size();
55
56 // 第四步:计算简单的几何一致性分数(仅供参考) / Step 4: Compute simple geometric consistency score (for reference)
57 if (correspondences.size() >= 3) {
58 float consistency_score = this->compute_geometric_consistency(correspondences);
59 // 可以在统计信息中报告这个分数 / Can report this score in statistics
60 }
61}
62
63template<typename DataType, typename Signature, typename KNN>
65{
66 // 将目标描述子设置为KNN的数据集 / Set target descriptors as KNN dataset
67 m_knn->set_input(*this->m_dst_descriptors);
68}
69
70template<typename DataType, typename Signature, typename KNN>
71void knn_correspondence_generator_t<DataType, Signature, KNN>::find_candidates_for_descriptor(
72 std::size_t src_idx, std::vector<correspondence_t>& candidates) const
73{
74 candidates.clear();
75
76 // 查找K个最近邻(K=2用于比率测试) / Find K nearest neighbors (K=2 for ratio test)
77 const std::size_t k = 2;
78 std::vector<std::size_t> indices;
79 std::vector<typename Signature::data_type> distances;
80
81 // 执行KNN搜索 / Perform KNN search
82 m_knn->kneighbors((*this->m_src_descriptors)[src_idx], k, indices, distances);
83
84 // 转换为correspondence_t格式 / Convert to correspondence_t format
85 for (std::size_t i = 0; i < indices.size(); ++i) {
86 correspondence_t corr;
87 corr.src_idx = (*this->m_src_keypoint_indices)[src_idx];
88 corr.dst_idx = (*this->m_dst_keypoint_indices)[indices[i]];
89 corr.distance = static_cast<float>(distances[i]);
90 candidates.push_back(corr);
91 }
92}
93
94template<typename DataType, typename Signature, typename KNN>
95void knn_correspondence_generator_t<DataType, Signature, KNN>::perform_mutual_verification(
96 const std::vector<correspondence_t>& forward_corrs,
97 std::vector<correspondence_t>& verified_corrs)
98{
99 verified_corrs.clear();
100
101 // 构建反向查找表:目标索引 -> 源索引 / Build reverse lookup: target index -> source index
102 std::unordered_map<std::size_t, std::size_t> dst_to_src;
103 for (const auto& corr : forward_corrs) {
104 dst_to_src[corr.dst_idx] = corr.src_idx;
105 }
106
107 // 对每个目标描述子执行反向搜索 / Perform reverse search for each target descriptor
108 for (const auto& forward_corr : forward_corrs) {
109 // 获取目标描述子在源描述子集中的索引 / Get target descriptor's index in source descriptor set
110 std::size_t dst_desc_idx = 0;
111 for (std::size_t i = 0; i < this->m_dst_keypoint_indices->size(); ++i) {
112 if ((*this->m_dst_keypoint_indices)[i] == forward_corr.dst_idx) {
113 dst_desc_idx = i;
114 break;
115 }
116 }
117
118 // 临时创建一个只包含源描述子的KNN / Temporarily create a KNN with only source descriptors
119 auto src_knn = std::make_shared<KNN>();
120 src_knn->set_input(*this->m_src_descriptors);
121
122 // 查找最近的源描述子 / Find nearest source descriptor
123 std::vector<std::size_t> indices;
124 std::vector<typename Signature::data_type> distances;
125 src_knn->kneighbors((*this->m_dst_descriptors)[dst_desc_idx], 1, indices, distances);
126
127 if (!indices.empty()) {
128 std::size_t reverse_src_idx = (*this->m_src_keypoint_indices)[indices[0]];
129
130 // 检查是否形成双向匹配 / Check if bidirectional match
131 if (reverse_src_idx == forward_corr.src_idx) {
132 verified_corrs.push_back(forward_corr);
133 }
134 }
135 }
136}
137
138} // namespace toolbox::pcl
基于KNN的对应点生成器 / KNN-based correspondence generator
Definition knn_correspondence_generator.hpp:50
void compute_impl(std::vector< correspondence_t > &correspondences)
计算对应关系的实现 / Implementation of computing correspondences
Definition knn_correspondence_generator_impl.hpp:13
#define LOG_ERROR_S
ERROR级别流式日志的宏 / Macro for ERROR level stream logging.
Definition thread_logger.hpp:1332
Definition base_correspondence_generator.hpp:18