Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional indices arg for fast computation of a small subset of FPFH features #7118

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
- Fix render to depth image on Apple Retina displays (PR #7001)
- Fix infinite loop in segment_plane if num_points < ransac_n (PR #7032)
- Add select_by_index method to Feature class (PR #7039)
- Add optional indices arg for fast computation of a small subset of FPFH features (PR #7118).


## 0.13
Expand Down
195 changes: 162 additions & 33 deletions cpp/benchmarks/t/pipelines/registration/Feature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,40 @@ static const std::string path = pointcloud_ply.GetPath();

void LegacyComputeFPFHFeature(benchmark::State& state,
utility::optional<int> max_nn,
utility::optional<double> radius) {
utility::optional<double> radius,
utility::optional<double> ratio_indices) {
auto pcd = open3d::io::CreatePointCloudFromFile(path)->UniformDownSample(3);
pcd->EstimateNormals();

utility::optional<std::vector<size_t>> indices = utility::nullopt;
if (ratio_indices.has_value()) {
std::vector<size_t> indices_tmp;
size_t step = 1.0 / ratio_indices.value();
size_t n_indices = pcd->points_.size() / step;
indices_tmp.reserve(n_indices);
for (size_t index = 0; index < pcd->points_.size(); index += step) {
indices_tmp.push_back(index);
}
indices.emplace(indices_tmp);
}

for (auto _ : state) {
if (max_nn.has_value() && radius.has_value()) {
auto fpfh = open3d::pipelines::registration::ComputeFPFHFeature(
*pcd, open3d::geometry::KDTreeSearchParamHybrid(
radius.value(), max_nn.value()));
*pcd,
open3d::geometry::KDTreeSearchParamHybrid(radius.value(),
max_nn.value()),
indices);
} else if (max_nn.has_value() && !radius.has_value()) {
auto fpfh = open3d::pipelines::registration::ComputeFPFHFeature(
*pcd,
open3d::geometry::KDTreeSearchParamKNN(max_nn.value()));
open3d::geometry::KDTreeSearchParamKNN(max_nn.value()),
indices);
} else if (!max_nn.has_value() && radius.has_value()) {
auto fpfh = open3d::pipelines::registration::ComputeFPFHFeature(
*pcd,
open3d::geometry::KDTreeSearchParamRadius(radius.value()));
open3d::geometry::KDTreeSearchParamRadius(radius.value()),
indices);
}
}
}
Expand All @@ -50,81 +68,192 @@ void ComputeFPFHFeature(benchmark::State& state,
const core::Device& device,
const core::Dtype& dtype,
utility::optional<int> max_nn,
utility::optional<double> radius) {
utility::optional<double> radius,
utility::optional<double> ratio_indices) {
t::geometry::PointCloud pcd;
t::io::ReadPointCloud(path, pcd);
pcd = pcd.To(device).UniformDownSample(3);
pcd.SetPointPositions(pcd.GetPointPositions().To(dtype));
pcd.EstimateNormals();

utility::optional<core::Tensor> indices = utility::nullopt;
if (ratio_indices.has_value()) {
std::vector<int64_t> indices_tmp;
int64_t step = 1.0 / ratio_indices.value();
int64_t n_indices = pcd.GetPointPositions().GetLength() / step;
indices_tmp.reserve(n_indices);
for (int64_t index = 0; index < pcd.GetPointPositions().GetLength();
index += step) {
indices_tmp.push_back(index);
}
indices.emplace(core::Tensor(indices_tmp, {(int)indices_tmp.size()},
core::Int64, device));
}

core::Tensor fpfh;
// Warm up.
fpfh = t::pipelines::registration::ComputeFPFHFeature(pcd, max_nn, radius);
fpfh = t::pipelines::registration::ComputeFPFHFeature(pcd, max_nn, radius,
indices);

for (auto _ : state) {
fpfh = t::pipelines::registration::ComputeFPFHFeature(pcd, max_nn,
radius);
radius, indices);
core::cuda::Synchronize(device);
}
}

BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Hybrid[0.01 | 100],
100,
0.01)
0.01,
utility::nullopt)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature, Legacy Hybrid[0.02 | 50], 50, 0.02)
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Hybrid[0.02 | 50],
50,
0.02,
utility::nullopt)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Hybrid[0.02 | 100],
100,
0.02)
0.02,
utility::nullopt)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy KNN[50],
50,
utility::nullopt,
utility::nullopt)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy KNN[100],
100,
utility::nullopt,
utility::nullopt)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Radius[0.01],
utility::nullopt,
0.01)
0.01,
utility::nullopt)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Radius[0.02],
utility::nullopt,
0.02)
0.02,
utility::nullopt)
->Unit(benchmark::kMillisecond);

BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Hybrid Indices[0.02 | 50 | null],
50,
0.02,
utility::nullopt)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Hybrid Indices[0.02 | 50 | 0.0001],
50,
0.02,
0.0001)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Hybrid Indices[0.02 | 50 | 0.001],
50,
0.02,
0.001)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Hybrid Indices[0.02 | 50 | 0.01],
50,
0.02,
0.01)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Hybrid Indices[0.02 | 50 | 0.1],
50,
0.02,
0.1)
->Unit(benchmark::kMillisecond);
BENCHMARK_CAPTURE(LegacyComputeFPFHFeature,
Legacy Hybrid Indices[0.02 | 50 | 1.0],
50,
0.02,
1.0)
->Unit(benchmark::kMillisecond);

#define ENUM_FPFH_METHOD_DEVICE(METHOD_NAME, MAX_NN, RADIUS, DEVICE) \
BENCHMARK_CAPTURE(ComputeFPFHFeature, METHOD_NAME##_Float32, \
core::Device(DEVICE), core::Float32, MAX_NN, RADIUS) \
->Unit(benchmark::kMillisecond); \
BENCHMARK_CAPTURE(ComputeFPFHFeature, DEVICE METHOD_NAME##_Float64, \
core::Device(DEVICE), core::Float32, MAX_NN, RADIUS) \
#define ENUM_FPFH_METHOD_DEVICE(METHOD_NAME, MAX_NN, RADIUS, INDICES, DEVICE) \
BENCHMARK_CAPTURE(ComputeFPFHFeature, METHOD_NAME##_Float32, \
core::Device(DEVICE), core::Float32, MAX_NN, RADIUS, \
INDICES) \
->Unit(benchmark::kMillisecond); \
BENCHMARK_CAPTURE(ComputeFPFHFeature, METHOD_NAME##_Float64, \
core::Device(DEVICE), core::Float64, MAX_NN, RADIUS, \
INDICES) \
->Unit(benchmark::kMillisecond);

ENUM_FPFH_METHOD_DEVICE(CPU[0.02 | 50] Hybrid, 100, 0.01, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(CPU[0.02 | 50] Hybrid, 50, 0.02, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(CPU[0.02 | 100] Hybrid, 100, 0.02, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(CPU[50] KNN, 50, utility::nullopt, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(CPU[100] KNN, 100, utility::nullopt, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(CPU[0.01] Radius, utility::nullopt, 0.01, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(CPU[0.02] Radius, utility::nullopt, 0.02, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[0.01 | 100] Hybrid, 100, 0.01, utility::nullopt, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[0.02 | 50] Hybrid, 50, 0.02, utility::nullopt, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[0.02 | 100] Hybrid, 100, 0.02, utility::nullopt, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[50] KNN, 50, utility::nullopt, utility::nullopt, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[100] KNN, 100, utility::nullopt, utility::nullopt, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[0.01] Radius, utility::nullopt, 0.01, utility::nullopt, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[0.02] Radius, utility::nullopt, 0.02, utility::nullopt, "CPU:0")

ENUM_FPFH_METHOD_DEVICE(CPU[0.02 | 50 | null] Hybrid Indices,
50,
0.02,
utility::nullopt,
"CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[0.02 | 50 | 0.0001] Hybrid Indices, 50, 0.02, 0.0001, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[0.02 | 50 | 0.001] Hybrid Indices, 50, 0.02, 0.001, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[0.02 | 50 | 0.01] Hybrid Indices, 50, 0.02, 0.01, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[0.02 | 50 | 0.1] Hybrid Indices, 50, 0.02, 0.1, "CPU:0")
ENUM_FPFH_METHOD_DEVICE(
CPU[0.02 | 50 | 1.0] Hybrid Indices, 50, 0.02, 1.0, "CPU:0")

#ifdef BUILD_CUDA_MODULE
ENUM_FPFH_METHOD_DEVICE(CUDA[0.02 | 50] Hybrid, 100, 0.01, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(CUDA[0.02 | 50] Hybrid, 50, 0.01, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(CUDA[0.02 | 100] Hybrid, 100, 0.02, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(CUDA[50] KNN, 50, utility::nullopt, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(CUDA[100] KNN, 100, utility::nullopt, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(CUDA[0.01] Radius, utility::nullopt, 0.01, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(CUDA[0.02] Radius, utility::nullopt, 0.02, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[0.01 | 100] Hybrid, 100, 0.01, utility::nullopt, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[0.02 | 50] Hybrid, 50, 0.02, utility::nullopt, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[0.02 | 100] Hybrid, 100, 0.02, utility::nullopt, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[50] KNN, 50, utility::nullopt, utility::nullopt, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[100] KNN, 100, utility::nullopt, utility::nullopt, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[0.01] Radius, utility::nullopt, 0.01, utility::nullopt, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[0.02] Radius, utility::nullopt, 0.02, utility::nullopt, "CUDA:0")

ENUM_FPFH_METHOD_DEVICE(CUDA[0.02 | 50 | null] Hybrid Indices,
50,
0.02,
utility::nullopt,
"CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[0.02 | 50 | 0.0001] Hybrid Indices, 50, 0.02, 0.0001, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[0.02 | 50 | 0.001] Hybrid Indices, 50, 0.02, 0.001, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[0.02 | 50 | 0.01] Hybrid Indices, 50, 0.02, 0.01, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[0.02 | 50 | 0.1] Hybrid Indices, 50, 0.02, 0.1, "CUDA:0")
ENUM_FPFH_METHOD_DEVICE(
CUDA[0.02 | 50 | 1.0] Hybrid Indices, 50, 0.02, 1.0, "CUDA:0")
#endif

} // namespace registration
Expand Down
Loading
Loading