【问题标题】:OpenCV - getting the slider to update its position during video playbackOpenCV - 让滑块在视频播放期间更新其位置
【发布时间】:2011-06-30 04:39:24
【问题描述】:

我学习了“Learning OpenCV”并尝试了一些代码示例/练习。在这段代码 sn-p 中,我想让滑块随着每个视频帧的变化而更新其位置,但由于某种原因它不起作用(图片因以下代码冻结):

#include "cv.h"
#include "highgui.h"

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)
{
    cvNamedWindow("The Tom 'n Jerry Show", CV_WINDOW_AUTOSIZE);
    g_capture = cvCreateFileCapture(argv[1]);
    int frames = (int) cvGetCaptureProperty(
        g_capture, 
        CV_CAP_PROP_FRAME_COUNT
        );

    if (frames != 0)
    {
        cvCreateTrackbar(
            "Position",
            "The Tom 'n Jerry Show",
            &g_slider_position,
            frames,
            onTrackbarSlide
            );
    }

    IplImage* frame;

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

        cvSetTrackbarPos(
            "Position", 
            "The Tom 'n Jerry Show",
            ++g_slider_position
            );

        cvShowImage("The Tom 'n Jerry Show", frame);
        char c = cvWaitKey(33);
        if (c == 27)
            break;
    }

    cvReleaseCapture(&g_capture);
    cvDestroyWindow("The Tom 'n Jerry Show");

    return 0;
}

知道如何让滑块和视频按预期工作吗?

【问题讨论】:

  • 图片是冻结还是整个应用程序冻结?

标签: c++ c video opencv slider


【解决方案1】:
This is the actual working code



// PROGRAM TO ADD A UPDATING TRACKBAR TO A VIDEO

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


int g_slider_position = 0;
CvCapture* video_capture = NULL;

void onTrackbarSlide(int current_frame)
{
    current_frame = g_slider_position;
    cvSetCaptureProperty(video_capture,CV_CAP_PROP_POS_FRAMES,current_frame);
}

int main( int argc, char** argv )
{
    cvNamedWindow( "Video", CV_WINDOW_AUTOSIZE );
    video_capture = cvCreateFileCapture( "Crowdy.avi");
    int no_of_frames = (int) cvGetCaptureProperty(video_capture,CV_CAP_PROP_FRAME_COUNT);
    if( no_of_frames!= 0 ) 
    {
        cvCreateTrackbar("Slider","Video",&g_slider_position,no_of_frames,onTrackbarSlide);
    }

    IplImage* frame;

    while(1) 
    {
        frame = cvQueryFrame( video_capture );
        if( !frame ) break;
        cvShowImage( "Video", frame );
        cvSetTrackbarPos("Slider","Video",++g_slider_position);
        char c = cvWaitKey(33);
        if( c == 27 ) break;
    }
    cvReleaseCapture( &video_capture );
    cvDestroyWindow( "Video" );

    return(0);
}

【讨论】:

    【解决方案2】:

    您在代码中将 g_slider_position 增加了两次,因此它将增加超出其限制(在cvCreateTrackbar 中设置为frames)。这可能会导致您的图片冻结。

    要修复,请更改此设置

        g_slider_position++;
        cvSetTrackbarPos(
            "Position", 
            "The Tom 'n Jerry Show",
            ++g_slider_position
            );
    

        cvSetTrackbarPos(
            "Position", 
            "The Tom 'n Jerry Show",
            ++g_slider_position
            );
    

    考虑到编辑后的代码,我会检查 OpenCV 是否正确地从您的文件中读取帧数。查看学习 OpenCV 的第 2 章,示例 2.3,了解一种从 AVI 中检索帧数的方法(如果您正在使用该方法)。

    在您上面的代码中,如果帧数为 0,则不会创建跟踪栏,但代码仍会进入一个尝试更新跟踪栏位置的循环(如果找到帧)。我会改用这个:

    if (frames != 0)
    {
        cvCreateTrackbar(
            "Position",
            "The Tom 'n Jerry Show",
            &g_slider_position,
            frames,
            onTrackbarSlide
            );
    } 
    else
    {
        exit(1);
    }
    

    【讨论】:

    • 对不起,我实际上错误地引用了我的代码。我要更正的代码没有++g_slider_position; 语句。我已经编辑了上述问题;它给出了与最初描述的相同的问题。
    • @Kristian - 我已经编辑了回复。希望这对现在有所帮助。
    • 谢谢赛斯。尽管您的编辑显然使代码更加健壮,但显然可以正确找到总帧数。不幸的是,问题仍然存在(视频冻结但轨迹栏会正确更新)。顺便说一句,是的,这是一个 avi。
    • @Kristian - 我明白了。我误解了这里冻结的内容。轨迹栏不断自我更新的事实表明您的解码器存在问题。您可以将 avi 文件转换为 raw 并重试吗?可以通过运行'mencoder in.avi -ovc raw -vf format=i420 -o out.avi'来完成转换
    【解决方案3】:

    这对我来说似乎有点复杂。我使用cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES) 调用来检索当前帧并使用它来更新滑块。

    然后使用回调函数来改变 g_capture 中的位置。

    所以回调是:

    //Call back for slider bar
    void onTrackbarSlide(int pos) {
        cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos);
    }
    

    循环是:

    IplImage* frame; //Frame grabbed from video
    while(1) {
        frame = cvQueryFrame( g_capture );
        if (!frame ) break;
        cvShowImage( "Example2", frame );
    
        g_frame_count = (int) cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES);
    
        cvSetTrackbarPos("Position","Example2", g_frame_count);
    
        char c = cvWaitKey(33);
        if ( c == 27 ) break;
    }
    

    g_ 变量是全局变量。

    【讨论】:

      【解决方案4】:

      您可以尝试以下解决方案。

      改变这个

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

      void onTrackbarSlide( int pos )
      {
          if( pos > g_slider_position + 1 )
          cvSetCaptureProperty( 
              g_capture, 
              CV_CAP_PROP_POS_FRAMES, 
              pos);
      }
      

      也改变这个

      cvSetTrackbarPos(
                  "Position", 
                  "The Tom 'n Jerry Show",
                  ++g_slider_position
                  );
      

      cvSetTrackbarPos(
                  "Position", 
                  "The Tom 'n Jerry Show",
                  g_slider_position + 1
                  );
      

      【讨论】:

        【解决方案5】:

        您好,我有类似的代码,我执行了以下操作:

        void onTrackbarSlide(int pos)
        {
        if(pos > g_lastPosition+1 || pos < g_lastPosition)
        cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
        g_lastPosition = pos;
        }
        

        ......

        while(1)
        {
        frame = cvQueryFrame( g_capture );
        if( !frame ) break;
        cvShowImage( "Example3", frame );
        cvSetTrackbarPos("Position", "Example3", g_slider_position+1);
        char c = cvWaitKey(33);
        if( c == 27 ) break;
        }
        

        所以你可以把滑条拉到任何方向,希望对你有帮助

        【讨论】:

          【解决方案6】:

          好的,我终于解决了更新滑块的问题 如果你想移动滑块,视频也会更新 现在已经没有画面卡顿的问题了

          #include "stdafx.h"
          
          #include<cv.h>
          #include<cxcore.h>
          #include<highgui.h>
          
          int g_slider_position = 0;
          CvCapture* g_capture = NULL;
          int count=0;              //initiate a global counter
          
          
          
          void onTrackbarSlide( int pos )
          {// if you are moving the slider for more than two frames then this loop will initiate      to
           // to update the video
              if(pos>count+2 || pos<count-2){
              cvSetCaptureProperty( 
                  g_capture, 
                  CV_CAP_PROP_POS_FRAMES, 
                  pos);}
              count=pos;
          }
          int main(int argc, _TCHAR* argv[])
          {
              //int count=0;
              cvNamedWindow("Example3",CV_WINDOW_AUTOSIZE);
              g_capture=cvCreateFileCapture("video.avi");
              int frames = (int) cvGetCaptureProperty(
                  g_capture,
                  CV_CAP_PROP_FRAME_COUNT
                  );
              if(frames!= 0) {
                  cvCreateTrackbar(
                      "Position",
                      "Example3",
                      &g_slider_position,
                      frames,
                      onTrackbarSlide
                      );
              }
              IplImage* frame;
              while (1)
              {
                  count++;  // the counter will move along with the frame
                  frame = cvQueryFrame( g_capture );
                  if (!frame) break;
                  cvShowImage ("Example3", frame);
                  cvSetTrackbarPos("Position", "Example3", g_slider_position+1);
                  char c = cvWaitKey(33);
                  if(c==27) break;
              }
          
              cvReleaseCapture(&g_capture);
              cvDestroyWindow("Example3");
              return 0;
          }
          

          好的,现在我所做的是我创建了一个全局计数器,它将与框架一起更新

          现在,当我们使用鼠标将滑块移动到不同位置时,在 onTrackbarSlider 例程中,将启动 if 循环并将视频设置到新位置

          【讨论】:

            猜你喜欢
            • 2013-01-07
            • 2013-06-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多