cpp-toolbox  0.0.1
A toolbox library for C++
Loading...
Searching...
No Matches
fpfh_extractor.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <cmath>
5#include <vector>
6
7#include <cpp-toolbox/cpp-toolbox_export.hpp>
12
13namespace toolbox::pcl
14{
15
24template<typename DataType>
25struct fpfh_signature_t : public base_signature_t<DataType, fpfh_signature_t<DataType>>
26{
27 using value_type = DataType; // 为了兼容KNN接口 / For KNN interface compatibility
28 static constexpr std::size_t HISTOGRAM_SIZE = 33;
29 std::array<DataType, HISTOGRAM_SIZE> histogram {};
30
31 // 提供data()和size()方法以兼容IMetric接口 / Provide data() and size() for IMetric compatibility
32 const DataType* data() const { return histogram.data(); }
33 DataType* data() { return histogram.data(); }
34 constexpr std::size_t size() const { return HISTOGRAM_SIZE; }
35
36 DataType distance_impl(const fpfh_signature_t& other) const
37 {
38 DataType dist = 0;
39 for (std::size_t i = 0; i < HISTOGRAM_SIZE; ++i) {
40 DataType diff = histogram[i] - other.histogram[i];
41 dist += diff * diff;
42 }
43 return std::sqrt(dist);
44 }
45};
46
83template<typename DataType,
84 typename KNN = kdtree_generic_t<point_t<DataType>, toolbox::metrics::L2Metric<DataType>>>
85class CPP_TOOLBOX_EXPORT fpfh_extractor_t
86 : public base_descriptor_extractor_t<fpfh_extractor_t<DataType, KNN>,
87 DataType,
88 fpfh_signature_t<DataType>>
89{
90public:
92 DataType,
94 using data_type = DataType;
96 using knn_type = KNN;
98 using point_cloud_ptr = std::shared_ptr<point_cloud>;
99
100 fpfh_extractor_t() = default;
101
105 std::size_t set_input(const point_cloud& cloud);
106 std::size_t set_input(const point_cloud_ptr& cloud);
107
111 std::size_t set_knn(const knn_type& knn);
112
116 std::size_t set_search_radius(data_type radius);
117
121 std::size_t set_num_neighbors(std::size_t num_neighbors);
122
127 void set_normals(const point_cloud_ptr& normals);
128
132 void enable_parallel_impl(bool enable);
133
137 void compute_impl(const point_cloud& cloud,
138 const std::vector<std::size_t>& keypoint_indices,
139 std::vector<signature_type>& descriptors) const;
140
141 void compute_impl(
142 const point_cloud& cloud,
143 const std::vector<std::size_t>& keypoint_indices,
144 std::unique_ptr<std::vector<signature_type>>& descriptors) const;
145
146private:
147 struct spfh_signature_t
148 {
149 std::array<DataType, 11> f1 {}; // alpha histogram
150 std::array<DataType, 11> f2 {}; // phi histogram
151 std::array<DataType, 11> f3 {}; // theta histogram
152 };
153
154 void compute_spfh(const point_cloud& cloud,
155 const point_cloud& normals,
156 std::size_t index,
157 const std::vector<std::size_t>& neighbor_indices,
158 spfh_signature_t& spfh) const;
159
160 void compute_fpfh_feature(const point_cloud& cloud,
161 const point_cloud& normals,
162 std::size_t index,
163 const std::vector<spfh_signature_t>& spfh_features,
164 signature_type& fpfh) const;
165
166 // 优化相关数据结构 / Optimization related data structures
167 template<typename T>
168 struct neighbor_info_t
169 {
170 std::vector<std::size_t> indices;
171 std::vector<T> distances;
172 bool computed = false;
173
174 void reserve(std::size_t n) {
175 indices.reserve(n);
176 distances.reserve(n);
177 }
178
179 void clear() {
180 indices.clear();
181 distances.clear();
182 computed = false;
183 }
184 };
185
186 template<typename T, typename K>
187 class spfh_cache_manager_t
188 {
189 public:
190 using spfh_signature_type = spfh_signature_t;
191
192 explicit spfh_cache_manager_t(std::size_t cloud_size)
193 : cloud_size_(cloud_size)
194 , needs_spfh_(cloud_size, false)
195 , point_to_spfh_idx_(cloud_size, -1)
196 {
197 spfh_features_.reserve(cloud_size / 4);
198 }
199
200 void mark_needed(std::size_t point_idx) {
201 if (point_idx < cloud_size_ && !needs_spfh_[point_idx]) {
202 needs_spfh_[point_idx] = true;
203 point_to_spfh_idx_[point_idx] = static_cast<int>(spfh_features_.size());
204 spfh_features_.emplace_back();
205 }
206 }
207
208 bool is_needed(std::size_t point_idx) const {
209 return point_idx < cloud_size_ && needs_spfh_[point_idx];
210 }
211
212 spfh_signature_type& get_spfh(std::size_t point_idx) {
213 int spfh_idx = point_to_spfh_idx_[point_idx];
214 return spfh_features_[spfh_idx];
215 }
216
217 const spfh_signature_type& get_spfh(std::size_t point_idx) const {
218 int spfh_idx = point_to_spfh_idx_[point_idx];
219 return spfh_features_[spfh_idx];
220 }
221
222 std::size_t size() const { return spfh_features_.size(); }
223
224 std::vector<std::size_t> get_needed_points() const {
225 std::vector<std::size_t> needed_points;
226 needed_points.reserve(spfh_features_.size());
227
228 for (std::size_t i = 0; i < cloud_size_; ++i) {
229 if (needs_spfh_[i]) {
230 needed_points.push_back(i);
231 }
232 }
233 return needed_points;
234 }
235
236 private:
237 std::size_t cloud_size_;
238 std::vector<bool> needs_spfh_;
239 std::vector<int> point_to_spfh_idx_;
240 std::vector<spfh_signature_type> spfh_features_;
241 };
242
243 void compute_fpfh_feature_optimized(const point_cloud& cloud,
244 const point_cloud& normals,
245 std::size_t index,
246 const neighbor_info_t<data_type>& neighbor_info,
247 const spfh_cache_manager_t<data_type, knn_type>& spfh_cache,
248 signature_type& fpfh) const;
249
253 void compute_fpfh_direct(const point_cloud& cloud,
254 const point_cloud& normals,
255 std::size_t index,
256 const std::vector<std::size_t>& neighbor_indices,
257 const std::vector<data_type>& neighbor_distances,
258 signature_type& fpfh) const;
259
263 void compute_fpfh_feature_adaptive(const point_cloud& cloud,
264 const point_cloud& normals,
265 std::size_t index,
266 const std::vector<std::size_t>& neighbor_indices,
267 const std::vector<data_type>& neighbor_distances,
268 std::vector<neighbor_info_t<data_type>>& all_neighbors,
269 std::vector<spfh_signature_t>& spfh_array,
270 std::vector<bool>& spfh_computed,
271 signature_type& fpfh) const;
272
273 void compute_pair_features(const point_t<data_type>& p1,
274 const point_t<data_type>& n1,
275 const point_t<data_type>& p2,
276 const point_t<data_type>& n2,
277 data_type& f1,
278 data_type& f2,
279 data_type& f3) const;
280
281 std::size_t compute_bin_index(data_type value,
282 data_type min_val,
283 data_type max_val,
284 std::size_t num_bins) const;
285
286 bool m_enable_parallel = false;
287 data_type m_search_radius = 0.05;
288 std::size_t m_num_neighbors = 50;
289 point_cloud_ptr m_cloud;
290 point_cloud_ptr m_normals;
291 knn_type* m_knn = nullptr;
292};
293
294} // namespace toolbox::pcl
295
Definition vector_metrics.hpp:18
描述子提取器的基类(CRTP模式) / Base class for descriptor extractors (CRTP pattern)
Definition base_descriptor_extractor.hpp:91
FPFH (Fast Point Feature Histogram) descriptor extractor.
Definition fpfh_extractor.hpp:89
std::shared_ptr< point_cloud > point_cloud_ptr
Definition fpfh_extractor.hpp:98
DataType data_type
Definition fpfh_extractor.hpp:94
KNN knn_type
Definition fpfh_extractor.hpp:96
Definition base_correspondence_generator.hpp:18
描述子签名的基类 / Base class for descriptor signatures
Definition base_descriptor_extractor.hpp:38
FPFH (Fast Point Feature Histogram) signature.
Definition fpfh_extractor.hpp:26
static constexpr std::size_t HISTOGRAM_SIZE
Definition fpfh_extractor.hpp:28
DataType * data()
Definition fpfh_extractor.hpp:33
DataType distance_impl(const fpfh_signature_t &other) const
Definition fpfh_extractor.hpp:36
constexpr std::size_t size() const
Definition fpfh_extractor.hpp:34
std::array< DataType, HISTOGRAM_SIZE > histogram
Definition fpfh_extractor.hpp:29
DataType value_type
Definition fpfh_extractor.hpp:27
const DataType * data() const
Definition fpfh_extractor.hpp:32