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

news2024/12/23 11:03:05

目录

一、概述

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;
}

三、实现效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2200833.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

07:(寄存器开发)串口通信

串口通信 1、串口简介2、串口通讯协议3、硬件外设4、发送数据5、使用轮询的方式接收数据&#xff08;USART1&#xff09;6、使用中断的方式接收数据7、串口进行printf重定向 1、串口简介 串口通讯&#xff08;Serial Communication&#xff09;是一种设备间非常常用的串行通讯方…

后端增删改查的基本应用——一个简单的货物管理系统

最终效果&#xff0c;如图所示&#xff1a; 如果想要进行修改操作&#xff0c;可点击某栏修改选项&#xff0c;会在本表格下方弹出修改的具体操作界面&#xff08;点击前隐藏&#xff09;&#xff0c;并且目前的信息可复现在修改框内。 本篇文章通过该项目将后端和前端结合起来…

java内存控制

Java 内存控制是一个相对复杂但至关重要的主题&#xff0c;它涉及到如何高效地管理Java应用程序中的内存资源。在Java中&#xff0c;内存管理主要由Java虚拟机&#xff08;JVM&#xff09;负责&#xff0c;包括内存的分配和回收。尽管如此&#xff0c;作为开发者&#xff0c;我…

2025年5月高项,从0备考信息系统项目管理师 | 备考经验全攻略分享

在逐步摸索备考信息系统项目管理师的过程中&#xff0c;我总结了很多关于班课资料和学习经验&#xff0c;现在与大家分享。&#xff08;全文约3k字&#xff0c;阅读用时约5min&#xff09; 这篇分享帖不仅告诉你关于备考信息系统项目管理师实用的班课资料&#xff0c;还有学习…

Win11 23H2 10月正式版:22631.4317 镜像免费下载!

今日&#xff0c;系统之家小编给您带来2024年10月最新更新的Windows11 23H2正式版系统下载&#xff0c;该版本系统基于微软官方最新Windows11 23H2 22631.4317专业版展开离线制作&#xff0c;没有病毒残留&#xff0c;且能完美支持新老机型&#xff0c;安装后&#xff0c;系统版…

【概率论】泊松分布

泊松分布 若 &#xff0c;则 归一性 例子 泊松分布多出现在当X表示一定时间或一定空间内出现的事件的个数这种场合&#xff0c;如在一定时间内某交通路口所发生的事故的个数。 将泊松分布假设为二项分布 假设条件: &#xff08;1&#xff09;泊松分布一般为一段时间或一…

★ 算法OJ题 ★ 二分查找算法

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;塞尔达将和大家一起做几道二分查找算法算法题 ~ ❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️ 澄岚主页&#xff1a;椎名澄嵐-CSDN博客 算法专栏&#xff1a;★ 优选算法100天 ★_椎名澄嵐的博客-CSDN博客…

STM32 SPI串行总线

目录 STM32的SPI通信原理 SPI串行总线概述 SPI串行总线互连方式 STM32F1 SPI串行总线的工作原理 SPI串行总线的特征 SPI串行总线的内部结构 SPI串行总线时钟信号的相位和极性 STM32的SPI接口配置 STM32的SPI接口数据发送与接收过程 SPI的HAL 驱动函数 STM32的SPI通信…

靶标弹孔检测系统源码分享

靶标弹孔检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

apt update报错:ModuleNotFoundError: No module named ‘apt_pkg‘(可能是默认python版本被改坏了)

文章目录 错误信息分析1. 确保 apt_pkg 模块已安装2. 检查 Python 版本3. 重新配置 Python4. 修复损坏的依赖5. 检查环境变量 尝试 错误信息 (base) rootkyai:/ky/tml/ky_ai_get_server_info# apt update 获取:1 file:/var/cuda-repo-cross-aarch64-ubuntu2004-11-4-local InR…

【Python】如何让SQL Server像MySQL一样拥有慢查询日志(Slow Query Log慢日志)

如何让SQL Server像MySQL一样拥有慢查询日志&#xff08;Slow Query Log慢日志&#xff09; SQL Server一直以来被人诟病的一个问题是缺少了像MySQL的慢日志功能&#xff0c;程序员和运维无法知道数据库过去历史的慢查询语句。 因为SQLServer默认是不捕获过去历史的长时间阻塞…

inBuilder低代码平台新特性推荐-第二十五期

今天来给大家带来的是inBuilder低代码平台社区版中的特性推荐系列第二十五期——选人组件扩展&#xff01; 一、概述 inBuilder低代码平台社区版的开发过程中&#xff0c;选人组件支持tab页中增加扩展页面&#xff0c;由二开人员根据业务场景实现自定义取数接口和页面展示形式…

【笔记】济南,天命人,春秋

孤独而高傲的济南人 浩克山东知天命热爱的sensei 浩克山东 哦哦&#xff0c;最高的大葱也是济南的了&#xff0c;这大葱&#xff0c;比一般人要高呢&#xff0c;尽管济南的朋友们也都个子不矮。。能想像的到两米高的米库。。。。 然而在这块地界&#xff0c;遇到个人&#xf…

基于STM32的简易交通灯proteus仿真设计(仿真+程序+设计报告+讲解视频)

基于STM32的简易交通灯proteus仿真设计(仿真程序设计报告讲解视频&#xff09; 仿真图proteus 8.9 程序编译器&#xff1a;keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;C0091 **1.**主要功能 功能说明&#xff1a; 以STM32单片机和数码管、LED灯设计简易交通…

版本控制系统Helix Core的常见使用误区及解决办法、实用工具及新功能介绍

日前&#xff0c;Perforce携手合作伙伴龙智一同亮相Unreal Fest 2024上海站&#xff0c;分享Helix Core版本控制系统及其协作套件的强大功能与最新动态&#xff0c;助力游戏创意产业加速前行。 Perforce解决方案工程师Kory Luo在活动主会场&#xff0c;带来《Perforce Helix C…

QT安装成功后-在创建项目时,发现仅有项目名文件

&#xff08;1&#xff09;QT安装成功后&#xff0c;发现仅有项目名文件其他可编辑文件缺失 &#xff08;2&#xff09;点击文件名左上角的感叹号显示【No kits are enabled for this project. Enable】 小编在尝试多次后发现&#xff0c;可以通过以下方式解决&#xff1a;QT软…

YOLO11改进|编码器篇|引入AIFI混合特征编码器

目录 一、【AIFI】混合编码器机制1.1【AIFI】混合编码器介绍1.2【AIFI】核心代码 二、添加【AIFI】机制2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【AIFI】混合编码器机制 1.1【AIFI】混合编码器介绍 【AIFI】在论文中并没有结构图…

CVPR 2024最佳论文候选-pixelSplat论文解读

目录 一、概述 二、相关工作 1、单场景下的视角合成 2、基于先验的三维重建和视图合成 3、多视图几何测量 三、3DGS的缺点 1、容易陷入最小值 2、需要大量输入图像 3、尺度模糊性 四、pixelSplat 1、解决尺度模糊性&#xff08;深度信息生成&#xff09; 2、编码器…

QT实现QMessageBox中文按钮

这是我记录Qt学习过程心得文章的第二篇&#xff0c;主要是为了方便QMessageBox弹出框的使用&#xff0c;通过自定义的方式&#xff0c;将其常用的功能&#xff0c;统一封装成一个函数&#xff0c;还是写在了Skysonya类里面。 实现代码&#xff1a; //中文提示对话框 bool Sky…

线程(四)线程的同步——条件变量

文章目录 线程线程的同步和互斥线程同步--条件变量什么是线程同步示例--条件变量的使用示例--使用两个线程对同一个文件进行读写示例--一个读者一个写者使用条件变量来实现同步 线程 线程的同步和互斥 线程同步–条件变量 是一个宏观概念&#xff0c;在微观上包含线程的相互…