Qt+PCL手把手教材(第11讲)——PCL库PCLVisualizer点云可视化以及与 VTK 交互器(Interactor)详解和代码示例

在 PCL 点云库中,PCLVisualizer 是建立在 VTK(Visualization Toolkit) 之上的 3D 可视化引擎,这也就是Qt+VTK+PCL联合的底层逻辑。PCL点云库通过 PCLVisualizer 提供的封装接口,用户可以实现基于事件的 交互操作、拾取响应、视角控制 等高级可视化需求(如展示点云、几何图形、标注文本等,并且支持与用户交互)。同时,它也允许直接使用底层 VTK 对象来自定义交互样式与行为。PCLVisualizer 是PCL点云可视化和交互的核心类之一,可以用于 3D 渲染、点云的颜色设置、缩放、旋转等操作。下面先对PCLVisualizer 的基本应用进行讲解。

在这里插入图片描述

1、PCLVisualizer 基本功能概述

  1. 点云显示:可以通过 PCLVisualizer 显示点云数据,支持不同的显示样式(如球体、点、平面等)。
viewer->addPointCloud<pcl::PointXYZ>(cloud, "cloud_id");

点云更新(动态刷新)

viewer->updatePointCloud(cloud, "cloud_id");
  1. 支持多种几何体渲染:除了点云,还可以渲染其他几何体,如线条、平面、立方体、轴等。
    用于可视化辅助线、坐标轴等结构,如下表。
图元示例函数
坐标轴addCoordinateSystem()
线段addLine()
球体addSphere()
平面addPlane()
多边形addPolygon()

  1. 交互支持:允许用户通过鼠标操作进行旋转、缩放、平移等交互。
  • 鼠标点选:registerPointPickingCallback
  • 框选:registerAreaPickingCallback
  • 键盘事件:registerKeyboardCallback
  • 鼠标移动/点击事件:通过 VTK 扩展实现(需继承 vtkInteractorStyle
  • 摄像机视角控制
viewer->setCameraPosition(
    0, 0, -3,    // 相机位置
    0, 0, 0,     // 视点中心
    0, -1, 0);   // 相机“上”方向
  • 点选拾取(交互功能)
viewer->registerPointPickingCallback(
    [](const pcl::visualization::PointPickingEvent& event, void*) {
        float x, y, z;
        event.getPoint(x, y, z);
        std::cout << "Picked point: " << x << ", " << y << ", " << z << std::endl;
    });
  1. 支持颜色和样式设置:可以设置点云的颜色、大小以及其它可视化样式。设置点云渲染属性示例如下:
viewer->setPointCloudRenderingProperties(
    pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud_id");
viewer->setPointCloudRenderingProperties(
    pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.0, 0.0, "cloud_id"); // RGB
  1. 多窗口支持PCLVisualizer 可以在同一个窗口中显示多个视图(例如多个视角)。
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
viewer->addPointCloud(cloud1, "cloud1", v1);
viewer->addPointCloud(cloud2, "cloud2", v2);
  1. 保存截图
viewer->saveScreenshot("screenshot.png");

2、 PCLVisualizer 主要方法介绍

1. 初始化和设置
  • 构造函数PCLVisualizer 构造函数用于创建一个可视化器实例。
    pcl::visualization::PCLVisualizer::Ptr viewer (new pcl::visualization::PCLVisualizer ("PCL Viewer"));
    
2. 添加点云
  • addPointCloud:将点云数据添加到可视化器。

    viewer->addPointCloud(cloud, "cloud");
    
    • 第一个参数是点云数据(例如 pcl::PointCloud<pcl::PointXYZ>::Ptr)。
    • 第二个参数是点云的标识符,用于在可视化器中区分不同的点云。
  • setPointCloudRenderingProperties:设置点云的渲染属性(例如点的大小、颜色等)。

    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud");
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0.0, 1.0, 0.0, "cloud");  // 设置颜色为绿色
    
3. 添加几何体
  • addLine:添加一条直线。

    viewer->addLine<pcl::PointXYZ>(start_point, end_point, "line");
    
  • addCube:添加一个立方体。

    viewer->addCube(min_point, max_point, "cube");
    
  • addText:添加文本标注。

    viewer->addText("Point Cloud", 10, 10, "text");
    
4. 交互功能
  • spin:启动可视化器并开始交互模式,用户可以使用鼠标进行旋转、缩放等操作。

    viewer->spin();
    
  • spinOnce:在没有用户交互时更新可视化器,这通常用于需要不断更新显示内容的应用场景。

    viewer->spinOnce();
    
5. 视角设置
  • resetCamera:重置视角,使得点云能够自适应显示。

    viewer->resetCamera();
    
  • setCameraPosition:设置视角的位置、方向和上下方向。

    viewer->setCameraPosition(0, 0, -10, 0, -1, 0);
    
6. 窗口管理
  • createViewPort:创建一个新的视口,支持多个视图窗口。
    int vp1, vp2;
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp1); // 第一个视口
    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp2); // 第二个视口
    

示例代码:使用 PCLVisualizer 显示点云综合示例

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <iostream>

// 点云类型定义
using PointT = pcl::PointXYZ;
using PointCloudT = pcl::PointCloud<PointT>;

int main(int argc, char** argv) {
    // 创建指针和点云实例
    PointCloudT::Ptr cloud(new PointCloudT);

    // 读取点云文件(PCD格式)
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << " <pcd-file>" << std::endl;
        return -1;
    }
    if (pcl::io::loadPCDFile<PointT>(argv[1], *cloud) == -1) {
        PCL_ERROR("Couldn't read PCD file\n");
        return -1;
    }
    std::cout << "Loaded " << cloud->size() << " points from " << argv[1] << std::endl;

    // 创建PCLVisualizer指针,窗口标题为"3D Viewer"
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));

    // 设置背景颜色(黑色)
    viewer->setBackgroundColor(0, 0, 0);

    // 添加点云到视图,点云标识符为"sample cloud"
    viewer->addPointCloud<PointT>(cloud, "sample cloud");

    // 设置点云渲染属性:点大小为2
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud");

    // 添加坐标系,坐标系大小为1.0
    viewer->addCoordinateSystem(1.0);

    // 初始化相机参数
    viewer->initCameraParameters();

    // 注册键盘事件回调,按下 'q' 键时关闭窗口
    viewer->registerKeyboardCallback(
        [&](const pcl::visualization::KeyboardEvent& event, void*) {
            if (event.keyDown() && event.getKeySym() == "q") {
                std::cout << "Q pressed. Exiting..." << std::endl;
                viewer->close();
            }
        });

    // 注册点选拾取回调,点击点云打印坐标
    viewer->registerPointPickingCallback(
        [&](const pcl::visualization::PointPickingEvent& event, void*) {
            float x, y, z;
            if (event.getPoint(x, y, z)) {
                std::cout << "Picked point coordinates: (" << x << ", " << y << ", " << z << ")" << std::endl;
            }
        });

    // 主渲染循环,直到关闭窗口
    while (!viewer->wasStopped()) {
        viewer->spinOnce(100);
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    return 0;
}

结果展示:
在这里插入图片描述

代码解析
  1. 创建一个点云对象 cloud,并给它填充一些简单的点。
  2. 使用 PCLVisualizer 创建一个可视化器实例。
  3. 使用 addPointCloud 将点云添加到可视化器中,显示的点云标识符是 "cloud"
  4. 使用 setPointCloudRenderingProperties 设置点云的点大小和颜色。
  5. 使用 spin 启动可视化,并允许用户进行交互。
常见问题和注意事项
  1. 性能问题:当点云非常大时,渲染速度可能会受到影响,尤其是在处理数百万点时。可以通过简化点云或使用点云下采样技术来提高性能。
  2. 多个视口:可以使用 createViewPort 来创建多个视口,并在同一个窗口中显示不同的点云视图。
  3. 交互功能spin 是一个阻塞函数,会一直等待用户的交互。如果需要非阻塞模式,可以使用 spinOnce 来轮询更新可视化。
  4. 颜色和样式设置:除了 setPointCloudRenderingProperties,还可以为其他几何对象(如线条、立方体)设置样式,具体取决于应用需求。

3、PCLVisualizer 类中与 **VTK 交互器(Interactor)的成员函数和变量

PCLVisualizer 类中,与 VTK 交互器(Interactor) 相关的成员函数和变量主要用于实现 交互控制,比如点云的旋转、缩放、拾取等操作。这些接口是 PCL 点云库封装了 VTK 的关键部分,但是PCL点云库允许开发者使用 VTK 直接操作底层,这部分内容我们会在Qt+PCL+VTK联合开发中就会应用到,因此了解此部分相关内容是非常有必要。


1、关键背景

在 PCL 中,PCLVisualizer 是基于 VTK 封装的 3D 可视化类,其背后使用了:

  • vtkRenderWindow:显示渲染图像。
  • vtkRenderWindowInteractor:处理用户输入(鼠标/键盘)。
  • vtkInteractorStyle / PCLVisualizerInteractorStyle:定义用户交互行为,如旋转/拾取等。

2、成员函数详解(与 Interactor 相关)
1. createInteractor()
void createInteractor();
  • 作用:内部创建一个 vtkRenderWindowInteractor 实例(智能指针 interactor_)。
  • 调用时机:初始化或用户未手动指定交互器时自动调用。

2. setupInteractor(vtkRenderWindowInteractor*, vtkRenderWindow*)
void setupInteractor(vtkRenderWindowInteractor* iren,
                     vtkRenderWindow* win);
  • 作用:为 iren 设置默认的 PCL 交互样式 PCLVisualizerInteractorStyle 并绑定 win
  • 使用场景:快速搭建 PCL 默认交互系统。

3. setupInteractor(vtkRenderWindowInteractor*, vtkRenderWindow*, vtkInteractorStyle*)
void setupInteractor(vtkRenderWindowInteractor* iren,
                     vtkRenderWindow* win,
                     vtkInteractorStyle* style);
  • 作用:允许用户传入自定义的交互样式 style
  • 用途:高级用户自定义操作(如拾取、框选、特殊事件)。

4. getInteractorStyle()
inline vtkSmartPointer<PCLVisualizerInteractorStyle> getInteractorStyle();
  • 作用:获取当前使用的交互样式。
  • 常用场景:手动修改交互行为,例如绑定快捷键、扩展事件处理。

3、成员变量详解
1. interactor_
vtkSmartPointer<vtkRenderWindowInteractor> interactor_;
  • 说明:内部交互器对象,驱动渲染和用户交互。
  • 用途:自动处理用户事件,触发交互样式。

2. style_
vtkSmartPointer<PCLVisualizerInteractorStyle> style_;
  • 说明:PCL 定义的自定义交互样式类,继承自 vtkInteractorStyleTrackballCamera

  • 功能扩展

    • 点云拾取事件处理。
    • 快捷键响应(如 ‘r’ 重置视图)。
    • 鼠标拖动、滚轮等行为定义。

4、常见使用流程(伪代码示意)
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));

// 使用默认交互器
viewer->createInteractor();    // 创建 interactor_
viewer->setupInteractor(viewer->getInteractor(), viewer->getRenderWindow());

// 获取交互样式,自定义行为
auto style = viewer->getInteractorStyle();
style->setKeyboardCallback(...);

5、实战建议
使用目标推荐接口
使用默认交互控制createInteractor() + setupInteractor(...)
自定义鼠标/键盘事件响应getInteractorStyle() 并设置回调
替换为自定义交互风格setupInteractor(..., custom_style)
手动集成 Qt + VTK 控件使用 getRenderWindow() + getInteractor() 绑定到 Qt 容器

4、总结

pcl::visualization::PCLVisualizer 是 PCL 提供的功能强大的点云可视化工具,适用于各种 3D 点云数据展示和交互。它支持点云、几何体的渲染和自定义视角设置,且能够实现交互式操作,非常适合用于科研和开发中对点云数据的展示和分析。


至此完成第11讲的内容,欢迎喜欢朋友的关注订阅!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云SLAM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值