> 技术文档 > 5.PCL 点云可视化,交互

5.PCL 点云可视化,交互


文章目录

  • 可视化
    • 简单可视化
    • 高级可视化
    • 显示的方法
    • 法向显示
    • 显示形状
  • 多窗口
  • 键盘鼠标交互

可视化

简单可视化

pcl::visualization::CloudViewer viewer(\"Cloud Viewer\"); // 创建viewer对象viewer.showCloud(cloud);

高级可视化

使用 PCLVisualizer

pcl::visualization::PCLVisualizer viewer(\"3D View\"); // 创建视窗对象或者增加显示一个点云,并提供唯一的标志(标识ID)(string格式)viewer.addPointCloud<pcl::PointXYZ>(cloud, \"sample cloud\"); // cloud是指针,//1. 更新点云,使用updatePointCloud()函数viewer.setBackgroundColor(100, 100, 100); // 设置背景颜色,默认黑色viewer.addPointCloud(cloud1, \"cloud1\"); // \"cloud1\"为显示id,默认cloud,显示多个点云时用默认会报警告。

设置点云颜色

pcl::visualization::PointCloudColorHandlerCustom<PointT> red(cloud2, 255, 0, 0); // rgbviewer.addPointCloud(cloud2, red, \"cloud2\");

显示网格数据

viewer.addPolygonMesh(mesh);

显示文本

viewer.addText(string, position.x of screen, position.y of screen, ID=default(\"Text\"), viewportID=default(0));

可视化线程调用一次

viewer.runOnVisualizationThreadOnce(sub/function); // 参数是一个sub或者function,表示该函数在可视化时仅调用一次

在可视化线程中持续调用

viewer.runOnVisualizationThread(sub/function); // 可视化时每次都调用,可用来显示text

显示的方法

阻塞

viewer.spin();

非阻塞

while (!viewer.wasStopped()){ viewer.spinOnce(100); boost::this_thread::sleep(boost::posix_time::microseconds(100000));}
viewer.wasStopped(): 检查用户是否已经关闭了可视化窗口。viewer.spinOnce(100): 执行一次可视化更新,并等待100毫秒。这个函数是非阻塞的,允许在可视化的同时执行其他任务。boost::this_thread::sleep(): 让当前线程暂停一段时间,这里设置为100000微秒(即100毫秒)。这有助于控制循环的频率,避免过度占用CPU资源。

法向显示

viewer.addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal>(cloud, normals, 10, 0.05, \"normals\");viewer.addPointCloudNormals(): 这个函数用于在可视化窗口中显示点云的法向量。cloud: 点云数据,类型为pcl::PointXYZRGB。normals: 点云对应的法向量数据。10:10个点显示一条法线。0.05: 每条法线的长度。\"normals\": 法线对象的标识符。

显示形状

添加线

viewer.addLine<pcl::PointXYZRGB>(cloud->points[0], cloud->points[cloud->size() - 1], \"line\"); viewer.addLine(): 这个函数用于在可视化窗口中添加一条线段。 cloud->points[0]: 线段的起点,取自点云的第一个点。 cloud->points[cloud->size() - 1]: 线段的终点,取自点云的最后一个点。 \"line\": 线段的标识符。

添加球体

viewer.addSphere(cloud->points[0], 0.2, 0.5, 0.5, 0.0, \"sphere\"); viewer.addSphere(): 这个函数用于在可视化窗口中添加一个球体。 cloud->points[0]: 球体的中心位置,取自点云的第一个点。 0.2: 球体的半径。 0.5, 0.5, 0.0: 球体的颜色,以RGB值表示。 \"sphere\": 球体的标识符。

添加平面

pcl::ModelCoefficients coeffs;coeffs.values.push_back(0.0);coeffs.values.push_back(0.0);coeffs.values.push_back(1.0);coeffs.values.push_back(0.0);viewer.addPlane(coeffs, \"plane\"); pcl::ModelCoefficients coeffs: 创建一个模型系数对象,用于定义平面的方程。 coeffs.values.push_back(0.0); coeffs.values.push_back(0.0); coeffs.values.push_back(1.0); coeffs.values.push_back(0.0);: 设置平面方程的系数。这里设置的是z = 0的平面,即原点中心,z轴方向的平面。 viewer.addPlane(): 这个函数用于在可视化窗口中添加一个平面。 coeffs: 平面的模型系数。 \"plane\": 平面的标识符。

多窗口

// 第一个窗口int v1 = 0;viewer.createViewPort(0, 0, 0.5, 1, v1); // Xmin, Ymin, Xmax, Ymax, view_IDviewer.setBackgroundColor(0, 0, 0, v1); // R, G, B, view_IDviewer.addText(\"TEXT 内容\", 10, 10, \"v1text\", v1); // 文字内容,position.x, position.y, text_ID, view_IDpcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgb, \"sample cloud1\", v1);// 第二个窗口int v2(1);viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);viewer.setBackgroundColor(0.3, 0.3, 0.3, v2);viewer.addText(\"Radius: 0.1\", 10, 10, \"v2 text\", v2);pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZRGB> single_color(cloud, 0, 255, 0);viewer.addPointCloud<pcl::PointXYZRGB>(cloud, single_color, \"sample cloud2\", v2);

键盘鼠标交互

键盘交互

viewer->registerKeyboardCallback(keyboardEventOccurred, (void*)&viewer);
viewer->registerKeyboardCallback(): 这个函数用于注册一个键盘事件回调函数。 keyboardEventOccurred: 回调函数名,当键盘事件发生时会被调用。 (void*)&viewer: 将viewer对象的指针传递给回调函数,以便在回调函数中访问viewer对象。

回调函数定义

void keyboardEventOccurred(const pcl::visualization::KeyboardEvent &event, void* viewer_void){ boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer>*>(viewer_void); if (event.getKeySym() == \"r\" && event.keyDown()) { // 响应的内容 }}
const pcl::visualization::KeyboardEvent &event: 回调函数的第一个参数是一个常量引用,表示发生的键盘事件。void* viewer_void: 回调函数的第二个参数是一个指向viewer对象的指针。boost::shared_ptr viewer = *static_cast<boost::shared_ptr*>(viewer_void);: 将传入的void*指针转换为boost::shared_ptr类型,并解引用得到viewer对象。if (event.getKeySym() == \"r\" && event.keyDown()): 检查是否按下“r”键。 event.getKeySym(): 获取按键的符号。 event.keyDown(): 检查按键是否被按下。

鼠标交互

viewer->registerMouseCallback(mouseEventOccurred, (void*)&viewer);
viewer->registerMouseCallback(): 这个函数用于注册一个鼠标事件回调函数。 mouseEventOccurred: 回调函数名,当鼠标事件发生时会被调用。 (void*)&viewer: 将viewer对象的指针传递给回调函数,以便在回调函数中访问viewer对象。

回调函数定义

void mouseEventOccurred(const pcl::visualization::MouseEvent &event, void* viewer_void){ boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer>*>(viewer_void); if (event.getButton() == pcl::visualization::MouseEvent::LeftButton && event.getType() == pcl::visualization::MouseEvent::MouseButtonRelease) { // 响应的内容 }}
const pcl::visualization::MouseEvent &event: 回调函数的第一个参数是一个常量引用,表示发生的鼠标事件。void* viewer_void: 回调函数的第二个参数是一个指向viewer对象的指针。boost::shared_ptr viewer = *static_cast<boost::shared_ptr*>(viewer_void);: 将传入的void*指针转换为boost::shared_ptr类型,并解引用得到viewer对象。if (event.getButton() == pcl::visualization::MouseEvent::LeftButton && event.getType() == pcl::visualization::MouseEvent::MouseButtonRelease): 检查是否释放了左键。 event.getButton(): 获取按下的鼠标按钮。 event.getType(): 获取鼠标事件的类型