5.PCL 点云可视化,交互

发布于:2025-07-25 ⋅ 阅读:(17) ⋅ 点赞:(0)

可视化

简单可视化

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); // rgb
viewer.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_ID
viewer.setBackgroundColor(0, 0, 0, v1); // R, G, B, view_ID
viewer.addText("TEXT 内容", 10, 10, "v1text", v1); // 文字内容,position.x, position.y, text_ID, view_ID
pcl::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<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer>*>(viewer_void);: 将传入的void*指针转换为boost::shared_ptr<pcl::visualization::PCLVisualizer>类型,并解引用得到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<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer>*>(viewer_void);: 将传入的void*指针转换为boost::shared_ptr<pcl::visualization::PCLVisualizer>类型,并解引用得到viewer对象。
if (event.getButton() == pcl::visualization::MouseEvent::LeftButton && event.getType() == pcl::visualization::MouseEvent::MouseButtonRelease): 检查是否释放了左键。
    event.getButton(): 获取按下的鼠标按钮。
    event.getType(): 获取鼠标事件的类型

网站公告

今日签到

点亮在社区的每一天
去签到