以前在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:测试的代

在OpenCV 2.0及以上版本中,使用cvSetCaptureProperty进行视频帧定位时常出现不准确的问题,主要是由于从opencv1.0的vfw采集方式转变为ffmpeg导致的。ffmpeg默认按照关键帧寻求,而cvSetCaptureProperty参数设置为0。通过将参数改为AVSEEK_FLAG_ANY,即`av_seek_frame(ic, video_stream, timestamp, AVSEEK_FLAG_ANY)`,可以解决视频定位跳跃的状况。测试代码显示,修改后能正确设置和获取视频帧位置。"
108463082,3039001,用户画像构建全攻略:从0到1,再到100,"['用户推荐', '机器学习', '深度学习', '用户画像']
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



