Skip to content
Merged
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
4 changes: 4 additions & 0 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ PCL_ADD_BENCHMARK(features_normal_3d FILES features/normal_3d.cpp
ARGUMENTS "${PCL_SOURCE_DIR}/test/table_scene_mug_stereo_textured.pcd"
"${PCL_SOURCE_DIR}/test/milk_cartoon_all_small_clorox.pcd")

PCL_ADD_BENCHMARK(features_shot FILES features/shot.cpp
LINK_WITH pcl_io pcl_search pcl_features
ARGUMENTS "${PCL_SOURCE_DIR}/test/milk_cartoon_all_small_clorox.pcd")

PCL_ADD_BENCHMARK(filters_voxel_grid FILES filters/voxel_grid.cpp
LINK_WITH pcl_io pcl_filters
ARGUMENTS "${PCL_SOURCE_DIR}/test/table_scene_mug_stereo_textured.pcd"
Expand Down
184 changes: 184 additions & 0 deletions benchmarks/features/shot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#include <pcl/features/normal_3d_omp.h>
#include <pcl/features/shot_omp.h>
#include <pcl/filters/uniform_sampling.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

#include <benchmark/benchmark.h>

constexpr float lrf_radius = 0.04f;
constexpr float shot_search_radius = 0.04f;
constexpr float uniform_sampling_radius = 0.03f;

static void
BM_SHOT352(benchmark::State& state, const std::string& file)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDReader reader;
reader.read(file, *cloud);

pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
ne.setInputCloud(cloud);
ne.setKSearch(10);
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
ne.compute(*normals);

pcl::UniformSampling<pcl::PointXYZ> uniform_sampling;
uniform_sampling.setInputCloud(cloud);
uniform_sampling.setRadiusSearch(uniform_sampling_radius);
pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints(new pcl::PointCloud<pcl::PointXYZ>);
uniform_sampling.filter(*keypoints);

pcl::SHOTEstimation<pcl::PointXYZ, pcl::Normal, pcl::SHOT352> shot;
shot.setInputCloud(keypoints);
shot.setInputNormals(normals);
shot.setSearchSurface(cloud);
shot.setRadiusSearch(shot_search_radius);
shot.setLRFRadius(lrf_radius);

pcl::PointCloud<pcl::SHOT352>::Ptr output(new pcl::PointCloud<pcl::SHOT352>);
for (auto _ : state) {
shot.compute(*output);
}
}

static void
BM_SHOT352_OMP(benchmark::State& state, const std::string& file)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDReader reader;
reader.read(file, *cloud);

pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
ne.setInputCloud(cloud);
ne.setKSearch(10);
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
ne.compute(*normals);

pcl::UniformSampling<pcl::PointXYZ> uniform_sampling;
uniform_sampling.setInputCloud(cloud);
uniform_sampling.setRadiusSearch(uniform_sampling_radius);
pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints(new pcl::PointCloud<pcl::PointXYZ>);
uniform_sampling.filter(*keypoints);

pcl::SHOTEstimationOMP<pcl::PointXYZ, pcl::Normal, pcl::SHOT352> shot(
0, state.range(0) //
);
shot.setInputCloud(keypoints);
shot.setInputNormals(normals);
shot.setSearchSurface(cloud);
shot.setRadiusSearch(shot_search_radius);
shot.setLRFRadius(lrf_radius);

pcl::PointCloud<pcl::SHOT352>::Ptr output(new pcl::PointCloud<pcl::SHOT352>);
for (auto _ : state) {
shot.compute(*output);
}
}

static void
BM_SHOT1344(benchmark::State& state, const std::string& file)
{
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_rgba(
new pcl::PointCloud<pcl::PointXYZRGBA>);
pcl::PCDReader reader;
reader.read(file, *cloud_rgba);

pcl::NormalEstimationOMP<pcl::PointXYZRGBA, pcl::Normal> ne;
ne.setInputCloud(cloud_rgba);
ne.setKSearch(10);
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
ne.compute(*normals);

pcl::UniformSampling<pcl::PointXYZRGBA> uniform_sampling;
uniform_sampling.setInputCloud(cloud_rgba);
uniform_sampling.setRadiusSearch(uniform_sampling_radius);
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr keypoints(
new pcl::PointCloud<pcl::PointXYZRGBA>);
uniform_sampling.filter(*keypoints);

pcl::SHOTColorEstimation<pcl::PointXYZRGBA, pcl::Normal, pcl::SHOT1344> shot(true,
true);
shot.setInputCloud(keypoints);
shot.setInputNormals(normals);
shot.setSearchSurface(cloud_rgba);
shot.setRadiusSearch(shot_search_radius);
shot.setLRFRadius(lrf_radius);

pcl::PointCloud<pcl::SHOT1344>::Ptr output(new pcl::PointCloud<pcl::SHOT1344>);
for (auto _ : state) {
shot.compute(*output);
}
}

static void
BM_SHOT1344_OMP(benchmark::State& state, const std::string& file)
{
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud_rgba(
new pcl::PointCloud<pcl::PointXYZRGBA>);
pcl::PCDReader reader;
reader.read(file, *cloud_rgba);

pcl::NormalEstimationOMP<pcl::PointXYZRGBA, pcl::Normal> ne;
ne.setInputCloud(cloud_rgba);
ne.setKSearch(10);
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
ne.compute(*normals);

pcl::UniformSampling<pcl::PointXYZRGBA> uniform_sampling;
uniform_sampling.setInputCloud(cloud_rgba);
uniform_sampling.setRadiusSearch(uniform_sampling_radius);
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr keypoints(
new pcl::PointCloud<pcl::PointXYZRGBA>);
uniform_sampling.filter(*keypoints);

pcl::SHOTColorEstimationOMP<pcl::PointXYZRGBA, pcl::Normal, pcl::SHOT1344> shot(
true, true, 0, state.range(0));
shot.setInputCloud(keypoints);
shot.setInputNormals(normals);
shot.setSearchSurface(cloud_rgba);
shot.setRadiusSearch(shot_search_radius);
shot.setLRFRadius(lrf_radius);

pcl::PointCloud<pcl::SHOT1344>::Ptr output(new pcl::PointCloud<pcl::SHOT1344>);
for (auto _ : state) {
shot.compute(*output);
}
}

int
main(int argc, char** argv)
{
if (argc < 2) {
std::cerr << "No test files given. Please provide a PCD file path to use for "
"both SHOT352 and SHOT1344 benchmarks."
<< std::endl;
return (-1);
}

constexpr int runs = 100;

benchmark::RegisterBenchmark("BM_SHOT352", &BM_SHOT352, argv[1])
->Unit(benchmark::kMillisecond)
->Iterations(runs);
benchmark::RegisterBenchmark("BM_SHOT352_OMP", &BM_SHOT352_OMP, argv[1])
->Arg(64)
->Arg(128)
->Arg(256)
->Unit(benchmark::kMillisecond)
->Iterations(runs);

benchmark::RegisterBenchmark("BM_SHOT1344", &BM_SHOT1344, argv[1])
->Unit(benchmark::kMillisecond)
->Iterations(runs);
benchmark::RegisterBenchmark("BM_SHOT1344_OMP", &BM_SHOT1344_OMP, argv[1])
->Arg(64)
->Arg(128)
->Arg(256)
->Unit(benchmark::kMillisecond)
->Iterations(runs);

benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks();
}
6 changes: 4 additions & 2 deletions features/include/pcl/features/impl/shot_omp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ pcl::SHOTEstimationOMP<PointInT, PointNT, PointOutT, PointRFT>::computeFeature (
#pragma omp parallel for \
default(none) \
shared(output) \
num_threads(threads_)
num_threads(threads_) \
schedule(dynamic, chunk_size_)
for (std::ptrdiff_t idx = 0; idx < static_cast<std::ptrdiff_t> (indices_->size ()); ++idx)
{

Expand Down Expand Up @@ -240,7 +241,8 @@ pcl::SHOTColorEstimationOMP<PointInT, PointNT, PointOutT, PointRFT>::computeFeat
#pragma omp parallel for \
default(none) \
shared(output) \
num_threads(threads_)
num_threads(threads_) \
schedule(dynamic, chunk_size_)
for (std::ptrdiff_t idx = 0; idx < static_cast<std::ptrdiff_t> (indices_->size ()); ++idx)
{
Eigen::VectorXf shot;
Expand Down
25 changes: 20 additions & 5 deletions features/include/pcl/features/shot_omp.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,12 @@ namespace pcl
using PointCloudOut = typename Feature<PointInT, PointOutT>::PointCloudOut;
using PointCloudIn = typename Feature<PointInT, PointOutT>::PointCloudIn;

/** \brief Empty constructor. */
SHOTEstimationOMP (unsigned int nr_threads = 0) : SHOTEstimation<PointInT, PointNT, PointOutT, PointRFT> ()
/** \brief Empty constructor.
* \param nr_threads the number of hardware threads to use (0 sets the value back to automatic)
* \param chunk_size PCL will use dynamic scheduling with this chunk size. Setting it too low will lead to more parallelization overhead. Setting it too high will lead to a worse balancing between the threads.
*/
SHOTEstimationOMP (unsigned int nr_threads = 0, int chunk_size = 256)
: SHOTEstimation<PointInT, PointNT, PointOutT, PointRFT> (), chunk_size_(chunk_size)
{
setNumberOfThreads(nr_threads);
};
Expand All @@ -122,6 +126,9 @@ namespace pcl

/** \brief The number of threads the scheduler should use. */
unsigned int threads_;

/** \brief Chunk size for (dynamic) scheduling. */
int chunk_size_;
};

/** \brief SHOTColorEstimationOMP estimates the Signature of Histograms of OrienTations (SHOT) descriptor for a given point cloud dataset
Expand Down Expand Up @@ -176,11 +183,16 @@ namespace pcl
using PointCloudOut = typename Feature<PointInT, PointOutT>::PointCloudOut;
using PointCloudIn = typename Feature<PointInT, PointOutT>::PointCloudIn;

/** \brief Empty constructor. */
/** \brief Empty constructor.
* \param nr_threads the number of hardware threads to use (0 sets the value back to automatic)
* \param chunk_size PCL will use dynamic scheduling with this chunk size. Setting it too low will lead to more parallelization overhead. Setting it too high will lead to a worse balancing between the threads.
*/
SHOTColorEstimationOMP (bool describe_shape = true,
bool describe_color = true,
unsigned int nr_threads = 0)
: SHOTColorEstimation<PointInT, PointNT, PointOutT, PointRFT> (describe_shape, describe_color)
unsigned int nr_threads = 0,
int chunk_size = 64)
: SHOTColorEstimation<PointInT, PointNT, PointOutT, PointRFT> (describe_shape, describe_color),
chunk_size_(chunk_size)
{
setNumberOfThreads(nr_threads);
}
Expand All @@ -207,6 +219,9 @@ namespace pcl

/** \brief The number of threads the scheduler should use. */
unsigned int threads_;

/** \brief Chunk size for (dynamic) scheduling. */
int chunk_size_;
};

}
Expand Down