您的位置:首页 > 运维架构

cvCaptureProperty()定位不准的另类解决办法

2014-03-29 16:57 253 查看
最近想实现对打开的视频实时定位,结果总是定位不成功。

上网查了一下,发现是版本更新后出现的问题,使用OpenCV 1.1版本,就可以正常定位。

OpenCV 2.X 版本中,调用cvCaptureProperty()定位视频到指定帧,采用下面两种方法都会出现定位不准的问题。

cvSetCaptureProperty( capture, CV_CAP_PROP_POS_AVI_RATIO, t)



cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, t);

网上的解决办法是:

原因在于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库,就可以了。

但是这样做会造成花频(具体原因不清楚)。所以我用了一个比较笨的办法:重新获取capture,然后一直调用到指定的帧数。

具体代码:

int count=GetDlgItemInt(IDC_EDIT_FRAME);
//cvSetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES,count);//该函数会出现定位不准情况
//cvReleaseCapture(&capture);
capture = cvCaptureFromFile(m_sFilePathName);//opencv的初始帧是从-1开始的
for (;count>=0;count--)
{
cvQueryFrame(capture);
}//到达count-1帧处
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: