赞
踩
void passthrough(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_PassThrough,float rangelow, float rangehigh, string dimension) {
//方法1:直通滤波器对点云处理
//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_PassThrough(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PassThrough<pcl::PointXYZ> passthrough;
passthrough.setInputCloud(cloud);//输入点云
passthrough.setFilterFieldName(dimension);//对z轴进行操作
passthrough.setFilterLimits(rangelow, rangehigh);//设置直通滤波器操作范围
//passthrough.setFilterLimitsNegative(true);//true表示保留范围内,false表示保留范围外
passthrough.filter(*cloud_after_PassThrough);//执行滤波,过滤结果保存在 cloud_after_PassThrough
}
void voxelgrid(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_voxelgrid, float length, float width, float heigth) {
//方法2:体素滤波器实现下采样
pcl::VoxelGrid<pcl::PointXYZ> voxelgrid;
voxelgrid.setInputCloud(cloud);//输入点云数据
voxelgrid.setLeafSize(length, width, heigth);//AABB长宽高
voxelgrid.filter(*cloud_after_voxelgrid);
}
void Statistical(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_StatisticalRemoval, float averagepoint, float droppoint) {
//方法3:统计滤波器滤波
// 创建滤波器,对每个点分析的临近点的个数设置为50 ,并将标准差的倍数设置为1 这意味着如果一
//个点的距离超出了平均距离一个标准差以上,则该点被标记为离群点,并将它移除,存储起来
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> Statistical; //创建滤波器对象
Statistical.setInputCloud(cloud); //设置待滤波的点云
Statistical.setMeanK(averagepoint); //设置在进行统计时考虑查询点临近点数
Statistical.setStddevMulThresh(droppoint); //设置判断是否为离群点的阀值
Statistical.filter(*cloud_after_StatisticalRemoval); //存储
}
void range_condition(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_Condition, float rangelow, float rangehigh, string dimension){ //方法4:条件滤波器 (其实和直通滤波器差不多) pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_condition(new pcl::ConditionAnd<pcl::PointXYZ>()); range_condition->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new pcl::FieldComparison<pcl::PointXYZ>(dimension, pcl::ComparisonOps::GT, rangelow))); GT表示大于 、EQ表示等于、LT表示小于、GE表示大于或等于、LE表示小于或等于 range_condition->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new pcl::FieldComparison<pcl::PointXYZ>(dimension, pcl::ComparisonOps::LT, rangehigh))); //LT表示小于等于 //创建滤波器并用条件定义对象初始化 pcl::ConditionalRemoval<pcl::PointXYZ> condition; condition.setCondition(range_condition); condition.setInputCloud(cloud); //输入点云 condition.setKeepOrganized(false); //设置是否保留滤波后删除的点,以保持点云的有序性,通过setuserFilterValue设置的值填充点云, //或从点云中删除滤波后的点,从而改变其组织结构. 如果设置为true且不设置setUserFilterValue的值,则用nan填充点云 condition.filter(*cloud_after_Condition); }
void radiusoutlier(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_Radius, float radius, int point) {
//方法5:半径滤波器 (类似统计滤波器但效果不如统计)
//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_Radius(new pcl::PointCloud<pcl::PointXYZ>);
pcl::RadiusOutlierRemoval<pcl::PointXYZ> radiusoutlier; //创建滤波器
radiusoutlier.setInputCloud(cloud); //设置输入点云
radiusoutlier.setRadiusSearch(radius); //设置半径为100的范围内找临近点
radiusoutlier.setMinNeighborsInRadius(point); //设置查询点的邻域点集数小于2的删除
radiusoutlier.filter(*cloud_after_Radius);
}
//该类的实现利用的并非XYZ字段的数据进行,而是利用强度数据进行双边滤波算法的实现 void bilateralFilter(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_bilateralFilter,float sigma_s, float sigma_r){ //方法6:双边滤波法(该滤波方法一般适用于有序点云,在此demo中不适用) // Apply the filter //(1)如果点云是有序的,通过 pcl: : Organ izedDatalnd ex 使用有序搜索方法 。 //(2 ) 如果点云是无序的,通过 pcl : : KdTreeFLANN 使用通用的 Kd 树 //有序点云 //Example: // cloud.width = 640; // Image-like organized structure, with 640 rows and 480 columns, // cloud.height = 480; // thus 640*480=307200 points total in the dataset //无序点云 //Example: // cloud.width = 307200; // cloud.height = 1; // unorganized point cloud dataset with 307200 points pcl::FastBilateralFilter<pcl::PointXYZ> fastbilateralfilter; fastbilateralfilter.setInputCloud(cloud); fastbilateralfilter.setSigmaS(sigma_s); fastbilateralfilter.setSigmaR(sigma_r); fastbilateralfilter.filter(*cloud_after_bilateralFilter);//存储滤波后的数据格式 }
void Gaussianfilter(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_GaussianFilter, float radius) { //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); cout << "Kernel made" << endl; //Set up the KDTree pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>); (*kdtree).setInputCloud(cloud); cout << "KdTree made" << 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(cloud); convolution.setSearchMethod(kdtree); convolution.setRadiusSearch(radius); convolution.setNumberOfThreads(10);//important! Set Thread number for openMP cout << "Convolution Start" << endl; convolution.convolve(*cloud_after_GaussianFilter); cout << "Convoluted" << endl; }
关于以上几种点云滤波方法的原理和适用情况将在之后的博客中说明
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。