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::string& cloudname = "cloud");
|
可视化化带有RGB颜色的点云数据,通过Cloudname控制显示那个点云,当有多个点云时
|
void showCloud (const ColorACloud::ConstPtr &cloud,
const std::string& cloudname = "cloud");
|
可视化化带有颜色+α通道的点云数据,通过Cloudname控制显示那个点云,当有多个点云时
|
void showCloud (const GrayCloud::ConstPtr &cloud,
const std::string& cloudname = "cloud");
|
可视化化带有强度信息的点云数据,通过Cloudname控制显示那个点云,当有多个点云时
|
void showCloud (const MonochromeCloud::ConstPtr &cloud,
const std::string& cloudname = "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,窗口id
viewer.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;
//获取事件点的ID
int 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,窗口id
viewer.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类复杂点云信息显示》的学习。