opencv中cvSetCaptureProperty定位不准的原因及解决(转载)

以前在opencv2.0里面用到cvSetCaptureProperty函数的时候总是发生定位不准确的问题,明明是让其跳到100帧,结果却总不是100帧,定位一段连续的视频,总是出现跳跃的现象。同样的代码在opencv1.0里面完全没错。可是这是为什么?这个问题一直困扰了我半年,终于在今天知道原因了。

经过差不多一晚上的探究,得出粗略的结论。原因在于opencv2.0以后,采用ffmpeg采集视频,而在opencv1.0采用vfw采集视频(具体的概念暂时还不清楚,有时间继续补上)。而opencv在定位时候,调用的ffmpeg的av_seek_frame()函数,此函数原型为:

int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags);

其中,最后一个参数有

AVSEEK_FLAG_BACKWARD = 1; ///< seek backward
AVSEEK_FLAG_BYTE     = 2; ///< seeking based on position in bytes
AVSEEK_FLAG_ANY      = 4; ///< seek to any frame, even non key-frames

ffmpeg默认的是选取关键帧(这个概念需要具体定义)。opencv里面这个函数的参数flag是0,

int ret = av_seek_frame(ic, video_stream, timestamp, 0);

也就是按照默认的读取关键帧。因此,视频跳跃就出现了。

解决这个问题需要将0改为 AVSEEK_FLAG_ANY ,即:

int ret = av_seek_frame(ic, video_stream, timestamp, AVSEEK_FLAG_ANY );

之后重新编译opencv库,就可以了。

P.S:测试的代码

view plaincopy to clipboardprint?
#include "opencv/highgui.h" 
#include <iostream>  
using namespace std;  
int main( int argc, char** argv )  
{   
    cvNamedWindow( "Example2", CV_WINDOW_AUTOSIZE );  
    CvCapture* capture = cvCreateFileCapture( "d://11.avi" );  
    IplImage* frame;  
    int pos=0;  
    int pos1=0;  
    while(1)  
    {  
        cvSetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES,pos);  
        cout<<pos;  
        frame = cvQueryFrame(capture);  
        pos1=cvGetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES);  
        cout<<"/t"<<pos1<<endl;  
        if( !frame ) break;  
        cvShowImage( "Example2", frame );  
        char c = cvWaitKey(33);  
        if( c == 27 ) break;  
        pos++;  
    }  
    cvReleaseCapture( &capture );  
    cvDestroyWindow( "Example2" );  

#include "opencv/highgui.h"
#include <iostream>
using namespace std;
int main( int argc, char** argv )
{
 cvNamedWindow( "Example2", CV_WINDOW_AUTOSIZE );
 CvCapture* capture = cvCreateFileCapture( "d://11.avi" );
 IplImage* frame;
 int pos=0;
 int pos1=0;
 while(1)
 {
  cvSetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES,pos);
  cout<<pos;
  frame = cvQueryFrame(capture);
  pos1=cvGetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES);
  cout<<"/t"<<pos1<<endl;
  if( !frame ) break;
  cvShowImage( "Example2", frame );
  char c = cvWaitKey(33);
  if( c == 27 ) break;
  pos++;
 }
 cvReleaseCapture( &capture );
 cvDestroyWindow( "Example2" );
}
 

参考:http://wsqhs.spaces.live.com/blog/cns!94F639580F58209C!697.entry

http://www.ffmpeg.com.cn/index.php/%E5%85%B3%E4%BA%8E_frame%E7%9A%84%E4%B8%80%E4%BA%9B%E5%9F%BA%E6%9C%AC%E7%9F%A5%E8%AF%86

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/friedvan/archive/2011/02/20/6195777.aspx

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/friedvan/archive/2011/02/20/6195777.aspx

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/friedvan/archive/2011/02/20/6195777.aspx

 

专注于最新测试仪器仪表(测试机)研发、生产、销售.

应用领域:线材测试、安规测试(高压测试)、变压器测试(LCR Meter)、PCB低阻测试、电源系统测试。

淘宝小店:http://shop72422917.taobao.com

有意者QQ:1482082920

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值