自学内容网 自学内容网

PCL 平面点云边界特征提取(alpha shapes)

目录

一、概述

1.1原理

1.2实现步骤

1.3应用场景

二、代码实现

2.1关键函数

2.1.1 点云边界提取

2.1.2 可视化点云与边界

2.2完整代码

三、实现效果


PCL点云算法汇总及实战案例汇总的目录地址链接:

PCL点云算法与项目实战案例汇总(长期更新)


一、概述

        平面点云边界特征提取可以帮助识别点云数据中的几何特征,通过提取边界信息,识别出点云的轮廓或边界。Alpha Shapes 是一种边界提取算法,通过调节参数 α,来控制提取的边界形状。本文使用 PCL 的 pcl::ConcaveHull 类实现基于 Alpha Shapes 的点云边界提取,并可视化结果。

1.1原理

        Alpha Shapes 算法是一种用于生成点集的边界的几何算法,具有灵活的 α 参数:

  • 当 α 较大时,边界较为凸;
  • 当 α 较小时,边界较为凹。

        边界由多个连接在一起的三角形组成,α 参数决定了哪些点会参与到边界生成中。通过调整 α,可以实现不同层次的边界提取。基本步骤如下:

  1. 点云输入:从点云中选择点。
  2. 生成边界:根据 α 参数生成边界形状。
  3. 可视化边界:对提取出的边界进行可视化展示。

1.2实现步骤

  1. 加载点云数据;
  2. 使用 pcl::ConcaveHull 进行边界特征提取;
  3. 通过调整 α 参数,生成不同的边界形状;
  4. 可视化点云和边界结果。

1.3应用场景

  1. 物体识别:通过提取边界点,识别物体的轮廓;
  2. 表面重建:提取物体边缘,辅助表面重建算法;
  3. 形状分析:基于点云数据的形状分析,判断物体的几何特征。

二、代码实现

2.1关键函数

2.1.1 点云边界提取

该函数使用 pcl::ConcaveHull 进行点云边界提取,alpha 参数控制边界形状。

void extractBoundary(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr boundary, float alpha)
{
    // 创建 ConcaveHull 对象
    pcl::ConcaveHull<pcl::PointXYZ> concave_hull;

    // 设置输入点云
    concave_hull.setInputCloud(cloud);

    // 设置 alpha 参数(控制边界形状)
    concave_hull.setAlpha(alpha);

    // 生成边界并存储到 boundary 点云中
    concave_hull.reconstruct(*boundary);
}

2.1.2 可视化点云与边界

该函数负责将原始点云和提取的边界点进行可视化展示,原始点云显示为红色,边界点显示为绿色。

void visualizeBoundary(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr boundary)
{
    // 创建可视化对象
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Boundary Viewer"));
    int vp1, vp2;

    // 创建视口 1,显示原始点云
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp1);
    viewer->setBackgroundColor(1.0, 1.0, 1.0, vp1);  // 设置背景为白色
    viewer->addText("Original Point Cloud", 10, 10, "vp1_text", vp1);

    // 原始点云设置为红色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 255, 0, 0);
    viewer->addPointCloud(cloud, cloud_color_handler, "original_cloud", vp1);

    // 创建视口 2,显示边界
    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp2);
    viewer->setBackgroundColor(0.98, 0.98, 0.98, vp2);  // 设置背景为灰色
    viewer->addText("Boundary", 10, 10, "vp2_text", vp2);

    // 边界点设置为绿色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> boundary_color_handler(boundary, 0, 255, 0);
    viewer->addPointCloud(boundary, boundary_color_handler, "boundary_cloud", vp2);

    // 开始可视化显示
    viewer->spin();
}

2.2完整代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/surface/concave_hull.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>

// 提取边界点
void extractBoundary(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr boundary, float alpha)
{
    // 创建 ConcaveHull 对象
    pcl::ConcaveHull<pcl::PointXYZ> concave_hull;

    // 设置输入点云
    concave_hull.setInputCloud(cloud);

    // 设置 alpha 参数(控制边界形状)
    concave_hull.setAlpha(alpha);

    // 生成边界并存储到 boundary 点云中
    concave_hull.reconstruct(*boundary);
}

// 可视化点云与边界
void visualizeBoundary(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr boundary)
{
    // 创建可视化对象
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Boundary Viewer"));
    int vp1, vp2;

    // 创建视口 1,显示原始点云
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp1);
    viewer->setBackgroundColor(1.0, 1.0, 1.0, vp1);  // 设置背景为白色
    viewer->addText("Original Point Cloud", 10, 10, "vp1_text", vp1);

    // 原始点云设置为红色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 255, 0, 0);
    viewer->addPointCloud(cloud, cloud_color_handler, "original_cloud", vp1);

    // 创建视口 2,显示边界
    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp2);
    viewer->setBackgroundColor(0.98, 0.98, 0.98, vp2);  // 设置背景为灰色
    viewer->addText("Boundary", 10, 10, "vp2_text", vp2);

    // 边界点设置为绿色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> boundary_color_handler(boundary, 0, 255, 0);
    viewer->addPointCloud(boundary, boundary_color_handler, "boundary_cloud", vp2);

    // 开始可视化显示
    viewer->spin();
}

// 主函数
int main(int argc, char** argv)
{
    // 读取点云数据
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
    pcl::io::loadPCDFile("cloud.pcd", *cloud);

    // 创建一个点云用于存储边界
    pcl::PointCloud<pcl::PointXYZ>::Ptr boundary(new pcl::PointCloud<pcl::PointXYZ>);

    // 提取边界,设定 alpha 为 0.05
    float alpha = 0.05f;
    extractBoundary(cloud, boundary, alpha);

    // 可视化边界
    visualizeBoundary(cloud, boundary);

    return 0;
}

三、实现效果


原文地址:https://blog.csdn.net/qq_47947920/article/details/142753654

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!