OpenCV - 如果滑块在播放时更新其位置,则视频播放速度很慢

时间:2013-06-21 09:45:13

标签: c opencv video

我已经选择了“学习OpenCV”并尝试了一些代码示例/练习。在此代码段中,我想让滑块在每次视频帧更改时更新其位置,但由于某种原因,它会降低视频播放速度。

滑块在视频播放期间使用 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;
}

3 个答案:

答案 0 :(得分:1)

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

等待(1),每次等待按键需要33毫秒。使这个数字更小。

EDITED LATER:

如下所示进行更改

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

答案 1 :(得分:1)

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

答案 2 :(得分:-1)

问题在于,每当您呼叫cvSetTrackbarPos("Slider","Playing Video With Slider", g_slider_position+1);回调onTrackbarSlide时,再次更改视频位置并减慢程序流程。

我发现避免这种情况的方式是带有旗帜。它告诉回调轨道栏中的更改是由正常更新流程产生的还是由您生成的。

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。