【PCL】教程 implicit_shape_model.cpp 3D点云数据的对象识别 利用隐式形状模型进行训练和识别...

6415877795f1f5d4540772f4ed252b20.png

ism_test_cat.pcd

a47db2d580c13a227bf90e25040898da.png

参数:ism_train_cat.pcd      0      ism_train_horse.pcd    1      ism_train_lioness.pcd  2      ism_train_michael.pcd  3      ism_train_wolf.pcd     4      ism_test_cat.pcd       0

这里红点表示对应感兴趣类别的对象预测中心

./ism_test ism_train_cat.pcd 0 ism_train_horse.pcd 1 ism_train_lioness.pcd 2 ism_train_michael.pcd 3 ism_train_wolf.pcd 4 ism_test_cat.pcd 0
./ism_test ism_train_cat.pcd 0 ism_train_horse.pcd 1 ism_train_lioness.pcd 2 ism_train_michael.pcd 3 ism_train_wolf.pcd 4 ism_test_horse.pcd 1

这段代码是一个使用PCL(Point Cloud Library)的C++程序,用于3D点云数据的识别训练和测试。程序的流程可以分为几个主要步骤:

  1. 参数检查:程序首先检查传入的参数数量,确保至少有一个训练云和一个测试云,每个云都需要有一个类别ID

  2. 训练数据准备:

  • 使用pcl::NormalEstimation为每个训练点云计算法线

  • 读取训练点云文件,计算法线,然后将点云、法线以及类别ID分别存储

特征提取:接着,使用pcl::FPFHEstimation为每个点计算FPFH(Fast Point Feature Histograms)特征

隐式形状模型训练:之后,使用pcl::ism::ImplicitShapeModelEstimation完成隐式形状模型的训练。这个过程中,将使用到上一步骤计算得到的特征,同时输入训练用的点云数据、法线以及类别ID。

模型保存与加载:训练得到的模型将保存到文件中,可以在后续进行加载和使用。

测试数据处理:与训练数据类似,为测试数据云计算法线

对象识别:利用训练好的模型,对测试数据进行对象识别。识别的过程中会生成一个投票列表,通过算法找出最强的峰值。

可视化:为测试点云着色,将识别的对象标记为不同的颜色,并使用pcl::visualization::CloudViewer显示结果。

整体而言,这段代码主要实现了使用PCL库进行3D点云数据的对象识别,包括数据准备、特征提取、模型训练、对象识别以及结果可视化等步骤。通过计算点云的法线和FPFH特征,利用隐式形状模型进行训练和识别,最终在视窗中显示带有识别结果的点云,以不同颜色区分识别出的对象和背景点云。这个程序适用于需要对3D点云进行对象分类和识别的场景。

#include <iostream> // 包含标准输入输出流库
#include <pcl/io/pcd_io.h> // 包含处理PCD(点云数据)文件输入输出操作的库
#include <pcl/features/normal_3d.h> // 包含计算点云法线特征的库
#include <pcl/features/feature.h> // 包含处理点云特征的基本方法的库
#include <pcl/visualization/cloud_viewer.h> // 包含点云可视化的库
#include <pcl/features/fpfh.h> // 包含计算FPFH(快速点特征直方图)特征的库
#include <pcl/features/impl/fpfh.hpp> // 包含FPFH特征实现的库
#include <pcl/recognition/implicit_shape_model.h> // 包含隐式形状模型(ISM)识别算法的库
#include <pcl/recognition/impl/implicit_shape_model.hpp> // 包含隐式形状模型实现的库


int main (int argc, char** argv)
{
  if (argc < 5 || argc % 2 == 0) // 判断命令行参数数量是否正确
    return (-1);


  unsigned int number_of_training_clouds = (argc - 3) / 2; // 计算训练云的数量


  pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimator; // 法线估计器的初始化
  normal_estimator.setRadiusSearch (25.0); // 设置搜索半径


  std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> training_clouds; // 用于存储训练用的点云数据
  std::vector<pcl::PointCloud<pcl::Normal>::Ptr> training_normals; // 用于存储训练数据对应的法线信息
  std::vector<unsigned int> training_classes; // 用于存储训练数据对应的类别ID


  for (unsigned int i_cloud = 0; i_cloud < number_of_training_clouds - 1; i_cloud++)
  {
    pcl::PointCloud<pcl::PointXYZ>::Ptr tr_cloud(new pcl::PointCloud<pcl::PointXYZ> ());
    if ( pcl::io::loadPCDFile <pcl::PointXYZ> (argv[i_cloud * 2 + 1], *tr_cloud) == -1 ) // 加载训练用的点云文件
      return (-1);


    pcl::PointCloud<pcl::Normal>::Ptr tr_normals (new pcl::PointCloud<pcl::Normal>); // 法线信息的容器
    normal_estimator.setInputCloud (tr_cloud); // 设置输入的点云为上述加载的点云
    normal_estimator.compute (*tr_normals); // 计算法线信息


    unsigned int tr_class = static_cast<unsigned int> (strtol (argv[i_cloud * 2 + 2], 0, 10)); // 从命令行参数中获取对应的类别ID


    training_clouds.push_back (tr_cloud); // 将点云数据存入训练集容器
    training_normals.push_back (tr_normals); // 将法线信息存入训练集容器
    training_classes.push_back (tr_class); // 将类别ID存入训练集容器
  }


  pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::Histogram<153> >::Ptr fpfh
    (new pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::Histogram<153> >); // 初始化FPFH特征估计器
  fpfh->setRadiusSearch (30.0); // 设置FPFH的搜索半径
  pcl::Feature< pcl::PointXYZ, pcl::Histogram<153> >::Ptr feature_estimator(fpfh); // 特征估计器的初始化


  pcl::ism::ImplicitShapeModelEstimation<153, pcl::PointXYZ, pcl::Normal> ism; // 初始化隐式形状模型估计器
  ism.setFeatureEstimator(feature_estimator); // 设置特征估计器
  ism.setTrainingClouds (training_clouds); // 设置训练用的点云数据
  ism.setTrainingNormals (training_normals); // 设置训练用的法线信息
  ism.setTrainingClasses (training_classes); // 设置训练用的类别ID
  ism.setSamplingSize (2.0f); // 设置采样大小


  pcl::ism::ImplicitShapeModelEstimation<153, pcl::PointXYZ, pcl::Normal>::ISMModelPtr model (new pcl::features::ISMModel); // 初始化ISM模型
  ism.trainISM (model); // 训练ISM模型


  std::string file ("trained_ism_model.txt"); // 指定模型保存的文件名
  model->saveModelToFile (file); // 保存模型到文件


  model->loadModelFromfile (file); // 从文件加载模型


  unsigned int testing_class = static_cast<unsigned int> (strtol (argv[argc - 1], 0, 10)); // 获取测试数据的类别ID
  pcl::PointCloud<pcl::PointXYZ>::Ptr testing_cloud (new pcl::PointCloud<pcl::PointXYZ> ());
  if ( pcl::io::loadPCDFile <pcl::PointXYZ> (argv[argc - 2], *testing_cloud) == -1 ) // 加载测试用的点云文件
    return (-1);


  pcl::PointCloud<pcl::Normal>::Ptr testing_normals (new pcl::PointCloud<pcl::Normal>); // 初始化存储测试数据法线信息的容器
  normal_estimator.setInputCloud (testing_cloud); // 设置输入的点云为测试点云
  normal_estimator.compute (*testing_normals); // 计算法线信息


  pcl::features::ISMVoteList<pcl::PointXYZ>::Ptr vote_list = ism.findObjects (
    model,
    testing_cloud,
    testing_normals,
    testing_class); // 使用训练好的ISM模型进行物体识别


  double radius = model->sigmas_[testing_class] * 10.0; // 根据类别ID计算搜索半径
  double sigma = model->sigmas_[testing_class]; // 获取当前类别的标准差
  std::vector<pcl::ISMPeak, Eigen::aligned_allocator<pcl::ISMPeak> > strongest_peaks; // 初始化存储搜索到的最强峰值的容器
  vote_list->findStrongestPeaks (strongest_peaks, testing_class, radius, sigma); // 搜索最强峰值


  pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud (new pcl::PointCloud<pcl::PointXYZRGB>); // 初始化用于可视化的有色云
  colored_cloud->height = 0;
  colored_cloud->width = 1;


  pcl::PointXYZRGB point; // 初始化绘制点的颜色为白色
  point.r = 255;
  point.g = 255;
  point.b = 255;


  for (std::size_t i_point = 0; i_point < testing_cloud->size (); i_point++) // 遍历测试数据的点
  {
    point.x = (*testing_cloud)[i_point].x; // 设置点的坐标
    point.y = (*testing_cloud)[i_point].y;
    point.z = (*testing_cloud)[i_point].z;
    colored_cloud->points.push_back (point); // 将点添加到有色云中
  }
  colored_cloud->height += testing_cloud->size (); // 更新有色云的高度


  point.r = 255; // 设置最强峰值点的颜色为红色
  point.g = 0;
  point.b = 0;
  for (std::size_t i_vote = 0; i_vote < strongest_peaks.size (); i_vote++) // 遍历所有最强峰值点
  {
    point.x = strongest_peaks[i_vote].x; // 设置点的坐标
    point.y = strongest_peaks[i_vote].y;
    point.z = strongest_peaks[i_vote].z;
    colored_cloud->points.push_back (point); // 将点添加到有色云中
  }
  colored_cloud->height += strongest_peaks.size (); // 更新有色云的高度
  //strongest_peaks.size ()==1; 
  pcl::visualization::CloudViewer viewer ("Result viewer"); // 初始化云查看器
  viewer.showCloud (colored_cloud); // 在查看器中显示有色云
  while (!viewer.wasStopped ()) // 持续显示直到用户关闭查看器
  {
  }


  return (0); // 程序正常结束
}

这段代码是一个使用PCL(Point Cloud Library)和隐式形状模型(ISM)进行点云识别的程序。主要实现了以下功能:

  1. 加载训练和测试数据的点云文件。

  2. 计算点云的法线信息。

  3. 使用FPFH算法进行特征估计

  4. 利用隐式形状模型对训练数据进行训练,并保存模型。

  5. 从文件加载训练好的模型。

  6. 使用加载的模型对测试数据进行识别。

  7. 根据识别结果,将识别到的对象在点云中标出,并通过可视化显示结果。

此代码片段适用于需要进行物体识别和分类的场合,特别是在利用3D点云数据进行机器人视觉或智能制造等领域。

pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal>
    normal_estimator

d770c74ac8ed5368000eba5c75d49ca3.png

e7523540e0635826d4407b8c0ea951b3.png

pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::Histogram<153>>::Ptr fpfh(
    new pcl::FPFHEstimation<pcl::PointXYZ,
                            pcl::Normal,
                            pcl::Histogram<153>>);

dd6b416cf5822f1090f9f5c86a1a61f7.png

pcl::Feature<pcl::PointXYZ, pcl::Histogram<153>>::Ptr
   feature_estimator(fpfh); // 特征估计器的初始化

cf8b41f741482bcc2d328ca2207b1c19.png

pcl::ism::ImplicitShapeModelEstimation<153, pcl::PointXYZ, pcl::Normal>
    ism;

f3b3b73dbd61df224176fc635f4ea0e2.png

pcl::ism::ImplicitShapeModelEstimation<153, pcl::PointXYZ, pcl::Normal>::ISMModelPtr
    model(new pcl::features::ISMModel);

6a5c27c78200de01dfe12ebdd944aff0.png

pcl::features::ISMVoteList<pcl::PointXYZ>::Ptr vote_list =
      ism.findObjects(model,
                      testing_cloud,
                      testing_normals,
                      testing_class);

e1777bf76a6a682f5dd853940bd330ff.png

vote_list->findStrongestPeaks(
     strongest_peaks, testing_class, radius, sigma);

9eaca1046b8aed54b3b9d18f62a96a0a.png

参考网址

隐式形状模型 —— 点云库 0.0 文档 --- Implicit Shape Model — Point Cloud Library 0.0 documentation (pcl.readthedocs.io) https://pcl.readthedocs.io/projects/tutorials/en/latest/implicit_shape_model.html#compiling-and-running-the-program

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

字节FE:JavaScript学习路线图

JavaScript简介 JavaScript是一种高级的、解释执行的编程语言。它是互联网的三大核心技术之一&#xff0c;与HTML和CSS一同工作&#xff0c;用于创建交互式的网页。JavaScript被所有现代网页浏览器支持而不需要任何插件。它可以增强用户界面和网页的交互性&#xff0c;可以进行…

【讲解下Spring Boot单元测试】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

FineBi中创建自定义的图表

FineBi中增加自己的自定义图表组件,比如: 的相关笔记: 1 获取有哪些BI自定义图表组件:http://localhost:8080/webroot/decision/v5/plugin/custom/component/list?_=1713667435473[{"name": "图表DEMO_EK","chartType": "amap_demo&q…

GO环境及入门案例

文章目录 简介一、win GO开发环境安装二、Linux go运行环境二、GO代码入门2.1 导包案例2.2 赋值2.3 变量、函数2.4 三方库使用 简介 go不是面向对象语言&#xff0c; 其指针、结构体等比较像C&#xff0c;知名的go 开源项目有docker k8s prometheus node-exporter等 一、win …

如何在3dMax中快速打包mzp 文件?

如何在3dMax中创建mzp 文件&#xff1f; 我喜欢将我的Maxscript脚本发布为mzp文件。这是一个为3dMax构建的自解压zip文件。在mzp文件中&#xff0c;您可以捆绑Maxscript脚本文件、图片、预设或其他文件&#xff0c;并链接安装时执行的特殊操作。 在3dMax中使用大型脚本时&…

耐高温300度锅炉轴承,江苏鲁岳轴承制造的行业标杆

自润滑轴承-产品类型-耐高温轴承-不锈钢轴承-江苏鲁岳轴承制造有限公司。锅炉轴承&#xff0c;耐高温至200度-800度。 江苏鲁岳轴承制造有限公司&#xff0c;一家专注于锅炉轴承和耐高温轴承的研发与生产的企业&#xff0c;致力于为客户提供高质量、高性能的轴承解决方案。其中…

LeetCode题练习与总结:矩阵置零--73

一、题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]示例 2&#xf…

Linux-内存文件

1. 基础IO操作 1.1 c语言的IO接口 fopen&#xff1a;打开一个文件&#xff0c;按照指定方式 参数&#xff1a;filename 文件名&#xff0c;也可以是路径&#xff0c;mode&#xff1a;打开方式 返回打开的文件指针 fread&#xff1a;从指定流中读数据 参数&#xff1a;从FIL…

Selenium web自动化测试环境搭建

Selenium web自动化环境搭建主要要经历以下几个步骤&#xff1a; 1、安装python 在python官网&#xff1a;Welcome to Python.org&#xff0c;根据各自对应平台如&#xff1a;windows&#xff0c;下载相应的python版本。 ​ 下载成功后&#xff0c;点击安装包&#xff0c;一直…

解释一下“暂存区”的概念,在Git中它扮演什么角色?

文章目录 暂存区在Git中的概念与作用什么是暂存区&#xff08;Staging Area&#xff09;暂存区的位置和结构 暂存区在Git工作流程中的角色1. 分离工作区与版本库的交互示例代码与操作步骤示例1&#xff1a;将工作区的修改添加至暂存区 2. 控制提交内容的粒度示例2&#xff1a;分…

【Linux】虚拟机与Xshell及VS Code的连接

一、基础环境 虚拟机&#xff1a;VMware Workstation Pro 虚拟机镜像&#xff1a;ubuntu-18.04.5-desktop-amd64.iso 其他&#xff1a;Xshell 6、Xftp 6、Visual Studio Code 上述软件的安装操作不再赘述&#xff0c;CSDN上有大量的优秀博文&#xff0c;可参考&#xff1a;详细…

安装和部署maven

准备工作 maven下载地址&#xff1a;https://maven.apache.org/download.cgi 使用wget将maven包下载到linux环境上&#xff0c;/toos/ 目录下&#xff08;也可用迅雷&#xff09; wget https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.g…

小游戏贪吃蛇的实现之C语言版

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;C语言 目录 游戏前期准备&#xff1a; 设置控制台相关的信息 GetStdHandle GetConsoleCursorInfo SetConsoleCursorInfo SetConsoleCu…

VSCode插件开发学习

一、环境准备 0、参考文档&#xff1a;VS Code插件创作中文开发文档 1、大于18版本的nodejs 2、安装Yeoman和VS Code Extension Generator&#xff1a; npm install -g yo generator-code 3、生成脚手架 yo code 选择内容&#xff1a; ? What type of extension do yo…

GPT-3.5 Turbo 的 temperature 设置为 0 就是贪婪解码?

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 将 GPT-3.5 Turbo 的 temperature 设置为 0 通常意味着采用贪婪解码&#xff08;greedy decoding&#xff09;策略。在贪婪解码中&#xff0c;模型在每一步生成文本时选择概率最高的词元&#xff0c;从…

微调Llama3实践并基于Llama3构建心理咨询EmoLLM

Llama3 Xtuner微调Llama3 EmoLLM 心理咨询师

LabVIEW多设备控制与数据采集系统

LabVIEW多设备控制与数据采集系统 随着科技的进步&#xff0c;自动化测试与控制系统在工业、科研等领域的应用越来越广泛。开发了一种基于LabVIEW平台开发的多设备控制与数据采集系统&#xff0c;旨在解决多设备手动设置复杂、多路数据显示不直观、数据存储不便等问题。通过RS…

基于STM32的蓝牙小车的Proteus仿真(虚拟串口模拟)

文章目录 一、前言二、仿真图1.要求2.思路3.画图3.1 电源部分3.2 超声波测距部分3.3 电机驱动部分3.4 按键部分3.5 蓝牙部分3.6 显示屏部分3.7 整体 4.仿真5.软件 三、总结 一、前言 proteus本身并不支持蓝牙仿真&#xff0c;这里我采用虚拟串口的方式来模拟蓝牙控制。 这里给…

42岁TVB男艺人曾靠刘德华贴钱出道,苦熬10年终上位

张颕康在无线&#xff08;TVB&#xff09;电视打滚多年&#xff0c;近年在《逆天奇案》第一、二辑凭扎实演技为人留下印象。他还是圈中出名的「爱妻号」&#xff0c;日前在访问期间&#xff0c;张颕康三句不离多谢太太。 较年长的观众或会记得&#xff0c;张颕康初出道以「刘德…

kettle从入门到精通 第五十三课 ETL之kettle MQTT/RabbitMQ consumer实战

1、上一节课我们学习了MQTT producer 生产者步骤&#xff0c;MQTT consumer消费者步骤。该步骤可以从支持MRQTT协议的中间件获取数据&#xff0c;该步骤和kafka consumer 一样可以处理实时数据交互&#xff0c;如下图所示&#xff1a; 2、双击步骤打开MQTT consumer 配置窗口&a…