|
8 | 8 | #include <cpp-toolbox/pcl/descriptors/fpfh_extractor.hpp> |
9 | 9 | #include <cpp-toolbox/pcl/descriptors/pfh_extractor.hpp> |
10 | 10 | #include <cpp-toolbox/pcl/descriptors/shot_extractor.hpp> |
| 11 | +#include <cpp-toolbox/pcl/descriptors/3dsc_extractor.hpp> |
11 | 12 | #include <cpp-toolbox/pcl/knn/bfknn.hpp> |
12 | 13 | #include <cpp-toolbox/pcl/knn/kdtree.hpp> |
13 | 14 | #include <cpp-toolbox/types/point.hpp> |
@@ -72,6 +73,25 @@ struct SHOTMetric |
72 | 73 | } |
73 | 74 | }; |
74 | 75 |
|
| 76 | +template<typename T> |
| 77 | +struct DSC3DMetric |
| 78 | +{ |
| 79 | + using value_type = T; |
| 80 | + using result_type = T; |
| 81 | + |
| 82 | + T operator()(const toolbox::pcl::dsc3d_signature_t<T>& a, |
| 83 | + const toolbox::pcl::dsc3d_signature_t<T>& b) const |
| 84 | + { |
| 85 | + return a.distance(b); |
| 86 | + } |
| 87 | + |
| 88 | + T distance(const toolbox::pcl::dsc3d_signature_t<T>& a, |
| 89 | + const toolbox::pcl::dsc3d_signature_t<T>& b) const |
| 90 | + { |
| 91 | + return a.distance(b); |
| 92 | + } |
| 93 | +}; |
| 94 | + |
75 | 95 | } // namespace toolbox::metrics |
76 | 96 |
|
77 | 97 | using namespace toolbox::pcl; |
@@ -188,6 +208,42 @@ create_test_shot_descriptors(size_t num_descriptors, std::mt19937& rng) |
188 | 208 | return {descriptors, indices}; |
189 | 209 | } |
190 | 210 |
|
| 211 | +// 创建测试3DSC描述子 / Create test 3DSC descriptors |
| 212 | +template<typename T> |
| 213 | +std::pair<std::shared_ptr<std::vector<dsc3d_signature_t<T>>>, |
| 214 | + std::shared_ptr<std::vector<std::size_t>>> |
| 215 | +create_test_3dsc_descriptors(size_t num_descriptors, std::mt19937& rng) |
| 216 | +{ |
| 217 | + auto descriptors = std::make_shared<std::vector<dsc3d_signature_t<T>>>(); |
| 218 | + auto indices = std::make_shared<std::vector<std::size_t>>(); |
| 219 | + |
| 220 | + std::uniform_real_distribution<T> dist(0.0, 1.0); |
| 221 | + |
| 222 | + for (size_t i = 0; i < num_descriptors; ++i) { |
| 223 | + dsc3d_signature_t<T> desc; |
| 224 | + |
| 225 | + // 创建随机描述子 / Create random descriptor (1980 dimensions) |
| 226 | + for (int j = 0; j < 1980; ++j) { |
| 227 | + desc.histogram[j] = dist(rng); |
| 228 | + } |
| 229 | + |
| 230 | + // 归一化 / Normalize |
| 231 | + T sum = 0; |
| 232 | + for (int j = 0; j < 1980; ++j) { |
| 233 | + sum += desc.histogram[j]; |
| 234 | + } |
| 235 | + if (sum > 0) { |
| 236 | + for (int j = 0; j < 1980; ++j) { |
| 237 | + desc.histogram[j] /= sum; |
| 238 | + } |
| 239 | + } |
| 240 | + |
| 241 | + descriptors->push_back(desc); |
| 242 | + indices->push_back(i * 10); |
| 243 | + } |
| 244 | + |
| 245 | + return {descriptors, indices}; |
| 246 | +} |
191 | 247 |
|
192 | 248 | TEST_CASE("对应点生成性能比较 / Correspondence Generation Performance Comparison", |
193 | 249 | "[pcl][correspondence][benchmark]") |
@@ -375,6 +431,57 @@ TEST_CASE("对应点生成性能比较 / Correspondence Generation Performance C |
375 | 431 | }; |
376 | 432 | } |
377 | 433 |
|
| 434 | + SECTION("3DSC描述子性能 / 3DSC descriptor performance") |
| 435 | + { |
| 436 | + auto src_data = create_test_3dsc_descriptors<T>(num_desc, rng); |
| 437 | + auto dst_data = create_test_3dsc_descriptors<T>(num_desc, rng); |
| 438 | + auto src_descriptors = src_data.first; |
| 439 | + auto src_indices = src_data.second; |
| 440 | + auto dst_descriptors = dst_data.first; |
| 441 | + auto dst_indices = dst_data.second; |
| 442 | + |
| 443 | + BENCHMARK("3DSC - KNN方法 / 3DSC - KNN method") |
| 444 | + { |
| 445 | + using CorrespondenceGen = knn_correspondence_generator_t< |
| 446 | + T, |
| 447 | + dsc3d_signature_t<T>, |
| 448 | + bfknn_generic_t<dsc3d_signature_t<T>, |
| 449 | + toolbox::metrics::DSC3DMetric<T>>>; |
| 450 | + CorrespondenceGen corr_gen; |
| 451 | + |
| 452 | + auto knn = std::make_shared< |
| 453 | + bfknn_generic_t<dsc3d_signature_t<T>, |
| 454 | + toolbox::metrics::DSC3DMetric<T>>>(); |
| 455 | + corr_gen.set_knn(knn); |
| 456 | + corr_gen.set_source(src_cloud, src_descriptors, src_indices); |
| 457 | + corr_gen.set_destination(dst_cloud, dst_descriptors, dst_indices); |
| 458 | + corr_gen.set_ratio(0.8f); |
| 459 | + corr_gen.set_mutual_verification(true); |
| 460 | + |
| 461 | + std::vector<correspondence_t> correspondences; |
| 462 | + corr_gen.compute(correspondences); |
| 463 | + |
| 464 | + return correspondences.size(); |
| 465 | + }; |
| 466 | + |
| 467 | + BENCHMARK("3DSC - 暴力搜索(并行) / 3DSC - Brute-force (parallel)") |
| 468 | + { |
| 469 | + brute_force_correspondence_generator_t<T, dsc3d_signature_t<T>> |
| 470 | + corr_gen; |
| 471 | + |
| 472 | + corr_gen.enable_parallel(true); |
| 473 | + corr_gen.set_source(src_cloud, src_descriptors, src_indices); |
| 474 | + corr_gen.set_destination(dst_cloud, dst_descriptors, dst_indices); |
| 475 | + corr_gen.set_ratio(0.8f); |
| 476 | + corr_gen.set_mutual_verification(true); |
| 477 | + |
| 478 | + std::vector<correspondence_t> correspondences; |
| 479 | + corr_gen.compute(correspondences); |
| 480 | + |
| 481 | + return correspondences.size(); |
| 482 | + }; |
| 483 | + } |
| 484 | + |
378 | 485 | } |
379 | 486 |
|
380 | 487 | SECTION("不同描述子数量的性能影响 / Performance impact of different descriptor counts") |
@@ -509,6 +616,39 @@ TEST_CASE("对应点生成性能比较 / Correspondence Generation Performance C |
509 | 616 | return correspondences.size(); |
510 | 617 | }; |
511 | 618 | } |
| 619 | + |
| 620 | + DYNAMIC_SECTION("3DSC描述子数量 / 3DSC descriptor count: " << num_desc) |
| 621 | + { |
| 622 | + std::mt19937 rng(42); |
| 623 | + auto src_data = create_test_3dsc_descriptors<T>(num_desc, rng); |
| 624 | + auto dst_data = create_test_3dsc_descriptors<T>(num_desc, rng); |
| 625 | + auto src_descriptors = src_data.first; |
| 626 | + auto src_indices = src_data.second; |
| 627 | + auto dst_descriptors = dst_data.first; |
| 628 | + auto dst_indices = dst_data.second; |
| 629 | + |
| 630 | + auto src_cloud = std::make_shared<point_cloud_t<T>>(); |
| 631 | + auto dst_cloud = std::make_shared<point_cloud_t<T>>(); |
| 632 | + src_cloud->points.resize(num_desc * 10); |
| 633 | + dst_cloud->points.resize(num_desc * 10); |
| 634 | + |
| 635 | + BENCHMARK("3DSC - 暴力搜索(并行) / 3DSC - Brute-force (parallel)") |
| 636 | + { |
| 637 | + brute_force_correspondence_generator_t<T, dsc3d_signature_t<T>> |
| 638 | + corr_gen; |
| 639 | + |
| 640 | + corr_gen.enable_parallel(true); |
| 641 | + corr_gen.set_source(src_cloud, src_descriptors, src_indices); |
| 642 | + corr_gen.set_destination(dst_cloud, dst_descriptors, dst_indices); |
| 643 | + corr_gen.set_ratio(0.8f); |
| 644 | + corr_gen.set_mutual_verification(true); |
| 645 | + |
| 646 | + std::vector<correspondence_t> correspondences; |
| 647 | + corr_gen.compute(correspondences); |
| 648 | + |
| 649 | + return correspondences.size(); |
| 650 | + }; |
| 651 | + } |
512 | 652 | } |
513 | 653 | } |
514 | 654 |
|
@@ -684,6 +824,26 @@ TEST_CASE("描述子维度对性能的影响 / Impact of descriptor dimensions o |
684 | 824 | }; |
685 | 825 | } |
686 | 826 |
|
| 827 | + // 3DSC (1980维) / 3DSC (1980 dimensions) |
| 828 | + { |
| 829 | + auto src_data = create_test_3dsc_descriptors<T>(num_desc, rng); |
| 830 | + auto dst_data = create_test_3dsc_descriptors<T>(num_desc, rng); |
| 831 | + |
| 832 | + BENCHMARK("3DSC (1980维) - 暴力搜索 / 3DSC (1980D) - Brute-force") |
| 833 | + { |
| 834 | + brute_force_correspondence_generator_t<T, dsc3d_signature_t<T>> corr_gen; |
| 835 | + corr_gen.enable_parallel(true); |
| 836 | + corr_gen.set_source(src_cloud, src_data.first, src_data.second); |
| 837 | + corr_gen.set_destination(dst_cloud, dst_data.first, dst_data.second); |
| 838 | + corr_gen.set_ratio(0.8f); |
| 839 | + corr_gen.set_mutual_verification(true); |
| 840 | + |
| 841 | + std::vector<correspondence_t> correspondences; |
| 842 | + corr_gen.compute(correspondences); |
| 843 | + return correspondences.size(); |
| 844 | + }; |
| 845 | + } |
| 846 | + |
687 | 847 | } |
688 | 848 | } |
689 | 849 |
|
|
0 commit comments