cpp-toolbox  0.0.1
A toolbox library for C++
Loading...
Searching...
No Matches
brute_force_correspondence_generator_impl.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <limits>
5#include <unordered_map>
7
8namespace toolbox::pcl
9{
10
11template<typename DataType, typename Signature>
13 std::vector<correspondence_t>& correspondences)
14{
15 if (m_enable_parallel) {
16 // 并行版本 / Parallel version
17 std::vector<correspondence_t> all_candidates;
18 compute_all_candidates_parallel(all_candidates);
19
20 // 双向验证(如果启用) / Mutual verification (if enabled)
21 if (this->m_mutual_verification) {
22 std::vector<correspondence_t> verified_corrs;
23 perform_mutual_verification(all_candidates, verified_corrs);
24 this->m_mutual_test_passed = verified_corrs.size();
25 correspondences = std::move(verified_corrs);
26 } else {
27 correspondences = std::move(all_candidates);
28 }
29 } else {
30 // 串行版本 / Serial version
31 std::vector<correspondence_t> all_candidates;
32 all_candidates.reserve(this->m_src_descriptors->size());
33
34 for (std::size_t i = 0; i < this->m_src_descriptors->size(); ++i) {
35 std::vector<correspondence_t> candidates;
36 find_candidates_for_descriptor_serial(i, candidates);
37
38 this->m_total_candidates += candidates.size();
39
40 // 应用比率测试 / Apply ratio test
41 if (!candidates.empty() && this->apply_ratio_test(candidates)) {
42 this->m_ratio_test_passed++;
43 all_candidates.push_back(candidates[0]); // 只保留最佳匹配 / Keep only best match
44 }
45 }
46
47 // 双向验证(如果启用) / Mutual verification (if enabled)
48 if (this->m_mutual_verification) {
49 std::vector<correspondence_t> verified_corrs;
50 perform_mutual_verification(all_candidates, verified_corrs);
51 this->m_mutual_test_passed = verified_corrs.size();
52 correspondences = std::move(verified_corrs);
53 } else {
54 correspondences = std::move(all_candidates);
55 }
56 }
57
58 // 应用距离阈值 / Apply distance threshold
59 this->apply_distance_threshold(correspondences);
60 this->m_distance_test_passed = correspondences.size();
61
62 // 计算简单的几何一致性分数(仅供参考) / Compute simple geometric consistency score (for reference)
63 if (correspondences.size() >= 3) {
64 float consistency_score = this->compute_geometric_consistency(correspondences);
65 // 可以在统计信息中报告这个分数 / Can report this score in statistics
66 }
67}
68
69template<typename DataType, typename Signature>
71 std::size_t src_idx, std::vector<correspondence_t>& candidates) const
72{
73 candidates.clear();
74
75 const auto& src_desc = (*this->m_src_descriptors)[src_idx];
76
77 // 存储所有距离和索引 / Store all distances and indices
78 std::vector<std::pair<float, std::size_t>> distance_index_pairs;
79 distance_index_pairs.reserve(this->m_dst_descriptors->size());
80
81 // 计算到所有目标描述子的距离 / Compute distances to all target descriptors
82 for (std::size_t i = 0; i < this->m_dst_descriptors->size(); ++i) {
83 float dist = src_desc.distance((*this->m_dst_descriptors)[i]);
84 distance_index_pairs.emplace_back(dist, i);
85 }
86
87 // 部分排序找到最近的两个(用于比率测试) / Partial sort to find nearest two (for ratio test)
88 std::partial_sort(distance_index_pairs.begin(),
89 distance_index_pairs.begin() + std::min(size_t(2), distance_index_pairs.size()),
90 distance_index_pairs.end());
91
92 // 转换为correspondence_t格式 / Convert to correspondence_t format
93 for (std::size_t i = 0; i < std::min(size_t(2), distance_index_pairs.size()); ++i) {
94 correspondence_t corr;
95 corr.src_idx = (*this->m_src_keypoint_indices)[src_idx];
96 corr.dst_idx = (*this->m_dst_keypoint_indices)[distance_index_pairs[i].second];
97 corr.distance = distance_index_pairs[i].first;
98 candidates.push_back(corr);
99 }
100}
101
102template<typename DataType, typename Signature>
103void brute_force_correspondence_generator_t<DataType, Signature>::compute_all_candidates_parallel(
104 std::vector<correspondence_t>& all_candidates)
105{
106 const std::size_t num_src = this->m_src_descriptors->size();
107
108 // 预分配结果向量 / Pre-allocate result vectors
109 std::vector<std::vector<correspondence_t>> thread_results(num_src);
110
111 // 获取线程池单例 / Get thread pool singleton
113
114 // 并行计算每个源描述子的候选匹配 / Compute candidate matches for each source descriptor in parallel
115 std::vector<std::future<void>> futures;
116 futures.reserve(num_src);
117
118 for (std::size_t i = 0; i < num_src; ++i) {
119 futures.push_back(pool_singleton.submit([this, i, &thread_results]() {
120 find_candidates_for_descriptor_serial(i, thread_results[i]);
121 }));
122 }
123
124 // 等待所有任务完成 / Wait for all tasks to complete
125 for (auto& future : futures) {
126 future.get();
127 }
128
129 // 收集结果并应用比率测试 / Collect results and apply ratio test
130 all_candidates.clear();
131 all_candidates.reserve(num_src);
132
133 for (std::size_t i = 0; i < num_src; ++i) {
134 const auto& candidates = thread_results[i];
135 this->m_total_candidates += candidates.size();
136
137 if (!candidates.empty() && this->apply_ratio_test(candidates)) {
138 this->m_ratio_test_passed++;
139 all_candidates.push_back(candidates[0]); // 只保留最佳匹配 / Keep only best match
140 }
141 }
142}
143
144template<typename DataType, typename Signature>
145void brute_force_correspondence_generator_t<DataType, Signature>::perform_mutual_verification(
146 const std::vector<correspondence_t>& forward_corrs,
147 std::vector<correspondence_t>& verified_corrs)
148{
149 verified_corrs.clear();
150
151 // 构建目标到源的映射 / Build target to source mapping
152 std::unordered_map<std::size_t, std::size_t> dst_to_src;
153 for (const auto& corr : forward_corrs) {
154 dst_to_src[corr.dst_idx] = corr.src_idx;
155 }
156
157 // 对每个唯一的目标点执行反向搜索 / Perform reverse search for each unique target point
158 std::unordered_map<std::size_t, std::pair<std::size_t, float>> reverse_matches;
159
160 for (const auto& [dst_idx, src_idx] : dst_to_src) {
161 // 找到目标描述子的索引 / Find target descriptor index
162 std::size_t dst_desc_idx = 0;
163 for (std::size_t i = 0; i < this->m_dst_keypoint_indices->size(); ++i) {
164 if ((*this->m_dst_keypoint_indices)[i] == dst_idx) {
165 dst_desc_idx = i;
166 break;
167 }
168 }
169
170 // 找到最近的源描述子 / Find nearest source descriptor
171 float min_dist = std::numeric_limits<float>::max();
172 std::size_t best_src_idx = 0;
173
174 for (std::size_t i = 0; i < this->m_src_descriptors->size(); ++i) {
175 float dist = (*this->m_dst_descriptors)[dst_desc_idx].distance((*this->m_src_descriptors)[i]);
176 if (dist < min_dist) {
177 min_dist = dist;
178 best_src_idx = (*this->m_src_keypoint_indices)[i];
179 }
180 }
181
182 reverse_matches[dst_idx] = {best_src_idx, min_dist};
183 }
184
185 // 检查双向匹配 / Check bidirectional matches
186 for (const auto& forward_corr : forward_corrs) {
187 auto it = reverse_matches.find(forward_corr.dst_idx);
188 if (it != reverse_matches.end() && it->second.first == forward_corr.src_idx) {
189 verified_corrs.push_back(forward_corr);
190 }
191 }
192}
193
194} // namespace toolbox::pcl
static thread_pool_singleton_t & instance()
获取单例实例/Get the singleton instance
Definition thread_pool_singleton.hpp:23
暴力搜索对应点生成器 / Brute-force correspondence generator
Definition brute_force_correspondence_generator.hpp:42
void compute_impl(std::vector< correspondence_t > &correspondences)
计算对应关系的实现 / Implementation of computing correspondences
Definition brute_force_correspondence_generator_impl.hpp:12
Definition base_correspondence_generator.hpp:18