pcl::PointCloud各种添加点云方法的速度对比

pcl::PointCloud官方提供了一个添加点云的函数接口push_back(),但是实际中经常看到有人先调用resize()函数,再逐个进行赋值,理由是这样更快。本文对两种方法的速度进行对比。

首先详细介绍一下输入数据和这两种方法:

1. 输入数据

本文中输出数据是随机生成的,这不影响后续的速度测试,先把这些数据存储在一个pcl::PointCloud中。

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

#include <ctime>
#include <cstdlib>
#include <chrono>

pcl::PointCloud<pcl::PointXYZ> cloud;

// Fill in the cloud data
cloud.width    = 10000000;
cloud.height   = 1;
cloud.is_dense = false;
cloud.points.resize (cloud.width * cloud.height);

for (size_t i = 0; i < cloud.points.size (); ++i)
{
  cloud.points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
  cloud.points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
  cloud.points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
}

2. 先调用resize()再逐个赋值

pcl::PointCloud<pcl::PointXYZ> cloud_1;
cloud_1.width = cloud.width;
cloud_1.height = cloud.height;
cloud_1.is_dense = cloud.is_dense;
cloud_1.points.resize(cloud.width * cloud.height);

for (size_t i = 0; i < cloud.points.size(); ++i)
{
  cloud_1.points[i].x = cloud.points[i].x;
  cloud_1.points[i].y = cloud.points[i].y;
  cloud_1.points[i].z = cloud.points[i].z;
}

3. 调用官方接口push_back()

注意:这里面在调用push_back()之前先调用了reserve(),这样才能大幅减少该方法的时间开销。

pcl::PointCloud<pcl::PointXYZ> cloud_2;
cloud_2.points.reserve(cloud.points.size());

for (size_t i = 0; i < cloud.points.size(); ++i)
{
  cloud_2.push_back(cloud.points[i]);
}

4. 时间开销对比

下面是其中一次测试的结果:

Duration 1: 0.0543553s
Duration 2: 0.0487025s

如果在调用官方接口push_back()之前不再用reserve(),则结果为:

Duration 1: 0.0543018s
Duration 2: 0.132413s

可以看到,其开销明显上升。

4. 结论

多次测试显示,使用官方的push_back接口并不慢,前提是调用reserve()函数。

所以,完全没有必要自己resize()再赋值。

/* 多源异构点云配准数据的滤波及精度分析 */ #include <pcl/io/pcd_io.h>// 点云文件I/O #include <pcl/surface/mls.h>// 移动最小二乘曲面重建 #include <pcl/point_types.h>// 点类型定义 #include <pcl/filters/voxel_grid.h>// 体素网格下采样 #include <pcl/features/normal_3d_omp.h> // 多线程法线估计 #include <pcl/visualization/pcl_visualizer.h> // 可视化模块 #include <pcl/filters/radius_outlier_removal.h> // 半径离群点移除 #include <pcl/filters/statistical_outlier_removal.h>// 统计离群点移除 using namespace std; int main(int argc, char** argv) { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_a(new pcl::PointCloud<pcl::PointXYZ>); string path = "D:\\新建文件夹\\点云数据集\\Point Cloud Library Files PCD datasets\\kitchen\\Rf3.pcd"; if (pcl::io::loadPCDFile<pcl::PointXYZ>(path, *cloud_a) == -1) { PCL_ERROR("Couldn't read file test_pcd.pcd \n"); return (-1); } //*******多源异构********** pcl::PointCloud<pcl::PointXYZ>::Ptr cloud1(new pcl::PointCloud<pcl::PointXYZ>); pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; sor.setInputCloud(cloud_a); sor.setMeanK(15); // 邻域点数量 sor.setStddevMulThresh(1); // 标准差倍数阈值 sor.filter(*cloud1); // 输出到cloud1,邻域15个点,距离均值超过1倍标准差视为离群点 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud11(new pcl::PointCloud<pcl::PointXYZ>); pcl::VoxelGrid<pcl::PointXYZ> grid; grid.setInputCloud(cloud1); Eigen::Vector4f leaf_size{ 0.08,0.08,0.08,0 }; grid.setLeafSize(leaf_size); grid.filter(*cloud11); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud2(new pcl::PointCloud<pcl::PointXYZ>); pcl::RadiusOutlierRemoval<pcl::PointXYZ> ror; ror.setInputCloud(cloud11); ror.setRadiusSearch(0.1); ror.setMinNeighborsInRadius(1); ror.filter(*cloud2); pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>); pcl::PointCloud<pcl::PointNormal>::Ptr mls_points_normal(new pcl::PointCloud<pcl::PointNormal>); pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> mls; mls.setInputCloud(cloud2); mls.setComputeNormals(true); // mls.setPolynomialFit(true); mls.setPolynomialOrder(2); // MLS拟合的阶数 mls.setSearchMethod(tree); mls.setSearchRadius(0.3); // 邻域搜索半径 mls.setNumberOfThreads(4); mls.process(*mls_points_normal); cout << "mls poits size is: " << mls_points_normal->size() << endl; pcl::io::savePCDFileASCII("多源异构.pcd", *mls_points_normal); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud3(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile<pcl::PointXYZ>("多源异构.pcd", *cloud3); // -----------------------------可视化----------------------------------- pcl::visualization::PCLVisualizer viewer("Cloud Viewer"); int v1 = 0; int v2 = 1; viewer.createViewPort(0, 0, 0.5, 1, v1); viewer.createViewPort(0.5, 0, 1, 1, v2); viewer.addPointCloud(cloud_a, "original cloud", v1); viewer.addPointCloud(cloud3, "cloud", v2); viewer.setBackgroundColor(255, 255, 255); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "original cloud"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "original cloud"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "cloud"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "cloud"); viewer.spin(); return 0; }详细解释一下这段代码,如有问题,请给出改进意见。
03-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值