【问题标题】:OpenCV - Video playback is slow if slider updates its position while playingOpenCV - 如果滑块在播放时更新其位置,则视频播放速度很慢
【发布时间】:2013-06-18 09:40:39
【问题描述】:

我已经学习了“Learning OpenCV”并一直在尝试一些代码示例/练习。在这段代码 sn-p 中,我想让滑块随着每个视频帧的变化而更新其位置,但由于某种原因,它会减慢视频播放速度。

在视频播放期间,滑块使用 cvSetTrackbarPos() 函数更新位置,但它使播放速度非常慢。

#include <cv.h>
#include <highgui.h>

using namespace std;

int        g_slider_position = 0;
CvCapture *g_capture         = NULL;

void onTrackbarSlide(int pos)
{
  cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
}

int main(int argc, char *argv[])
{
  if(argc<2)
  {
    printf("Usage: main <video-file-name>\n\7");
    exit(0);
  }

  // create a window
  cvNamedWindow("Playing Video With Slider", CV_WINDOW_AUTOSIZE); 

  g_capture = cvCreateFileCapture(argv[1]);

  int frames = (int) cvGetCaptureProperty(g_capture, \
      CV_CAP_PROP_FRAME_COUNT);

  if(frames !=0)
  {
    cvCreateTrackbar("Slider","Playing Video With Slider", \
        &g_slider_position,frames, onTrackbarSlide);
  }

  IplImage* frame = 0; 

  while(1)
  {
    frame = cvQueryFrame(g_capture);
    if(!frame)
    {
      break;
    }

    cvShowImage("Playing Video With Slider", frame);

    cvSetTrackbarPos("Slider","Playing Video With Slider", \
        g_slider_position+1);  //Slowing down playback

    char c= cvWaitKey(33);

    if(c == 27)
    {
      break;
    }
  }

  // release the image
  cvReleaseImage(&frame );
  cvReleaseCapture(&g_capture);

  // Destroy Window
  cvDestroyWindow("Playing Video With Slider");

  return 0;
}

【问题讨论】:

    标签: c opencv video


    【解决方案1】:

    这是 opencv 显示轨迹栏的效率低下(即使您不更新滑块也会出现同样的问题,并且如果您在处理循环之外引用不变的变量)。 一种解决方法可能是在单独的窗口中显示跟踪栏。

    【讨论】:

      【解决方案2】:

      问题是每次你调用cvSetTrackbarPos("Slider","Playing Video With Slider", g_slider_position+1);回调onTrackbarSlide时都会改变视频位置,拖慢程序流程。

      我发现避免这种情况的方法是使用标志。它告诉回调 Trackbar 中的更改是由正常更新流程产生还是由 You 产生。

      int g_slider_position = 0;
      int g_update_slider = 0;//flag
      CvCapture *g_capture = NULL;
      
      void onTrackbarSlide(int pos)
      {
          if (!g_update_slider)//if not changed by the video flow
          {
              cvSetCaptureProperty(
                  g_capture,
                  CV_CAP_PROP_POS_FRAMES,
                  pos
                  );
          }
      }
      
      void updateSlider(int pos)
      {
          g_update_slider = 1; //Changed by the video flow
          cvSetTrackbarPos("Position", "Example3", pos);
          g_update_slider = 0; //Returns the flag when the change is performed
      }
      

      我主要调用 updateSlider 而不是 cvSetTrackbarPos。

      【讨论】:

        【解决方案3】:

        char c= cvWaitKey(33); 行有问题。

        它在 while(1) 中,每次等待按下的键需要 33 毫秒。使这个数字更小。

        EDITED LATER:
        

        如下图进行修改

        void onTrackbarSlide(int pos)
        {
          pos = g_slider_position;
          cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
        }
        

        【讨论】:

        • char c= cvWaitKey(33); 完全可以。因为我的视频是以 30 fps 的速度拍摄的。问题出在以下行:cvSetTrackbarPos("Slider","Playing Video With Slider", g_slider_position+1); 但我不知道确切的问题。
        • @Vivekan 然后也许你需要设置 pos 值。我已经编辑了我的答案以显示所需的功能更改。
        • 我认为你没有得到我的问题。 onTrackbarSlide(int pos) 与视频播放速度无关。它只是一个与trackbar关联的回调函数,会被自动调用。我的问题是cvSetTrackbarPos(),它降低了视频播放速度。不知道为什么?
        猜你喜欢
        • 2013-01-07
        • 2011-06-30
        • 1970-01-01
        • 2014-02-07
        • 2017-09-15
        • 2018-08-28
        • 1970-01-01
        • 2011-01-29
        相关资源
        最近更新 更多