空集是任何集合的真子集
2.1-PCL点云滤波Filtering
点云滤波概述
在获取点云数据时,由于设备精度、操作者经验、环境因素等带来的影响,以及电磁波衍射特性、被测物体表⾯性质变化和数据拼接配准操作过程的影响,点云数据中将不可避免地出现⼀些噪声点。实际应⽤中除了这些测量随机误差产⽣的噪声点之外,由于受到外界⼲扰如视线遮挡、障碍物等因素的影响,点云数据中往往存在着⼀些离主体点云较远的离散点,即离群点。不同的获取设备点云噪声结构也有不同。
通过滤波完成的功能还包括孔洞修复、最⼩信息损失的海量点云数据压缩处理等 。在点云处理流程中滤波处理作为预处理的第⼀步,往往对后续处理流程影响很⼤,只有在滤波预处理中将噪声点、离群点、孔洞、数据压缩等 按照后续需求处理,才能够更好地进⾏配准、特征提取、曲⾯重建、可视化等后续流程。
PCL 中点云滤波模块提供了很多灵活实⽤的滤波处理算法,例如双边滤波、⾼斯滤波、条件滤波、直通滤波、基于随机采样⼀致性滤波RANSAC等。滤波模块是作为 PCL的⼀个重要处理模块,其在应⽤中可以⾮常⽅便与其他点云处理流程协同使⽤。
(1)应⽤场景
点云数据密度不规则需要平滑处理
去除因为遮挡等问题造成离群点
数据量较⼤,需要进⾏下采样( Downsample)
去除噪声数据。
(2)⽰例
下图显⽰了⼀个噪声消除的⽰例。 由于测量误差,某些数据集会出现⼤量阴影点。 这使局部点云3D特征的估算变得复杂。我们通过对每个点的邻域进⾏统计分析,并修剪掉不符合特定条件的那些异常值,进⽽可以过滤掉某些异常值。
PCL中的实现这些稀疏离群值的消除,需要计算数据集中的点与邻居距离的分布。 即对于每个点,都会计算从它到所有相邻点的平均距离。 通过假设结果分布是具有均值和标准差的⾼斯分布,可以将那些平均距离在【由全局距离均值和标准差定义的区间】之外的所有点视为离群值,并将之从数据集中进⾏修剪。
直通滤波PassThrough
(1)代码实现
PassThrough.cpp
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/cloud_viewer.h>
typedef pcl::PointXYZ PointT;
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>);
testreport// Fill in the cloud data
cloud->width = 5;
cloud->height = 1;
cloud-&size(cloud->width * cloud->height);
for (size_t i = 0; i < cloud->points.size(); ++i) {
cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}
std::cerr << "Cloud before filtering: " << std::endl;
for (size_t i = 0; i < cloud->points.size(); ++i)
std::cerr << " " << cloud->points[i].x << " "
<< cloud->points[i].y << " "
<< cloud->points[i].z << std::endl;
// Create the filtering object
pcl::PassThrough<pcl::PointXYZ> pass;
pass.tInputCloud(cloud); // 1. 设置输⼊源
pass.tFilterFieldName("z"); // 2. 设置过滤域名
pass.tFilterLimits(0.0, 1.0); // 3. 设置过滤范围
// pass.tFilterLimitsNegative(true); // 设置获取Limits之外的内容
pass.filter(*cloud_filtered); // 4. 执⾏过滤,并将结果输出到cloud_filtered
std::cerr << "Cloud after filtering: " << std::endl;
for (size_t i = 0; i < cloud_filtered->points.size(); ++i)
std::cerr << " " << cloud_filtered->points[i].x << " "
<< cloud_filtered->points[i].y << " "
<< cloud_filtered->points[i].z << std::endl;
pcl::visualization::CloudViewer viewer("Cloud Viewer");
//这⾥会⼀直阻塞直到点云被渲染
viewer.showCloud(cloud);
while (!viewer.wasStopped()) {
}
return (0);
}
(2)输出结果
Cloud before filtering:
0.352222 -0.151883 -0.106395
-0.397406 -0.473106 0.292602
-0.731898 0.667105 0.441304四级查成绩时间
-0.734766 0.854581 -0.0361733
-0.4607 -0.277468 -0.916762
Cloud after filtering:edg啥意思
-0.397406 -0.473106 0.292602
-0.731898 0.667105 0.441304
可见以下Z轴正⽅向的两个绿⾊的点被保留,Z轴负⽅向的红⾊点被过滤掉。
【取反】
如果使⽤了pass.tFilterLimitsNegative (true);,则以上结果取反。
降采样&VoxelGrid
通过体素⽹格实现降采样,可以减少点数量的同时,保证点云的形状特征,可以提⾼配准、曲⾯重建、形状识别等算法的速度,并保证准确性。
肚皮舞服装(1)代码实现
downsample_voxel_grid.cpp
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
int
main (int argc, char** argv)
中秋节英语翻译{
pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ());
pcl::PCLPointCloud2::Ptr cloud_filtered (new pcl::PCLPointCloud2 ());
// 从⽂件读取点云图
// Fill in the cloud data
pcl::PCDReader reader;
// Replace the path below with the path where you saved your filerefu的用法
std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height
<< " data points (" << pcl::getFieldsList (*cloud) << ").";
// 创建⼀个长宽⾼分别是1cm的体素过滤器,cloud作为输⼊数据,cloud_filtered作为输出数据 float leftSize = 0.01f;
// Create the filtering object
pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
sor.tInputCloud (cloud);bathroom是什么意思
sor.tLeafSize (leftSize, leftSize, leftSize);
sor.filter (*cloud_filtered);
std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height
<< " data points (" << pcl::getFieldsList (*cloud_filtered) << ").";
// 将结果输出到⽂件
pcl::PCDWriter writer;
writer.write ("./data/table_scene_lms400_downsampled.pcd", *cloud_filtered);
return (0);
}
genital是什么意思啊
(2)输出结果
PointCloud before filtering: 460400 data points (x y z intensity distance sid).
PointCloud after filtering: 41049 data points (x y z intensity distance sid).
原pcd⽂件
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z intensity distance sid
SIZE 4 4 4 4 4 4
TYPE F F F F F F
COUNT 1 1 1 1 1 1
WIDTH 460400
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 460400
DATA binary_compresd
...
降采样后pcd⽂件
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z intensity distance sid
SIZE 4 4 4 4 4 4
TYPE F F F F F F
COUNT 1 1 1 1 1 1
WIDTH 41049
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 41049
DATA ascii
...
可以看到POINTS个数从原来的460400个减少为41049个
(3)实现效果
双屏对⽐
pcl_viewer -multiview 1 ./data/table_scene_mug_stereo_textured.pcd ./data/table_scene_mug_stereo_textured_downsampled.pcd
可鄙离群点移除
激光扫描通常会⽣成不同点密度的点云数据集。此外,测量误差会导致稀疏的异常值,从⽽进⼀步破坏结果。这会使局部点云特征(例如表⾯法线或曲率变化)的估计复杂化,从⽽导致错误的值,进⽽可能导致点云配准失败。通过对每个点的邻域进⾏统计分析,并对不符合特定条件的部分进⾏修整,可以解决其中⼀些不规则现象。
稀疏离群值的消除基于输⼊数据集中点到邻居距离的分布的计算。对于每个点,我们计算从它到所有相邻点的平均距离。通过假设结果分布是具有均值和标准差的⾼斯分布,可以将其平均距离在由全局距离均值和标准差定义的区间之外的所有点视为离群值并从数据集中进⾏修剪。 下图显⽰了稀疏离群值分析和删除的效果:原始数据集显⽰在左侧,结果数据集显⽰在右侧。数据集图显⽰了滤波前后每个点的邻域中平均K最近邻距离。
StatisticalOutlierRemoval
接下来,我们使⽤StatisticalOutlierRemoval(统计学离群点移除过滤器)移除噪点。