PCL 渲染显示
PCL (Point Cloud Library) 提供了强大的点云渲染和可视化功能,主要通过 pcl::visualization
模块实现。
渲染类
类名 | 描述 | 头文件 |
---|---|---|
pcl::visualization::PCLVisualizer | 主要的可视化类,用于显示点云和其他3D数据 | <pcl/visualization/pcl_visualizer.h> |
pcl::visualization::PointCloudColorHandler | 点云颜色处理基类 | <pcl/visualization/point_cloud_color_handlers.h> |
pcl::visualization::PointCloudGeometryHandler | 点云几何处理基类 | <pcl/visualization/point_cloud_geometry_handlers.h> |
PCLVisualizer 主要方法
方法 | 描述 |
---|---|
addPointCloud() | 添加点云到可视化窗口 |
setPointCloudRenderingProperties() | 设置点云渲染属性 |
spinOnce() | 单次刷新显示 |
spin() | 进入显示循环 |
removePointCloud() | 移除点云 |
addCoordinateSystem() | 添加坐标系 |
addLine() | 添加线段 |
addSphere() | 添加球体 |
addText() | 添加文本 |
addPolygon() | 添加多边形 |
saveScreenshot() | 保存屏幕截图 |
渲染属性常量
属性 | 描述 |
---|---|
pcl::visualization::RenderingProperties::POINT_SIZE | 点大小 |
pcl::visualization::RenderingProperties::OPACITY | 不透明度 |
pcl::visualization::RenderingProperties::LINE_WIDTH | 线宽 |
pcl::visualization::RenderingProperties::REPRESENTATION | 表示方式(点/线/面) |
pcl::visualization::RenderingProperties::IMMEDIATE_RENDERING | 立即渲染标志 |
颜色处理器常用子类
类名 | 描述 |
---|---|
PointCloudColorHandlerCustom | 自定义颜色 |
PointCloudColorHandlerGenericField | 根据字段值着色 |
PointCloudColorHandlerRGBField | 使用RGB字段 |
PointCloudColorHandlerLabelField | 根据标签字段着色 |
相机相关方法
方法 | 描述 |
---|---|
setCameraPosition() | 设置相机位置和视角 |
getCameraParameters() | 获取当前相机参数 |
setCameraClipDistances() | 设置剪裁平面距离 |
resetCamera() | 重置相机到自动计算的最佳位置 |
resetCameraViewpoint() | 重置相机到默认视角 |
saveCameraParameters() | 保存相机参数到文件 |
loadCameraParameters() | 从文件加载相机参数 |
光照设置与渲染
光照属性常量
属性 | 描述 |
---|---|
pcl::visualization::RenderingProperties::AMBIENT | 环境光强度 |
pcl::visualization::RenderingProperties::DIFFUSE | 漫反射强度 |
pcl::visualization::RenderingProperties::SPECULAR | 镜面反射强度 |
pcl::visualization::RenderingProperties::SHADING | 着色模式 |
光照相关方法
方法 | 描述 |
---|---|
setLightingProperties() | 设置光照属性 |
setLightPosition() | 设置光源位置 |
setShapeRenderingProperties() | 设置形状的光照属性 |
setRepresentationToSurface() | 将表示方式设置为表面(启用光照) |
基本使用示例
cpp
#include <pcl/visualization/pcl_visualizer.h>// 创建可视化对象
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));// 添加点云
viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud");// 设置渲染属性
viewer->setPointCloudRenderingProperties(pcl::visualization::RenderingProperties::POINT_SIZE, 3, "sample cloud");// 添加坐标系
viewer->addCoordinateSystem(1.0);// 进入显示循环
while (!viewer->wasStopped()) {viewer->spinOnce(100);
}
完整示例
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>int main()
{// 创建一个点云对象pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);// 生成简单的点云数据(一个平面上的点)cloud->width = 100; // 点云宽度(点数)cloud->height = 1; // 无序点云设为1cloud->points.resize(cloud->width * cloud->height);// 填充点云数据 - 创建一个简单的平面for (size_t i = 0; i < cloud->points.size(); ++i){cloud->points[i].x = 0.1f * (i % 10);cloud->points[i].y = 0.1f * (i / 10);cloud->points[i].z = 0.5f;}// 可选:保存点云到文件pcl::io::savePCDFileASCII("test_pcd.pcd", *cloud);std::cerr << "Saved " << cloud->points.size() << " data points to test_pcd.pcd." << std::endl;// 打印前5个点for (size_t i = 0; i < 5; ++i)std::cerr << " " << cloud->points[i].x << " " << cloud->points[i].y << " " << cloud->points[i].z << std::endl;// 创建可视化对象并显示pcl::visualization::CloudViewer viewer("Simple Cloud Viewer");viewer.showCloud(cloud);// 保持可视化窗口打开while (!viewer.wasStopped()){// 可以在这里添加其他处理代码(例如:更新点云、处理键盘事件等)//比如:动态更新点云static int counter = 0;if (counter++ % 100 == 0){for (auto& point : cloud->points){point.z += 0.01f; // 所有点上移}viewer.showCloud(cloud); // 更新显示}// 短暂休眠以避免占用太多CPUboost::this_thread::sleep(boost::posix_time::microseconds(10000));}return 0;
}
高级渲染特性
-
多视口渲染:
cpp
// 创建多视口可视化 pcl::visualization::PCLVisualizer viewer("Multi-viewport");// 设置视口布局 int v1(0), v2(1); 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);// 设置不同视口的背景色 viewer.setBackgroundColor(0, 0, 0, v1); viewer.setBackgroundColor(0.5, 0.5, 0.5, v2);
-
自定义着色:
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color_handler(cloud, 255, 0, 0); viewer->addPointCloud(cloud, color_handler, "colored cloud");
-
相机参数设置:
#include <pcl/visualization/pcl_visualizer.h>int main() {pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));// 添加点云viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud");// 设置相机位置和视角viewer->setCameraPosition(0.0, 0.0, -3.0, // 相机位置(x,y,z)0.0, 0.0, 1.0, // 相机看向的点0.0, -1.0, 0.0); // 相机的"上"方向// 设置剪裁平面(近平面和远平面)viewer->setCameraClipDistances(0.1, 10.0);// 获取当前相机参数pcl::visualization::Camera camera;viewer->getCameraParameters(camera);std::cout << "Camera position: " << camera.pos[0] << ", " << camera.pos[1] << ", " << camera.pos[2] << std::endl;while (!viewer->wasStopped()) {viewer->spinOnce(100);}return 0; }
// 保存相机参数到文件 viewer->saveCameraParameters("camera_params.cam"); // 从文件加载相机参数 viewer->loadCameraParameters("camera_params.cam");//多视口相机控制 // 创建两个视口 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);// 为不同视口设置不同相机 viewer->setCameraPosition(0,0,-5, 0,0,1, 0,-1,0, vp1); // 正面视角 viewer->setCameraPosition(-5,0,0, 0,0,0, 0,-1,0, vp2); // 侧面视角//交互式相机控制 // 注册键盘回调函数 void keyboardEventOccurred(const pcl::visualization::KeyboardEvent &event, void* viewer_void) {if (event.getKeySym() == "r" && event.keyDown()) {std::cout << "r was pressed => reset camera" << std::endl;viewer->resetCamera();} }// 主函数中注册回调 viewer->registerKeyboardCallback(keyboardEventOccurred, (void*)&viewer);
-
光照
#include <pcl/visualization/pcl_visualizer.h>// 创建可视化对象 pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));// 添加点云 viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud");// 启用光照效果 viewer->setShapeRenderingProperties(pcl::visualization::RenderingProperties::SHADING, pcl::visualization::RenderingProperties::PHONG, "sample cloud");// 设置光源位置 (x, y, z, w) viewer->setLightPosition(1.0, 1.0, 1.0, 0.0);// 设置光照属性 viewer->setLightingProperties(0.3, // 环境光强度0.7, // 漫反射强度0.2, // 镜面反射强度50.0); // 镜面反射高光指数// 进入显示循环 while (!viewer->wasStopped()) {viewer->spinOnce(100); }
//多光源设置 // 添加多个光源 viewer->addLight(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, "light1"); viewer->addLight(-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, "light2");//材质属性设置 // 设置球体的材质属性 viewer->addSphere(pcl::PointXYZ(0,0,0), 0.1, "sphere"); viewer->setShapeRenderingProperties(pcl::visualization::RenderingProperties::AMBIENT, 0.5, "sphere"); viewer->setShapeRenderingProperties(pcl::visualization::RenderingProperties::DIFFUSE, 0.7, "sphere");//着色模式选择 // 设置不同的着色模式 viewer->setShapeRenderingProperties(pcl::visualization::RenderingProperties::SHADING, pcl::visualization::RenderingProperties::FLAT, "object"); // 或 viewer->setShapeRenderingProperties(pcl::visualization::RenderingProperties::SHADING, pcl::visualization::RenderingProperties::GOURAUD, "object"); // 或 viewer->setShapeRenderingProperties(pcl::visualization::RenderingProperties::SHADING, pcl::visualization::RenderingProperties::PHONG, "object");
-
显示法线
// 计算点云法线 pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>); // ... 计算法线 ...// 添加法线到可视化 viewer.addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 10, 0.05, "normals");
-
颜色点云显示
// 1. 使用自定义颜色 pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 255, 0); // RGB绿色// 2. 根据Z值着色 pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> z_color(cloud, "z"); // 使用z字段值// 3. 使用RGB字段 pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb_color(cloud);// 添加带颜色处理的点云 viewer->addPointCloud(cloud, rgb_color, "colored_cloud");
-
几何元素叠加
// 添加坐标系 (尺寸, ID, 视口) viewer->addCoordinateSystem(1.0, "global", 0);// 添加线段 (点1, 点2, R,G,B, ID, 视口) viewer->addLine<pcl::PointXYZ>(p1, p2, 1.0, 0.0, 0.0, "line1");// 添加球体 (中心, 半径, R,G,B, ID, 视口) viewer->addSphere(center, 0.1, 0.5, 0.5, 0.0, "sphere1");// 添加文本 (内容, x,y, 字体大小, R,G,B, ID, 视口) viewer->addText("Sample Text", 10, 10, 16, 1.0, 1.0, 1.0, "text1");
-
交互控制
// 键盘回调函数 void keyboardEventOccurred(const pcl::visualization::KeyboardEvent &event, void* viewer_void) {if (event.getKeySym() == "s" && event.keyDown()) {std::cout << "s pressed - saving screenshot" << std::endl;viewer->saveScreenshot("screenshot.png");} }// 鼠标回调函数 void mouseEventOccurred(const pcl::visualization::MouseEvent &event, void* viewer_void) {if (event.getType() == pcl::visualization::MouseEvent::MouseButtonPress && event.getButton() == pcl::visualization::MouseEvent::LeftButton) {std::cout << "Left mouse button pressed at (" << event.getX() << ", " << event.getY() << ")" << std::endl;} }// 创建可视化对象pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));// 设置背景色 (默认为黑色)viewer->setBackgroundColor(0.05, 0.05, 0.05);// 添加点云viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud");// 设置点云渲染属性viewer->setPointCloudRenderingProperties(pcl::visualization::RenderingProperties::POINT_SIZE, 2, "sample cloud");// 注册回调 viewer->registerKeyboardCallback(keyboardEventOccurred); viewer->registerMouseCallback(mouseEventOccurred);// 进入渲染循环while (!viewer->wasStopped()) {viewer->spinOnce(100);std::this_thread::sleep_for(std::chrono::milliseconds(100));}