这就是问题所在。我有一个点云指针向量,我想一次可视化一个。我所拥有的是一个可视化器,它查看向量中的第一个点并等待键盘输入来改变可视化的内容。例如,“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);
}
}