为啥循环和可视化点云滞后于 PCL 可视化器?

Posted

技术标签:

【中文标题】为啥循环和可视化点云滞后于 PCL 可视化器?【英文标题】:Why does looping through and visualizing point clouds lag the PCL visualizer?为什么循环和可视化点云滞后于 PCL 可视化器? 【发布时间】:2021-07-14 22:46:09 【问题描述】:

这就是问题所在。我有一个点云指针向量,我想一次可视化一个。我所拥有的是一个可视化器,它查看向量中的第一个点并等待键盘输入来改变可视化的内容。例如,“n”将为可视化器提供向量中的下一个元素,“b”将为您提供前一个元素。

//n moves to the next frame
    if(event.getKeySym () == "n" && event.keyDown ())
        moveForward();
    

    //b goes back a frame
    if(event.getKeySym () == "b" && event.keyDown ())
        if (current_spot > 0)
            newCloud(--current_spot); 
            viewer->updateText("Frame: " + std::to_string(--current_frame), TEXT_X, TEXT_FRAME_Y, "fileNum");
        
    

这使您可以在阵列中来回移动并查看点云的某些帧。这很好用,但是我还有另一个键,'m',它可以像视频一样播放帧。它通过创建一个 while 循环并在其中实现这一点,向前移动帧,更新可视化器,并休眠以支持帧速率。

//m plays all point clouds from current frame
    if(event.getKeySym () == "m" && event.keyUp ())
        play = true;
        while(moveForward() && play)  
            viewer->spinOnce(10);
            std::this_thread::sleep_for(std::chrono::milliseconds(22));
        
    

这里是 moveForward() 和 newCloud() 函数:

bool moveForward()
    if(current_spot < BUFFER_LIMIT || (PC_Done && current_spot < DEQUE_SIZE - 1))
        newCloud(++current_spot);
        viewer->updateText("Frame: " + std::to_string(++current_frame), TEXT_X, TEXT_FRAME_Y, "fileNum");
        return true;
    else if(current_spot == BUFFER_LIMIT)
        clouds.pop_front();
        signalPC.notify_one();
        newCloud(current_spot);
        viewer->updateText("Frame: " + std::to_string(++current_frame), TEXT_X, TEXT_FRAME_Y, "fileNum");
        return true;
    
    return false;


void newCloud(int spot)
    viewer->removePointCloud("cloud");
    viewer->addPointCloud(clouds[spot]);
    viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud");


这在到达终点或过早停止后按预期工作,可视化器滞后于所有其他输入以移动相机或帧,更糟糕的是,它会堆叠。您点击“m”的动作,可视化器滞后的次数越多。奇怪的是,按住 'n' 前进并不会破坏任何东西,而使用 'm' 会。任何人都知道为什么这个杀戮表现如此之好?

更新

事实证明,可视化器的整体滞后源于自旋循环。我正在使用 spinOnce(x) 然后休眠,这有点多余,并且似乎延迟了输入,因为它正在休眠并存储输入,从而导致粘性输入。我摆脱了睡眠并将 spinOnce(x) 更改为 spin() ,这使输入更加平滑。然而,这并没有完全解决视频播放功能。我仍然需要在该循环中使用 spinOnce() 以便 1. 在每个新帧之后实际更新可视化器和 2. 模拟帧速率。这会导致一些奇怪的效果。使用一次电影功能会显着减慢一切,但是它在停止后不会堆叠,实际上它会相反。再次按下“m”键将使一切恢复正常并以适当的速率播放视频并停止它将使可视化器处于最佳状态。这会来回走,很奇怪。所以我会努力解决这个问题。如果您有任何想法,请告诉我。谢谢!

这里还有新的“m”按功能:

//m plays all point clouds from current frame
    if(event.getKeySym () == "m" && event.keyUp ())
        play = true;
        while(moveForward() && play)  
            viewer->spinOnce(33);
        
    

【问题讨论】:

【参考方案1】:

想通了...所以事实证明 m 键绑定到 vtk 中的某些东西。我查看了pcl source code,但找不到任何绑定到 m 的功能,所以我不知道为什么 m 键专门减慢了可视化器的速度。我只是将我的键绑定从 m 上移开,现在它可以完美运行了。不过,按 m 似乎仍然会造成不良影响,对此一无所知。我知道这是一个小众问题,但我希望有人能从中受益,或者也许,只是也许,这可以帮助某人。

【讨论】:

以上是关于为啥循环和可视化点云滞后于 PCL 可视化器?的主要内容,如果未能解决你的问题,请参考以下文章

PCL:CloudViewer 简单点云可视化

PCL点云处理:计算点云法向量并可视化

PCL:Visualizer 可视化❤️自定义颜色显示

学习PCL库:基于LOD的大规模点云可视化

ROS 可视化: 发布PointCloud2点云数据到Rviz

qt可视化教程点云不出现