OpenCV中cvSetCaptureProperty定位不准的原因及处理
发布时间:2021-12-18 17:24:45 所属栏目:教程 来源:互联网
导读:以前在opencv2.0里面用到cvSetCaptureProperty函数的时候总是发生定位不准确的问题,明明是让其跳到100帧,结果却总不是100帧,定位一段连续的视频,总是出现跳跃的现象。同样的代码在opencv1.0里面完全没错。可是这是为什么?这个问题一直困扰了我半年,终于
以前在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:测试的代码 #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" ); } ![]() (编辑:开发网_开封站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |