赞
踩
最近投稿点云数据处理的文章,经常被审稿人Diss不加点云去噪的相关介绍。点云去噪本身就是一个非常独立且复杂的研究领域,要想增加这部分内容的介绍,还是要下一点功夫的。这里,就跟大家分享一个基于PCL库的比较成熟的点云去噪方法实现,即高斯滤波。
去噪结果:
点云数据去噪前(左),去噪后,sigma = 6(右)。
Mesh数据去噪前(左),去噪后(右)。
适用于呈正态分布的数据。考虑到离群点的特征,则可以定义某处点云小于某个密度,既点云无效。计算每个点到其最近的k个点平均距离。则点云中所有点的距离应构成高斯分布。给定均值与方差,可剔除3∑之外的点。
高斯函数的具体介绍转自:https://blog.csdn.net/jorg_zhao/article/details/52687448
这里有几个对高斯核函数进行参数设置的方法,单独列出来以方便学习:
设置高斯函数的方差。随着sigma的增大,整个高斯函数的尖峰逐渐减小,整体也变的更加平缓,则对图像的平滑效果越来越明显。
设置高斯函数的作用域半径threshold,超过则不计入计算。
依据核函数方差获得关联作用域,sigma_coefficient^2 * sigma^2 = threshold。
实例代码如下:
- //radius代表点云扫面的半径,这里需要用户计算获得
-
- #include <iostream>
- #include <pcl/io/pcd_io.h>
- #include <pcl/point_types.h>
- #include <pcl/point_cloud.h>
- #include <boost/random.hpp>
- #include <pcl/console/time.h>
- #include <pcl/filters/convolution_3d.h>
- #include <pcl/kdtree/kdtree_flann.h>
- using namespace std;
-
- vector<vector<double>> DenoisingPD_GaussianKernel(vector<vector<double>> pointCloudOriginal,double radius) {
-
- cout << "Gaussian denoising start:" << endl;
- pcl::PointCloud<pcl::PointXYZ>::Ptr inputcloud(new pcl::PointCloud<pcl::PointXYZ>);
- pcl::PointCloud<pcl::PointXYZ>::Ptr outputcloud(new pcl::PointCloud<pcl::PointXYZ>);
-
- //Read point cloud in the input file
- for (int i = 0; i < pointCloudOriginal.size(); i++)
- {
- pcl::PointXYZ cloud_i;
- cloud_i.x = pointCloudOriginal[i][0];
- cloud_i.y = pointCloudOriginal[i][1];
- cloud_i.z = pointCloudOriginal[i][2];
- inputcloud->push_back(cloud_i);
- }
-
- //Set up the Gaussian Kernel
- pcl::filters::GaussianKernel<pcl::PointXYZ, pcl::PointXYZ>::Ptr kernel(new pcl::filters::GaussianKernel<pcl::PointXYZ, pcl::PointXYZ>);
- (*kernel).setSigma(4);
- (*kernel).setThresholdRelativeToSigma(4);
- std::cout << "Kernel made" << std::endl;
-
- //Set up the KDTree
- pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
- (*kdtree).setInputCloud(inputcloud);
- std::cout << "KdTree made" << std::endl;
-
-
- //Set up the Convolution Filter
- pcl::filters::Convolution3D <pcl::PointXYZ, pcl::PointXYZ, pcl::filters::GaussianKernel<pcl::PointXYZ, pcl::PointXYZ> > convolution;
- convolution.setKernel(*kernel);
- convolution.setInputCloud(inputcloud);
- convolution.setSearchMethod(kdtree);
- convolution.setRadiusSearch(radius);
- convolution.setNumberOfThreads(10);//important! Set Thread number for openMP
- std::cout << "Convolution Start" << std::endl;
- convolution.convolve(*outputcloud);
- std::cout << "Convoluted" << std::endl;
-
- vector<vector<double>> pCDenosing(pointCloudOriginal.size());
-
- for (int i = 0; i < outputcloud->size(); i++) {
- vector<double> pi(3);
- pi[0] = outputcloud->at(i).x;
- pi[1] = outputcloud->at(i).y;
- pi[2] = outputcloud->at(i).z;
- pCDenosing[i] = pi;
- }
- cout << "Gaussian denoising finished!" << endl;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。