PCL点云库入门——PCL库可视化之CloudViewer类简单点云信息显示

1、前言

        可视化(visualization)涉及运用计算机图形学和图像处理技术,将数据转换成图像并在屏幕上展示,同时支持交互式处理。在PCL库中,一系列强大的可视化工具可供使用,其中较为流行的包括CloudViewer和PCLVisualizer类。CloudViewer是一个用于点云数据的简易可视化工具,而PCLVisualizer类则提供了PCL中最全面的可视化功能。相较于CloudViewer,PCLVisualizer的操作更为复杂,但其功能也更为全面。本节和下节将逐步介绍这两种工具的使用方法,从基础到高级,内容将不断更新。

2、CloudViewer类可视化

        CloudViewer以其简洁直观的设计,成为点云数据可视化的理想选择,尤其适合初学者和需要快速查看点云数据的用户。使用时,只需将点云数据加载到CloudViewer中,即可立即在屏幕上看到数据的三维图像,从而快速了解数据的整体结构和分布。下面从CloudViewer类中的主要成员函数说明到示例应用对其进行讲解说明,供大家参考学习。

2.1、主要成员函数

         CloudViewer类在#include <pcl/visualization/cloud_viewer.h>中可找到,其的成员函数不多,可见其提供的可视化功能简单,从中可知 CloudViewer类只提供如下4中点云类型的显示。

 //只包含三维点(x,y,z,)和颜色(r,g,b)+透明度(a)信息的点云显示using ColorACloud = pcl::PointCloud<pcl::PointXYZRGBA>;//只包含三维点(x,y,z,)和颜色(r,g,b)信息的点云显示using ColorCloud = pcl::PointCloud<pcl::PointXYZRGB>;//只包含三维点(x,y,z,)和强度(I)信息的点云显示using GrayCloud = pcl::PointCloud<pcl::PointXYZI>;//只包含三维点(x,y,z)的点云显示using MonochromeCloud = pcl::PointCloud<pcl::PointXYZ>;

        主要的成员函数和变量如下表:

函数名
描述
 CloudViewer (const std::string& window_name)
类构造函数,参数为可视化窗口的名称,如PCLVis
using VizCallable = std::function<void (pcl::visualization::PCLVisualizer&)>;
可视化回调函数定义
void showCloud (const ColorCloud::ConstPtr &cloud,
 const std::stringcloudname = "cloud");
可视化化带有RGB颜色的点云数据,通过Cloudname控制显示那个点云,当有多个点云时
void showCloud (const ColorACloud::ConstPtr &cloud
const std::stringcloudname = "cloud");
可视化化带有颜色+α通道的点云数据,通过Cloudname控制显示那个点云,当有多个点云时
void showCloud (const GrayCloud::ConstPtr &cloud,
 const std::stringcloudname = "cloud");
可视化化带有强度信息的点云数据,通过Cloudname控制显示那个点云,当有多个点云时
void showCloud (const MonochromeCloud::ConstPtr &cloud,
 const std::stringcloudname = "cloud");
可视化化没有RGB颜色的点云数据,通过Cloudname控制显示那个点云,当有多个点云时
bool  wasStopped  ( int  millis_to_wait  = 1);
判断UI界面是否退出,
void  runOnVisualizationThread  ( VizCallable  x ,  const  std :: string &  key  =  "callable" ); 
在渲染输出时每次都调用接口函数 
void  runOnVisualizationThreadOnce  ( VizCallable  x );
在渲染输出执行一次调用接口函数 
void  removeVisualizationCallable  ( const  std :: string &  key  =  "callable" );
响应清除可视化界面回调函数 
inline  boost :: signals2 :: connection  registerKeyboardCallback  ( void  (* callback ) ( const  pcl :: visualization :: KeyboardEvent &,  void *),  void *  cookie  =  nullptr )
响应键盘事件回调函数
inline  boost :: signals2 :: connection  registerMouseCallback  ( void  (* callback ) ( const  pcl :: visualization :: MouseEvent &,  void *),  void *  cookie  =  nullptr )
响应鼠标事件回调函数
inline  boost :: signals2 :: connection  registerPointPickingCallback  ( void  (* callback ) ( const  pcl :: visualization :: PointPickingEvent &,  void *),  void *  cookie  =  nullptr )
响应单击选点事件回调函数

 2.2、主要函数示例

        1)、void runOnVisualizationThreadOnce (VizCallable x),该函数在渲染输出时只执行一次调用,参数为回调函数。回调函数定义为如下:

// 回调函数,在主函数中只注册一次 ,设置可视化背景颜色,添加3D文字
void viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{viewer.setBackgroundColor(0.0, 0.40784, 0.5451); //设置背景颜色pcl::PointXYZ pose;                          //添加属性的位置pose.x = 10.0;pose.y = 0;pose.z = 0;//添加PCL LOGO 3D 文字//参数分别为:3D文字内容,文字位置,文字大小,文字颜色viewer.addText3D("PCL LOGO", pose,2,1,0.647,0);std::cout << "Only run once" << std::endl;
}

 2)、void runOnVisualizationThread (VizCallable x, const std::string& key = "callable"),该函数在渲染输出时每次都调用,参数为回调函数。回调函数定义为如下:

// 调函数,注册后每帧显示都执行一次,可视化添加一个刷新显示字符串
void viewerPsycho(pcl::visualization::PCLVisualizer& viewer)
{static unsigned count = 0;std::stringstream ss;ss << "Point Cloud Library: " << count++;viewer.removeShape("text", 0);// 参数含义:刷新字符串,在屏幕位置(x,y),字体大(100),字体颜色(1,0.54,0.0),字符串id,窗口idviewer.addText(ss.str(), 20, 500, 40, 1, 0.54, 0, "text", 0);
}

3)、inline boost::signals2::connection registerPointPickingCallback (void (*callback) (const pcl::visualization::PointPickingEvent&, void*), void* cookie = nullptr),该函数响应单击选点事件操作,操作相对其他两个复杂,具体操作如下,先定义回调参数类型:

struct callback_args {pcl::PointCloud<pcl::PointXYZ>::Ptr clicked_points_3d;pcl::visualization::PCLVisualizer::Ptr viewerPtr;
};

        在定义回调函数如下:


void pp_callback(const pcl::visualization::PointPickingEvent& event, void* args)
{struct callback_args* data = (struct callback_args*)args;if (event.getPointIndex() == -1)return;//获取事件点的IDint index = event.getPointIndex();std::cout << "index: " << index << std::endl;//获取点的三维坐标pcl::PointXYZ current_point;event.getPoint(current_point.x, current_point.y, current_point.z);data->clicked_points_3d->points.push_back(current_point);//设置可视点的颜色信息pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> red(data->clicked_points_3d, 255, 0, 0);data->viewerPtr->removePointCloud("clicked_points");//添加可视点data->viewerPtr->addPointCloud(data->clicked_points_3d, red, "clicked_points");//设置可视点的大小data->viewerPtr->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "clicked_points");//输出点的信息std::cout << current_point.x << " " << current_point.y << " " << current_point.z << std::endl;
}

注意:以上3的)内容我们会在下节进行结果展示,大家可以先跳过内容。 

3、CloudViewer可视化点云信息Demo

3.1、示例1,可视化无颜色点云和有颜色点云

        示例代码如下:

/*****************************************************************//**
* \file   PCLviewerMian.cpp
* \brief
*
* \author YZS
* \date   December 2024
*********************************************************************/
#include <iostream>              
#include <string>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>  //cloud_viewer类的头文件
using namespace std;// 回调函数,在主函数中只注册一次 ,设置可视化背景颜色,添加3D文字
void viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{viewer.setBackgroundColor(0.0, 0.40784, 0.5451); //设置背景颜色pcl::PointXYZ pose;                          //添加属性的位置pose.x = 0.10;pose.y = 0;pose.z = 0;//添加PCL LOGO 3D 文字//参数分别为:3D文字内容,文字位置,文字大小,文字颜色viewer.addText3D("PCL LOGO", pose, 0.5, 1, 0.647, 0);std::cout << "Only run once" << std::endl;
}
// 调函数,注册后每帧显示都执行一次,可视化添加一个刷新显示字符串
void viewerPsycho(pcl::visualization::PCLVisualizer& viewer)
{static unsigned count = 0;std::stringstream ss;ss << "Point Cloud Library: " << count++;viewer.removeShape("text", 0);// 参数含义:刷新字符串,在屏幕位置(x,y),字体大(100),字体颜色(1,0.54,0.0),字符串id,窗口idviewer.addText(ss.str(), 20, 500, 50, 1, 0.54, 0, "text", 0);
}
// 可视化点为PointXYZ的点云
void TestVisPointClouXYZ()
{// 创建点云对象,显示点类型为(X,Y,Z)的点云pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);//读取点云文件std::string fileName = "E:/PCLlearnData/4/fragment.pcd";pcl::io::loadPCDFile(fileName, *cloud);//创建可视化句柄viewer对象pcl::visualization::CloudViewer viewer("PCLVisPointXYZ");//用showCloud,将Cloud可视化到屏幕viewer.showCloud(cloud);//该接口函数在可视化的时候只执行一次,可以用于设置背景等一次性操作viewer.runOnVisualizationThreadOnce(viewerOneOff);//该接口函数在渲染输出时每次都调用,可以用于设置显示时间戳、计时器和动态处理等操作viewer.runOnVisualizationThread(viewerPsycho);while (!viewer.wasStopped()){//此处可以添加其他处理}
}
//可视化点为PointXYZRGB的点云数据
void TestVisPointClouXYZRGB()
{// 创建点云对象,显示点类型为(X,Y,Z ,R,G,B)的点云pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new  pcl::PointCloud<pcl::PointXYZRGB>);//读取点云文件std::string fileName = "E:/PCLlearnData/4/fragment.pcd";pcl::io::loadPCDFile(fileName, *cloud);//创建可视化句柄viewer对象pcl::visualization::CloudViewer viewer("PCLVisPointXYZRGB");//用showCloud,将Cloud可视化到屏幕viewer.showCloud(cloud);while (!viewer.wasStopped()){//此处可以添加其他处理}
}int main(int argc, char* argv[])
{//TestVisPointClouXYZ();TestVisPointClouXYZRGB();std::cout << "Hello PCL!" << std::endl;std::system("pause");return 0;
}

        结果展示:

3.2、键盘操作展示

        在上面2.1节内容中提到键盘和鼠标回调操作,常用的键盘操作命令有如下:

键盘操作命令

说明

p

切换到基于点的表示

w

切换到基于线框的表示

s

切换到基于表面的表示

c

显示当前摄像头/窗口参数

f

飞到点模式

e

退出交互程序

q

停止并调用VTK的TerminateApp

o

在透视/平行投影之间切换

g

显示比例栅格(开/关)

u

显示查找表(开/关)

        1)、显示比例栅格展示如下,其他的命令大家可自行操作一下查看效果。

至此完成第四节PCL库可视化之CloudViewer类简单点云信息显示学习,下一节我们将进入《PCL库可视化之PCLVisualizer类复杂点云信息显示》的学习。 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GUNS搭建

一、准备工作 源码下载&#xff1a; 链接: https://pan.baidu.com/s/1bJZzAzGJRt-NxtIQ82KlBw 提取码: criq 官方文档 二、导入代码 1、导入后端IDE 导入完成需要&#xff0c;需要修改yml文件中的数据库配置&#xff0c;改成自己的。 2、导入前端IDE 我是用npm安装的yarn npm…

Keil5添加stc的库到keil5中

1打开STC-ISP软件 在上图中找到keil仿真设置 再点击 点击之后会弹出选择文件 必须找到c51选中确定即可 之后在keil5中可以看到创建项目选择芯片是可以看到图中的选项

Vue基础记录

Vue 整体要学的 vue基础 vue-cli vue-router vuex element-ui vue3 简介 特点: 组件化声明式编码使用虚拟dom 优秀Diff算法 在生成真实dom的时候,会先有一部虚拟dom,且新的虚拟dom会和旧的虚拟dom进行diff算法比较 如果有些dom没改,那么就可以不用再重新渲染了,提高性能 …

【和春笋一起学C++】for语句和递增操作符

目录 1. for语句简介 2. for语句实例 3. 顺序点和副作用 4. 递增递减操作符应用于指针 1. for语句简介 for语句包含控制体和循环体&#xff0c;循环体跟在控制体的后面。 如下所示&#xff0c;控制体为for括号中的几个表达式&#xff0c;循环体为花括号中的几条语句。 fo…

有哪些方法可以快速批量的去查询手机号码归属地和运营商,快速的按归属地和运营商进行号码的分类 ?

下面为大家总结了一些快速查询手机号码归属地的工具和方法 工具仅供参考&#xff1a; 如何大批量的进行手机号码归属地查询 &#xff0c;按省份分类&#xff0c;按城市分类&#xff0c;按运营商&#xff08;移动、电信、联通&#xff09;快速分类&#xff0c;高效办公工具批量…

Elasticsearch+Kibana分布式存储引擎

1.ElaticSearch介绍 ElaticSearch &#xff0c;简称为 ES &#xff0c; ES 是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检 索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理 PB 级别的数据。 ES 也使用 …

The Past, Present and Future of Apache Flink

摘要&#xff1a;本文整理自阿里云开源大数据负责人王峰&#xff08;莫问&#xff09;在 Flink Forward Asia 2024上海站主论坛开场的分享&#xff0c;今年正值Flink开源项目诞生的第10周年&#xff0c;借此时机&#xff0c;王峰回顾了Flink在过去10年的发展历程以及 Flink社区…

OpenAI 正式赋予 ChatGPT 通过视频实时与用户互动的能力

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

java jar包加密 jar-protect

介绍 java 本身是开放性极强的语言,代码也容易被反编译,没有语言层面的一些常规保护机制,jar包很容易被反编译和破解。 受classfinal&#xff08;已停止维护&#xff09;设计启发,针对springboot日常项目开发,重新编写安全可靠的jar包加壳加密技术,用于保护软件版权。 使用说…

arm CPS指令解释

arm CPS指令解释 1 The Current Program Status Register, CPSR1.1 N, Z, C, V, bits [31:28]1.2 Q, bit [27]1.3 SSBS, bit [23]1.4 PAN, bit [22]1.4.1 About the PAN bit 1.5 DIT, bit [21]1.6 GE[3:0], bits [19:16]1.7 E, bit [9]1.8 A, I, F, bits [8:6]1.9 M[4:0], bits…

VSCode 报错:rust-analyzer requires glibc >= 2.28 in latest build

报错信息 /home/jake/.vscode-server-insiders/extensions/matklad.rust-analyzer-0.3.953/server/rust-analyzer: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.29 not found (required by /home/jake/.vscode-server-insiders/extensions/matklad.rust-analyzer-0.3.9…

GFPS扩展技术原理(一)消息流

消息流作用 Google fast pair service要求Provider提供一个额外得通道以便seeker寻求建立连接&#xff0c;连接建立后&#xff0c;Seeker就可以向Provider发送一串数据流&#xff0c;这样做的目的是为了支持GFPS Extension&#xff0c;也就是扩展的GFPS&#xff0c;主要涉及一…

Vue项目打包部署到服务器

1. Vue项目打包部署到服务器 1.1. 配置 &#xff08;1&#xff09;修改package.json文件同级目录下的vue.config.js文件。 // vue.config.js module.exports {publicPath: ./, }&#xff08;2&#xff09;检查router下的index.js文件下配置的mode模式。   检查如果模式改…

rk3588-ubuntu22.04系统网关实现路由器功能:

rk3588-ubuntu22.04系统网关实现路由器功能&#xff1a; 场景需求描述&#xff1a; 需求背景&#xff1a; 场景一&#xff1a;通过网线eth0/(路由器wlan0)访问外网&#xff1a; 如果网关 和 设备所处的环境可以通过网线联网或者路由器联网&#xff0c;那么不需要将网关配置成…

GIF制作工具推荐与详细使用教程

引言 GIF&#xff08;Graphics Interchange Format&#xff09;是一种广泛使用的图像格式&#xff0c;常用于创建动画或短视频片段。无论你是想制作表情包、动画教程还是简单的动画效果&#xff0c;选择一个合适的GIF制作工具是关键。下面我们将推荐几款免费且易用的GIF制作工…

打卡第十二天 P1012 [NOIP1998 提高组] 拼数

题目描述 设有 n 个正整数 &#xff0c;将它们联接成一排&#xff0c;相邻数字首尾相接&#xff0c;组成一个最大的整数。 输入格式 第一行有一个整数&#xff0c;表示数字个数 n。 第二行有 n 个整数&#xff0c;表示给出的 n 个整数 。 输出格式 一个正整数&#xff0c…

【每日刷题】Day169

【每日刷题】Day169 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 718. 最长重复子数组 - 力扣&#xff08;LeetCode&#xff09; 2. 2269. 找到一个数字的 K 美丽值…

SeaTunnel Web1.0.0安装

部署seatunnel2.3.8参考:部署seatunnel2.3.8-CSDN博客 SeaTunnel Web1.0.1对应的seatunnel2.3.3版本,所以如果要想在SeaTunnel Web1.0.1上能正常跑seatunnel对应版本包,在seatunnel上传的connector-开头的包,都得跟着SeaTunnel Web依赖的版本走,如安装了seatunnel2.3.7但…

AI大模型学习笔记|多目标算法梳理、举例

多目标算法学习内容推荐&#xff1a; 1.通俗易懂讲算法-多目标优化-NSGA-II(附代码讲解)_哔哩哔哩_bilibili 2.多目标优化 (python pyomo pareto 最优)_哔哩哔哩_bilibili 学习笔记&#xff1a; 通过网盘分享的文件&#xff1a;多目标算法学习笔记 链接: https://pan.baidu.com…

Go 语言与时间拳击理论下的结对编程:开启高效研发编程之旅

一、引言 结对编程作为一种软件开发方法&#xff0c;在提高代码质量、增强团队协作等方面具有显著优势。而时间拳击理论为结对编程带来了新的思考角度。本文将以 Go 语言为中心&#xff0c;深入探讨时间拳击理论下的结对编程。 在当今软件开发领域&#xff0c;高效的开发方法和…