-
Notifications
You must be signed in to change notification settings - Fork 5
/
statisticalremoval.cpp
95 lines (86 loc) · 2.62 KB
/
statisticalremoval.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/search/kdtree.h>
#include <pcl/filters/extract_indices.h>
/**
* @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);
}
int main(int argc, char* argv[])
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("rabbit.pcd", *cloud);
statisticalremoval(cloud, cloud_filtered, 50, 1.0);
pcl::io::savePCDFile("mystatisticalremoval.pcd", *cloud_filtered);
system("pause");
return EXIT_SUCCESS;
}