
[done, 599.439 ms : 307200 points]
Available dimensions: x y z rgb原始点云
PointCloud after filtering has: 139656 data points.
PointCloud after segmentation has: 123727 inliers.
PointCloud after projection has: 139656 data points.
Concave hull has: 457 data points.
[done, 438.018 ms : 457 points]
Available dimensions: x y z投影后点云凸包
该段代码是一个使用PCL(Point Cloud Library,点云库)进行点云处理的完整程序。程序的主要过程如下:
首先,初始化三个
pcl::PointCloud<pcl::PointXYZ>智能指针,cloud用于存储原始点云数据,cloud_filtered用于存储过滤后的点云数据,cloud_projected用于存储投影后的点云数据。使用
pcl::PCDReader对象读取名为"table_scene_mug_stereo_textured.pcd"的PCD文件到cloud中。使用
pcl::PassThrough<pcl::PointXYZ>过滤器来移除点云中的NaN值,同时根据z字段的范围(0到1.1)来裁剪点云,以移除场景背景,结果存入cloud_filtered。初始化
pcl::ModelCoefficients和pcl::PointIndices,以存储模型系数和分割得到的内点索引。创建
pcl::SACSegmentation<pcl::PointXYZ>对象进行分割操作,设置模型类型为平面(pcl::SACMODEL_PLANE),方法类型为RANSAC(pcl::SAC_RANSAC),并设定距离阈值为0.01。将cloud_filtered作为输入进行分割,并将内点索引存入inliers。使用
pcl::ProjectInliers<pcl::PointXYZ>对象将分割出的平面内点投影到一个模型平面上,得到的投影点云存储在cloud_projected。创建一个凹包(
Concave Hull)的表示形式,使用pcl::ConcaveHull<pcl::PointXYZ>对象对投影的点云cloud_projected进行处理,设置凹包的alpha值为0.1,并将重构后的凹包点云存储在cloud_hull。最后,使用
pcl::PCDWriter对象将凹包点云写入名为"table_scene_mug_stereo_textured_hull.pcd"的文件中。程序返回0,正常结束。
总而言之,这段代码是利用PCL对3D点云数据进行预处理的工作流程,这包括对点云进行过滤、分割、投影以及凹包构建等处理步骤,最终生成了目标物体凹包表示的点云数据,这种数据可用于后续的物体识别或其他点云处理任务。
// 包含PCL库中关于模型系数的头文件
#include <pcl/ModelCoefficients.h>
// 包含PCL库中PCD文件输入输出的头文件
#include <pcl/io/pcd_io.h>
// 包含PCL库中点类型定义的头文件
#include <pcl/point_types.h>
// 包含PCL库中随机抽样一致性算法所需方法类型的头文件
#include <pcl/sample_consensus/method_types.h>
// 包含PCL库中随机抽样一致性算法所需模型类型的头文件
#include <pcl/sample_consensus/model_types.h>
// 包含PCL库中直通滤波器的头文件
#include <pcl/filters/passthrough.h>
// 包含PCL库中点云投影的头文件
#include <pcl/filters/project_inliers.h>
// 包含PCL库中平面分割的头文件
#include <pcl/segmentation/sac_segmentation.h>
// 包含PCL库中凹面包络的头文件
#include <pcl/surface/concave_hull.h>
// 主函数入口
int
main ()
{
// 创建几个PointCloud<pcl::PointXYZ>智能指针,用于后续存储数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>),
cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>),
cloud_projected (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDReader reader;
// 从PCD文件中读取点云数据
reader.read ("table_scene_mug_stereo_textured.pcd", *cloud);
// 创建直通过滤器,移除NaN数据点和背景的数据点
pcl::PassThrough<pcl::PointXYZ> pass;
// 设置输入点云
pass.setInputCloud (cloud);
// 设置过滤时所用的字段名称
pass.setFilterFieldName ("z");
// 设置过滤的z轴数值范围为0到1.1
pass.setFilterLimits (0, 1.1);
// 进行过滤,并保存结果到cloud_filtered
pass.filter (*cloud_filtered);
// 输出过滤之后点云的数量
std::cerr << "PointCloud after filtering has: "
<< cloud_filtered->size () << " data points." << std::endl;
// 定义一个模型系数对象和点索引对象的智能指针
pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
// 创建平面分割对象
pcl::SACSegmentation<pcl::PointXYZ> seg;
// 可选设置,设置优化系数
seg.setOptimizeCoefficients (true);
// 必选设置,选择分割模型的类型,这里选择平面模型
seg.setModelType (pcl::SACMODEL_PLANE);
// 必选设置,选择采用的RANSAC方法类型
seg.setMethodType (pcl::SAC_RANSAC);
// 设置RANSAC的距离阈值
seg.setDistanceThreshold (0.01);
// 设置输入点云为过滤后的点云
seg.setInputCloud (cloud_filtered);
// 执行分割操作,并将分割结果的内点和模型系数输出
seg.segment (*inliers, *coefficients);
// 输出分割后的内点数量
std::cerr << "PointCloud after segmentation has: "
<< inliers->indices.size () << " inliers." << std::endl;
// 创建点云投影对象
pcl::ProjectInliers<pcl::PointXYZ> proj;
// 设置投影模型的类型
proj.setModelType (pcl::SACMODEL_PLANE);
// 设置输入的点云为过滤后的点云
proj.setInputCloud (cloud_filtered);
// 设置模型系数
proj.setModelCoefficients (coefficients);
// 执行投影滤波,并将结果输出到cloud_projected
proj.filter (*cloud_projected);
// 输出投影后的点云数量
std::cerr << "PointCloud after projection has: "
<< cloud_projected->size () << " data points." << std::endl;
// 创建凹面包络(Concave Hull)对象
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull (new pcl::PointCloud<pcl::PointXYZ>);
pcl::ConcaveHull<pcl::PointXYZ> chull;
// 设置输入的点云为投影后的点云
chull.setInputCloud (cloud_projected);
// 设置凹面包络的alpha值,控制输出凹包络的形状
chull.setAlpha (0.1);
// 构建凹面包络,输出结果到cloud_hull
chull.reconstruct (*cloud_hull);
// 输出凹面包络的点数量
std::cerr << "Concave hull has: " << cloud_hull->size ()
<< " data points." << std::endl;
// 创建PCD文件写入对象
pcl::PCDWriter writer;
// 将凹面包络的点云数据写入到文件中
writer.write ("table_scene_mug_stereo_textured_hull.pcd", *cloud_hull, false);
// 程序正常执行结束
return (0);
}代码的主要功能:
从PCD文件中读取点云数据。
使用直通过滤器(PassThrough)移除NaNs值和不在指定范围内的点。
使用SACSegmentation进行基于RANSAC的平面分割,输出平面模型的内点(inliers)和模型系数(coefficients)。
使用ProjectInliers将内点投影到平面模型上。
使用ConcaveHull构造投影点云的凹包络,输出凹面形状。
最终将凹面包络的点云数据写入到新的PCD文件中。
pcl::PassThrough<pcl::PointXYZ>
pcl::ModelCoefficients::Ptr
pcl::SACSegmentation<pcl::PointXYZ>
样本一致性算法,如 RANSAC、LMedS、MSAC 和 MLESAC样本一致性算法是用于从数据中估计数学模型参数的一组算法,特别适用于数据中含有大量离群点(噪声)的情况。它们通过迭代地选择一组随机样本来估计模型,并计算整个数据集中有多少点符合该模型(内点),然后选择出最佳匹配的模型。下面是一些常见的样本一致性算法,以及它们的应用场景对比:
RANSAC(Random Sample Consensus)
RANSAC 是一种基本且广泛使用的样本一致性算法。
特点:假设数据集中大部分数据是内点,内点是可以拟合成某个模型的。
优势:对于大量的噪声和离群点非常鲁棒。
劣势:可能需要较多的迭代次数,所需迭代次数难以提前确定,可能无法找到最优解。
应用场景:适用于点云分割、图像配准、目标检测等,在点云数据处理和计算机视觉领域非常常见。
LMedS(Least Median of Squares)
LMedS 是另一种样本一致性算法,它通过最小化中值误差来增强数据噪声的鲁棒性。
特点:不需要设置误差阈值。
优势:非常鲁棒,特别是在有高比例的离群点时。
劣势:无法直接确保结果模型优化到最高程度,且计算代价相对较高。
应用场景:当离群点比例很高,且数据分布不清楚时候适用,常见于健壮回归分析。
MSAC(M-Estimator SAmple Consensus)
MSAC 是 RANSAC 的变种,它通过修改成本函数改善了估计质量。
特点:使用另一种成本函数,倾向于内点较多的模型。
优势:结果模型的质量通常比 RANSAC 更好。
劣势:对于成本函数的选择比较敏感。
应用场景:在重视模型质量,但同时需要鲁棒性的场合,如图像分析和三维重建。
MLESAC(Maximum Likelihood Estimation SAmple Consensus)
MLESAC 是 RANSAC 的另一个变种,它通过最大似然估计来提高参数估计的准确性。
特点:将问题转化为最大似然估计问题,更偏向于可能性高的模型。
优势:相比 RANSAC,能够得到更准确的参数估计。
劣势:计算代价较高,设置适当的似然函数可能很复杂。
应用场景:当需要非常准确的参数估计时,如在高精度的机器人导航和地图制作中。
总结
所有这些算法都各有特点和优势,也都各自适合于不同类型的问题。选择哪种算法往往取决于应用需求、噪声和离群点的比例、计算资源等因素。通常,RANSAC 是最常见的起点,但若数据中的噪声比例极高或者需要更精确的模型,可能需要考虑使用 LMedS、MSAC 或 MLESAC 等算法。最终的选择应根据具体问题和实验结果来确定。
pcl::ProjectInliers<pcl::PointXYZ>
pcl::ConcaveHull<pcl::PointXYZ>
pcl::PCDWriter
1279

被折叠的 条评论
为什么被折叠?



