-1

我已经学习了“Learning 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;
}
4

3 回答 3

2

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

于 2015-07-13T18:43:37.587 回答
1

线路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);
}
于 2013-06-21T09:56:15.383 回答
-1

问题是每次您调用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。

于 2015-04-12T21:27:04.247 回答