StatisticalRemoval统计滤波实现

该博客介绍了如何使用PCL库实现一种统计学滤波方法,用于去除点云数据中的离群点。算法通过计算每个点到其最近k个邻近点的平均距离,然后根据高斯分布确定距离阈值,将点分类为内点或离群点。代码示例展示了计算均值、标准差以及执行滤波的过程。

原理:
对每一点的邻域进行统计分析,基于点到所有邻近点的距离分布特征,过滤掉一些不满足要求的离群点。该算法对整个输入进行两次迭代:在第一次迭代中,它将计算每个点到最近k个近邻点的平均距离,得到的结果符合高斯分布。接下来,计算所有这些距离的平均值 μ 和标准差 σ 以确定距离阈值 thresh_d ,且 thresh_d = μ + k·σ。 k为标准差乘数。在下一次迭代中,如果这些点的平均邻域距离分别低于或高于该阈值,则这些点将被分类为内点或离群点。

实现:

/**
 * @description:	计算向量元素的均值
 * @param v			输入向量
 * @return			向量元素的均值
 */
float distavg(std::vector<float>& v)
{
	float sum = 0.0;
	for (int i = 0; i < v.size(); ++i)
	{
		sum += sqrt(v[i]);
	}
	return sum / v.size();
}

/**
 * @description:	计算向量元素的标准差
 * @param v			输入向量
 * @param avg		向量元素的均值
 * @return			向量元素的标准差
 */
float calcsigma(std::vector<float>& v, float& avg)
{
	float sigma = 0.0;
	for (int i = 0; i < v.size(); ++i)
	{
		sigma += pow(v[i] - avg, 2);
	}
	return sqrt(sigma / v.size());
}

/**
 * @description:			统计学滤波
 * @param cloud				输入点云
 * @param cloud_filtered	滤波点云
 * @param nr_k				k邻近点数
 * @param std_mul			标准差乘数
 * @param negative			设置移除或者保留
 */
void statisticalremoval(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_filtered, 
	int nr_k, double std_mul, bool negative = false)
{
	pcl::KdTreeFLANN<pcl::PointXYZ> tree;
	tree.setInputCloud(cloud);
    std::vector<float> avg;
	for (int i = 0; i < cloud->points.size(); ++i)
	{
		std::vector<int> id(nr_k);
		std::vector<float> dist(nr_k);
		tree.nearestKSearch(cloud->points[i], nr_k, id, dist);
		avg.push_back(distavg(dist));
	}

	float u = accumulate(avg.begin(), avg.end(), 0.0) / avg.size(); 
	float sigma = calcsigma(avg, u);
    std::vector<int> index;
	for (int i = 0; i < cloud->points.size(); ++i)
	{
        std::vector<int> id(nr_k);
        std::vector<float> dist(nr_k);
		tree.nearestKSearch(cloud->points[i], nr_k, id, dist);
		float temp_avg = distavg(dist);
		if (temp_avg >= u - std_mul*sigma && temp_avg <= u + std_mul*sigma)
		{
			index.push_back(i);
		}
	}

	boost::shared_ptr<std::vector<int>> index_ptr = boost::make_shared<std::vector<int>>(index);
	pcl::ExtractIndices<pcl::PointXYZ> extract;
	extract.setInputCloud(cloud);
	extract.setIndices(index_ptr);
	extract.setNegative(negative);
	extract.filter(*cloud_filtered);
}

代码传送门:https://github.com/taifyang/PCL-algorithm

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

给算法爸爸上香

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值