3 #include <boost/core/checked_delete.hpp>
4 #include <boost/smart_ptr/shared_ptr.hpp>
5 #include <pcl/common/centroid.h>
6 #include <pcl/common/impl/centroid.hpp>
7 #include <pcl/common/io.h>
8 #include <pcl/kdtree/kdtree_flann.h>
15 pcl::PointCloud<pcl::PointXYZI>::Ptr
smoothenCloud(pcl::PointCloud<pcl::PointXYZI>::Ptr cloud,
double r,
bool useMedian)
17 pcl::PointCloud<pcl::PointXYZI>::Ptr result_cloud(
new pcl::PointCloud<pcl::PointXYZI>());
19 pcl::copyPointCloud(*cloud, *result_cloud);
22 pcl::KdTreeFLANN<pcl::PointXYZI> kdtree;
24 kdtree.setInputCloud(cloud);
26 for (
size_t i = 0; i < cloud->size(); ++i) {
27 pcl::PointXYZI newPoint;
29 pcl::CentroidPoint<pcl::PointXYZI> centroid;
30 pcl::PointXYZI centroidPoint;
31 std::vector<int> pointIdxNKNSearch;
32 std::vector<float> pointNKNSquaredDistance;
33 int found = kdtree.radiusSearch(*cloud, (
int)i, r, pointIdxNKNSearch, pointNKNSquaredDistance);
35 for (
int j = 0; j < found; ++j) {
36 centroid.add((*cloud)[pointIdxNKNSearch[j]]);
39 centroid.get(centroidPoint);
42 std::vector<float> xList;
43 std::vector<float> yList;
44 std::vector<float> zList;
46 for (
int j = 0; j < found; ++j) {
47 pcl::PointXYZI
const &point = (*cloud)[pointIdxNKNSearch[j]];
49 xList.push_back(point.x);
50 yList.push_back(point.y);
51 zList.push_back(point.z);
54 auto xMedianIt = xList.begin() + (xList.size() / 2);
55 std::nth_element(xList.begin(), xMedianIt, xList.end());
56 newPoint.x = *xMedianIt;
58 auto yMedianIt = yList.begin() + (yList.size() / 2);
59 std::nth_element(yList.begin(), yMedianIt, yList.end());
60 newPoint.y = *yMedianIt;
62 auto zMedianIt = zList.begin() + (zList.size() / 2);
63 std::nth_element(zList.begin(), zMedianIt, zList.end());
64 newPoint.z = *zMedianIt;
66 newPoint = centroidPoint;
68 result_cloud->push_back(newPoint);