点云添加高斯噪声的C++实现
Posted 借我十斤肉
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了点云添加高斯噪声的C++实现相关的知识,希望对你有一定的参考价值。
0 添加高斯噪声后的点云
红色为添加的高斯噪声点,白色为原始点
1 什么是高斯噪声
高斯噪声是指它的概率密度函数服从高斯分布(即正态分布)的一类噪声。(百度百科)
高斯分布,也称正态分布,又称常态分布,记为
N
(
μ
,
σ
2
)
N(μ,σ^2)
N(μ,σ2),其中
μ
,
σ
2
μ,σ^2
μ,σ2 为分布的参数,分别为高斯分布的期望和方差,其中
σ
>
0
\\sigma>0
σ>0,称为标准差。当
μ
,
σ
μ,σ
μ,σ 有确定值时,
p
(
x
)
p(x)
p(x) 也就确定了,特别当
μ
=
0
,
σ
2
=
1
μ=0,σ^2=1
μ=0,σ2=1 时,
x
x
x 的分布为标准正态分布。
p
(
x
)
=
1
σ
2
π
e
−
(
x
−
μ
)
2
2
σ
2
p(x)=\\cfrac{1}{\\sigma\\sqrt{2\\pi}}e^{-\\cfrac{(x-\\mu)^2}{2\\sigma^2}}
p(x)=σ2π1e−2σ2(x−μ)2
2 怎样添加高斯噪声
磨刀不误砍柴工,将添加高斯噪声封装到 CreatGaussNoise类 中,只需在main.cpp
中设置输入点云(要添加噪声的点云)、设置高斯噪声参数(
μ
,
σ
\\mu,\\sigma
μ,σ)即可。
实现代码
main.cpp
#include "add_gauss_noise.h"
int main()
{
//-------------------加载点云-------------------
pcl::PointCloud<pcl::PointXYZ> cloud_in;
if (pcl::io::loadPCDFile("Armadillo.pcd", cloud_in) < 0)
{
PCL_ERROR("->点云文件不存在!\\a\\n");
system("pause");
return -1;
}
//-------------------添加高斯噪声-------------------
AddGaussNoise agn; //创建高斯噪声对象agn
pcl::PointCloud<pcl::PointXYZ> cloud_out; //保存结果的点云
agn.setInputCloud(cloud_in); //设置输入点云
agn.setParameters(0,2); //设置高斯噪声参数mu,sigma
agn.addGaussNoise(cloud_out); //执行添加高斯噪声,并将结果保存在cloud_out中
//-------------------保存添加高斯噪声后的点云-------------------
pcl::io::savePCDFileBinary("addGaussNoise.pcd", cloud_out);
return 0;
}
add_gauss_noise.h
#pragma once
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <boost/random.hpp> //随机数所需头文件
class AddGaussNoise
{
public:
/**
* @brief : 设置输入点云
* @param[I]: cloud_in (输入点云)
* @param[O]: none
* @return : none
* @note :
**/
void setInputCloud(pcl::PointCloud<pcl::PointXYZ> &cloud_in);
/**
* @brief : 设置高斯噪声参数
* @param[I]: mu (均值,默认0)
* @param[I]: sigma (标准差,默认1)
* @param[O]: none
* @return : none
* @note :
**/
void setParameters(double mu = 0.0, double sigma = 1.0);
/**
* @brief : 执行添加高斯噪声
* @param[I]: cloud_out (添加高斯噪声后的点云)
* @param[O]: none
* @return : none
* @note :
**/
void addGaussNoise(pcl::PointCloud<pcl::PointXYZ> &cloud_out);
private:
pcl::PointCloud<pcl::PointXYZ> m_cloud_in; //输入点云
bool is_setInputCloud = false; //是否设置输入点云
double m_mu, m_sigma; //高斯分布参数
bool is_setParameters = false; //是否设置高斯分布参数
};
add_gauss_noise.cpp
#include "add_gauss_noise.h"
/**
* @brief : 设置输入点云
* @param[I]: cloud_in (输入点云)
* @param[O]: none
* @return : none
* @note :
**/
void AddGaussNoise::setInputCloud(pcl::PointCloud<pcl::PointXYZ> &cloud_in)
{
m_cloud_in = cloud_in;
is_setInputCloud = true;
}
/**
* @brief : 设置高斯噪声参数
* @param[I]: mu (均值,默认0)
* @param[I]: sigma (标准差,默认1)
* @param[O]: none
* @return : none
* @note :
**/
void AddGaussNoise::setParameters(double mu, double sigma)
{
if (sigma > 0)
{
m_mu = mu;
m_sigma = sigma;
is_setParameters = true;
}
else
{
PCL_ERROR("->sigma应大于0!\\a\\n");
system("pause");
abort();
}
}
/**
* @brief : 执行添加高斯噪声
* @param[I]: cloud_out (添加高斯噪声后的点云)
* @param[O]: none
* @return : none
* @note :
**/
void AddGaussNoise::addGaussNoise(pcl::PointCloud<pcl::PointXYZ> &cloud_out)
{
boost::mt19937 zgy; //等分布均匀伪随机数发生器
zgy.seed(static_cast<unsigned int>(time(0))); //随机种子
boost::normal_distribution<> nd(m_mu, m_sigma); //定义正态分布,均值为mu,标准差为sigma
boost::variate_generator<boost::mt19937&, boost::normal_distribution<>> gauss_noise(zgy, nd); //生成高斯噪声
pcl::PointCloud<pcl::PointXYZ> cloud_gauss; //声明高斯噪声点云
cloud_gauss = m_cloud_in; //将原始点云拷贝给高斯噪声点云,用于下面的平移
for (size_t i = 0; i < cloud_gauss.size(); i++)
{
cloud_gauss.points[i].x += static_cast<float> (gauss_noise());
cloud_gauss.points[i].y += static_cast<float> (gauss_noise());
cloud_gauss.points[i].z += static_cast<float> (gauss_noise());
}
cloud_out = m_cloud_in + cloud_gauss; //将原始点云与噪声点云合并,得到添加高斯噪声后的点云
}
参考链接
以上是关于点云添加高斯噪声的C++实现的主要内容,如果未能解决你的问题,请参考以下文章
Opencv——图像添加椒盐噪声高斯滤波去除噪声原理及手写Python代码实现