ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Feature.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <benchmark/benchmark.h>
11 #include <ecvFeature.h>
12 
18 
19 namespace cloudViewer {
20 namespace t {
21 namespace pipelines {
22 namespace registration {
23 
25 static const std::string path = pointcloud_ply.GetPath();
26 
27 void LegacyComputeFPFHFeature(benchmark::State& state,
30  utility::optional<double> ratio_indices) {
31  auto pcd =
33  3);
34  pcd->EstimateNormals();
35 
37  if (ratio_indices.has_value()) {
38  std::vector<size_t> indices_tmp;
39  size_t step = 1.0 / ratio_indices.value();
40  size_t n_indices = pcd->size() / step;
41  indices_tmp.reserve(n_indices);
42  for (size_t index = 0; index < pcd->size(); index += step) {
43  indices_tmp.push_back(index);
44  }
45  indices.emplace(indices_tmp);
46  }
47 
48  for (auto _ : state) {
49  if (max_nn.has_value() && radius.has_value()) {
51  *pcd,
53  radius.value(), max_nn.value()),
54  indices);
55  } else if (max_nn.has_value() && !radius.has_value()) {
57  *pcd,
59  indices);
60  } else if (!max_nn.has_value() && radius.has_value()) {
62  *pcd,
64  radius.value()),
65  indices);
66  }
67  }
68 }
69 
70 void ComputeFPFHFeature(benchmark::State& state,
71  const core::Device& device,
72  const core::Dtype& dtype,
75  utility::optional<double> ratio_indices) {
78  pcd = pcd.To(device).UniformDownSample(3);
79  pcd.SetPointPositions(pcd.GetPointPositions().To(dtype));
80  pcd.EstimateNormals();
81 
83  if (ratio_indices.has_value()) {
84  std::vector<int64_t> indices_tmp;
85  int64_t step = 1.0 / ratio_indices.value();
86  int64_t n_indices = pcd.GetPointPositions().GetLength() / step;
87  indices_tmp.reserve(n_indices);
88  for (int64_t index = 0; index < pcd.GetPointPositions().GetLength();
89  index += step) {
90  indices_tmp.push_back(index);
91  }
92  indices.emplace(core::Tensor(indices_tmp, {(int)indices_tmp.size()},
93  core::Int64, device));
94  }
95 
96  core::Tensor fpfh;
97  // Warm up.
98  fpfh = t::pipelines::registration::ComputeFPFHFeature(pcd, max_nn, radius,
99  indices);
100 
101  for (auto _ : state) {
103  radius, indices);
104  core::cuda::Synchronize(device);
105  }
106 }
107 
109  Legacy Hybrid[0.01 | 100],
110  100,
111  0.01,
113  ->Unit(benchmark::kMillisecond);
115  Legacy Hybrid[0.02 | 50],
116  50,
117  0.02,
119  ->Unit(benchmark::kMillisecond);
121  Legacy Hybrid[0.02 | 100],
122  100,
123  0.02,
125  ->Unit(benchmark::kMillisecond);
127  Legacy KNN[50],
128  50,
131  ->Unit(benchmark::kMillisecond);
133  Legacy KNN[100],
134  100,
137  ->Unit(benchmark::kMillisecond);
139  Legacy Radius[0.01],
141  0.01,
143  ->Unit(benchmark::kMillisecond);
145  Legacy Radius[0.02],
147  0.02,
149  ->Unit(benchmark::kMillisecond);
150 
152  Legacy Hybrid Indices[0.02 | 50 | null],
153  50,
154  0.02,
156  ->Unit(benchmark::kMillisecond);
158  Legacy Hybrid Indices[0.02 | 50 | 0.0001],
159  50,
160  0.02,
161  0.0001)
162  ->Unit(benchmark::kMillisecond);
164  Legacy Hybrid Indices[0.02 | 50 | 0.001],
165  50,
166  0.02,
167  0.001)
168  ->Unit(benchmark::kMillisecond);
170  Legacy Hybrid Indices[0.02 | 50 | 0.01],
171  50,
172  0.02,
173  0.01)
174  ->Unit(benchmark::kMillisecond);
176  Legacy Hybrid Indices[0.02 | 50 | 0.1],
177  50,
178  0.02,
179  0.1)
180  ->Unit(benchmark::kMillisecond);
182  Legacy Hybrid Indices[0.02 | 50 | 1.0],
183  50,
184  0.02,
185  1.0)
186  ->Unit(benchmark::kMillisecond);
187 
188 #define ENUM_FPFH_METHOD_DEVICE(METHOD_NAME, MAX_NN, RADIUS, INDICES, DEVICE) \
189  BENCHMARK_CAPTURE(ComputeFPFHFeature, METHOD_NAME##_Float32, \
190  core::Device(DEVICE), core::Float32, MAX_NN, RADIUS, \
191  INDICES) \
192  ->Unit(benchmark::kMillisecond); \
193  BENCHMARK_CAPTURE(ComputeFPFHFeature, METHOD_NAME##_Float64, \
194  core::Device(DEVICE), core::Float64, MAX_NN, RADIUS, \
195  INDICES) \
196  ->Unit(benchmark::kMillisecond);
197 
199  CPU[0.01 | 100] Hybrid, 100, 0.01, utility::nullopt, "CPU:0")
201  CPU[0.02 | 50] Hybrid, 50, 0.02, utility::nullopt, "CPU:0")
203  CPU[0.02 | 100] Hybrid, 100, 0.02, utility::nullopt, "CPU:0")
205  CPU[50] KNN, 50, utility::nullopt, utility::nullopt, "CPU:0")
207  CPU[100] KNN, 100, utility::nullopt, utility::nullopt, "CPU:0")
209  CPU[0.01] Radius, utility::nullopt, 0.01, utility::nullopt, "CPU:0")
211  CPU[0.02] Radius, utility::nullopt, 0.02, utility::nullopt, "CPU:0")
212 
213 ENUM_FPFH_METHOD_DEVICE(CPU[0.02 | 50 | null] Hybrid Indices,
214  50,
215  0.02,
216  utility::nullopt,
217  "CPU:0")
219  CPU[0.02 | 50 | 0.0001] Hybrid Indices, 50, 0.02, 0.0001, "CPU:0")
221  CPU[0.02 | 50 | 0.001] Hybrid Indices, 50, 0.02, 0.001, "CPU:0")
223  CPU[0.02 | 50 | 0.01] Hybrid Indices, 50, 0.02, 0.01, "CPU:0")
225  CPU[0.02 | 50 | 0.1] Hybrid Indices, 50, 0.02, 0.1, "CPU:0")
227  CPU[0.02 | 50 | 1.0] Hybrid Indices, 50, 0.02, 1.0, "CPU:0")
228 
229 #ifdef BUILD_CUDA_MODULE
231  CUDA[0.01 | 100] Hybrid, 100, 0.01, utility::nullopt, "CUDA:0")
233  CUDA[0.02 | 50] Hybrid, 50, 0.02, utility::nullopt, "CUDA:0")
235  CUDA[0.02 | 100] Hybrid, 100, 0.02, utility::nullopt, "CUDA:0")
237  CUDA[50] KNN, 50, utility::nullopt, utility::nullopt, "CUDA:0")
239  CUDA[100] KNN, 100, utility::nullopt, utility::nullopt, "CUDA:0")
241  CUDA[0.01] Radius, utility::nullopt, 0.01, utility::nullopt, "CUDA:0")
243  CUDA[0.02] Radius, utility::nullopt, 0.02, utility::nullopt, "CUDA:0")
244 
245 ENUM_FPFH_METHOD_DEVICE(CUDA[0.02 | 50 | null] Hybrid Indices,
246  50,
247  0.02,
248  utility::nullopt,
249  "CUDA:0")
251  CUDA[0.02 | 50 | 0.0001] Hybrid Indices, 50, 0.02, 0.0001, "CUDA:0")
253  CUDA[0.02 | 50 | 0.001] Hybrid Indices, 50, 0.02, 0.001, "CUDA:0")
255  CUDA[0.02 | 50 | 0.01] Hybrid Indices, 50, 0.02, 0.01, "CUDA:0")
257  CUDA[0.02 | 50 | 0.1] Hybrid Indices, 50, 0.02, 0.1, "CUDA:0")
259  CUDA[0.02 | 50 | 1.0] Hybrid Indices, 50, 0.02, 1.0, "CUDA:0")
260 #endif
261 
262 } // namespace registration
263 } // namespace pipelines
264 } // namespace t
265 } // namespace cloudViewer
Common CUDA utilities.
#define ENUM_FPFH_METHOD_DEVICE(METHOD_NAME, MAX_NN, RADIUS, INDICES, DEVICE)
Definition: Feature.cpp:188
int64_t GetLength() const
Definition: Tensor.h:1125
Tensor To(Dtype dtype, bool copy=false) const
Definition: Tensor.cpp:739
Data class for BunnyMesh contains the BunnyMesh.ply from the Stanford 3D Scanning Repository.
Definition: Dataset.h:234
std::string GetPath() const
Path to the BunnyMesh.ply file.
Definition: Dataset.h:239
KDTree search parameters for hybrid KNN and radius search.
KDTree search parameters for pure KNN search.
KDTree search parameters for pure radius search.
A point cloud contains a list of 3D points.
Definition: PointCloud.h:82
void EstimateNormals(const utility::optional< int > max_nn=30, const utility::optional< double > radius=utility::nullopt)
Function to estimate point normals. If the point cloud normals exist, the estimated normals are orien...
Definition: PointCloud.cpp:619
void SetPointPositions(const core::Tensor &value)
Set the value of the "positions" attribute. Convenience function.
Definition: PointCloud.h:186
core::Tensor & GetPointPositions()
Get the value of the "positions" attribute. Convenience function.
Definition: PointCloud.h:124
PointCloud To(const core::Device &device, bool copy=false) const
Definition: PointCloud.cpp:112
PointCloud UniformDownSample(size_t every_k_points) const
Downsamples a point cloud by selecting every kth index point and its attributes.
Definition: PointCloud.cpp:345
void emplace(Args &&... args)
Definition: Optional.h:410
constexpr bool has_value() const noexcept
Definition: Optional.h:440
constexpr T const & value() const &
Definition: Optional.h:465
const Dtype Int64
Definition: Dtype.cpp:47
std::shared_ptr< ccPointCloud > CreatePointCloudFromFile(const std::string &filename, const std::string &format, bool print_progress)
bool ReadPointCloud(const std::string &filename, geometry::PointCloud &pointcloud, const cloudViewer::io::ReadPointCloudOption &params)
static const std::string path
Definition: Feature.cpp:25
core::Tensor ComputeFPFHFeature(const geometry::PointCloud &input, const utility::optional< int > max_nn, const utility::optional< double > radius, const utility::optional< core::Tensor > &indices)
Definition: Feature.cpp:23
void LegacyComputeFPFHFeature(benchmark::State &state, utility::optional< int > max_nn, utility::optional< double > radius, utility::optional< double > ratio_indices)
Definition: Feature.cpp:27
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature, Legacy Hybrid[0.01|100], 100, 0.01, utility::nullopt) -> Unit(benchmark::kMillisecond)
constexpr nullopt_t nullopt
Definition: Optional.h:136
std::shared_ptr< Feature > ComputeFPFHFeature(const ccPointCloud &input, const geometry::KDTreeSearchParam &search_param=geometry::KDTreeSearchParamKNN(), const utility::optional< std::vector< size_t >> &indices=utility::nullopt)
Generic file read and write utility for python interface.