注意:PCL生成高斯噪声时,只是生成了一个原始点云点的位移量,需要将该位移量添加到原始点云点上,而不是直接生成了一个带有高斯噪声的新点云。
1.原理
对于当前点云,修改当前点云点的位置,符合高斯分布的噪声点云结果。
2.使用场景
生成高斯噪声数据(实际工作中使用较少)
3.注意事项
PCL生成高斯噪声时,只是生成了一个原始点云点的位移量,需要将该位移量添加到原始点云点上,而不是直接生成了一个带有高斯噪声的新点云。
因此下方代码中,分为生成高斯噪声及添加高斯噪声两步,注意区别。
4.关键函数
(1)按照设定的均值和标准差,在xyz方向分别计算高斯噪声参数,最终生成高斯噪声的位移量。
标准差越大,数据的高斯分布越分散,即生成的高斯噪声点云越分散。
// 生成高斯噪声位移量
// 设置xyz方向的均值及标准差
float xmean = 0, ymean = 0, zmean = 0;
float xstddev = 0.02, ystddev = 0.02, zstddev = 0.02;
pcl::common::CloudGenerator<pcl::PointXYZ, pcl::common::NormalGenerator<float> > generator; // 高斯噪声生成器
uint32_t seed = static_cast<uint32_t> (time(NULL)); // 随机数种子
pcl::common::NormalGenerator<float>::Parameters x_params(xmean, xstddev, seed++); // 添加x方向的噪声
generator.setParametersForX(x_params);
pcl::common::NormalGenerator<float>::Parameters y_params(ymean, ystddev, seed++); // 添加y方向的噪声
generator.setParametersForY(y_params);
pcl::common::NormalGenerator<float>::Parameters z_params(zmean, zstddev, seed++); // 添加z方向的噪声
generator.setParametersForZ(z_params);
generator.fill((*cloud).width, (*cloud).height, *cloud_out); // 生成高斯噪声
(2)将高斯噪声的位移量添加到原始点云坐标上,得到最终的符合高斯分布的噪声点云结果。
// 给原始点云添加高斯噪声位移量
for (size_t i = 0; i < cloud->points.size(); ++i)
{
cloud_out->points[i].x += cloud->points[i].x;
cloud_out->points[i].y += cloud->points[i].y;
cloud_out->points[i].z += cloud->points[i].z;
}
5.代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/random.h>
#include <pcl/common/generate.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
int main()
{
/****************添加高斯噪声********************/
// 原始点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("D:/code/csdn/data/person2.pcd", *cloud); // 加载原始点云数据
// 结果点云
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out(new pcl::PointCloud<pcl::PointXYZ>);
// 生成高斯噪声位移量
// 设置xyz方向的均值及标准差
float xmean = 0, ymean = 0, zmean = 0;
float xstddev = 0.02, ystddev = 0.02, zstddev = 0.02;
pcl::common::CloudGenerator<pcl::PointXYZ, pcl::common::NormalGenerator<float> > generator; // 高斯噪声生成器
uint32_t seed = static_cast<uint32_t> (time(NULL)); // 随机数种子
pcl::common::NormalGenerator<float>::Parameters x_params(xmean, xstddev, seed++); // 添加x方向的噪声
generator.setParametersForX(x_params);
pcl::common::NormalGenerator<float>::Parameters y_params(ymean, ystddev, seed++); // 添加y方向的噪声
generator.setParametersForY(y_params);
pcl::common::NormalGenerator<float>::Parameters z_params(zmean, zstddev, seed++); // 添加z方向的噪声
generator.setParametersForZ(z_params);
generator.fill((*cloud).width, (*cloud).height, *cloud_out); // 生成高斯噪声
// 给原始点云添加高斯噪声位移量
for (size_t i = 0; i < cloud->points.size(); ++i)
{
cloud_out->points[i].x += cloud->points[i].x;
cloud_out->points[i].y += cloud->points[i].y;
cloud_out->points[i].z += cloud->points[i].z;
}
pcl::io::savePCDFile("D:/code/csdn/data/person5.pcd", *cloud_out); // 保存带有高斯噪声的点云
/****************展示********************/
boost::shared_ptr<pcl::visualization::PCLVisualizer> view_raw(new pcl::visualization::PCLVisualizer("raw"));
view_raw->addPointCloud<pcl::PointXYZ>(cloud, "raw cloud");
view_raw->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "raw cloud");
boost::shared_ptr<pcl::visualization::PCLVisualizer> view_gauss(new pcl::visualization::PCLVisualizer("filter"));
view_gauss->addPointCloud<pcl::PointXYZ>(cloud_out, "gauss cloud");
view_gauss->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "filtered cloud");
while (!view_raw->wasStopped() || !view_gauss->wasStopped())
{
view_raw->spinOnce(100);
view_gauss->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}