学习opencv例2-3

  • 格式:doc
  • 大小:42.00 KB
  • 文档页数:5

视频播放控制 学习opencv书上例2-3,最好留了一个思考问题:实现滚动条随着视频播放自动移动。

笔者也是在原来书上写的程序的基础上稍作修改,现将代码写出来供大家参考!

#include "cv.h" #include "highgui.h" #include using namespace std;

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("Example3",CV_WINDOW_AUTOSIZE); g_capture=cvCreateFileCapture(argv[1]); int frames = (int) cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_COUNT);

/*获得总帧数,也就是滚动条位置的最大值,这个函数的功能和第二个参数有关。*/ if(frames!=0) { cvCreateTrackbar("position","Example3",&g_slider_position,frames,onTrackbarSlide);/*当滚动条被拖动时,opencv会自动将当前位置所代表的值传个指 针所指向的整数,也就是说当滚动条被拖动时, g_slider_position的值是在改变的*/

} /*如果此处滚动条没有被拖动,此语句的作用就是在窗口上创建了一个滚动条,其位置为0,即在初始位置。*/

IplImage* frame; //while loop (as in Example2) caprpture & show video int n=g_slider_position; while(1) {

frame=cvQueryFrame(g_capture); if(!frame) break; cvShowImage("Example3",frame); cvCreateTrackbar("position","Example3",&n,frames,onTrackbarSlide);/*每次循环都在当前位置重新创造一个滚动条,也就是滚动条随着视频播放自动移动*/

char c=cvWaitKey(33); if(c==27) break; n++;

}

cvReleaseCapture(&g_capture); cvDestroyWindow("Example3"); }  例2-3学习笔记 cvCreateTrackbar 该函数为开放计算机视觉(OpenCV)库库函数,创建trackbar并将它添加到指定的窗口。 定义: CV_EXTERN_C_FUNCPTR( void (*CvTrackbarCallback)(int pos) ); int cvCreateTrackbar( const char* trackbar_name, const char* window_name, int* value, int count, CvTrackbarCallback on_change ); 参数:

trackbar_name 被创建的trackbar名字。 window_name 窗口名字,这个窗口将为被创建trackbar的父对象。 value 整数指针,它的值将反映滑块的位置。这个变量指定创建时的滑块位置。 count 滑块位置的最大值。最小值一直是0。 on_change 每次滑块位置被改变的时候,被调用函数的指针。这个函数应该被声明为void Foo(int); 如果没有回调函数,这个值可以设为NULL。 函数cvCreateTrackbar用指定的名字和范围来创建trackbar(滑块或者范围控制),指定与trackbar位置同步的变量,并且指定当trackbar位置被改变的时候调用的回调函数。 被创建的trackbar默认显示在指定窗口的顶端,可以通过函数cvGetTrackbarPos来获取trackbar显示的位置信息,以及通过函数cvSetTrackbarPos来重新设置trackbar的显示位置。

int cvCreateTrackbar( const char* trackbar_name, //滑动条的名称 const char* window_name, //窗口的名称,滑动条不会遮挡图像 int* value, //当滑动条被拖到时,OpenCV会自动将当前位置所代表的值传给指针指向的整数 int count, //滑动条所能达到的最大值 CvTrackbarCallback on_change //可选的回调函数,回调函数可参见

其中openCV的highgui库提供了两个函数来读取和设置滚动条的value值 //读取value值 int cvGetTrackbarPos( const char* trackbar_name, cosnt char* window_name );

//设置value值 void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos );

OpenCV中关于cvGetCaptureProperty函数

OpenCV中提供了一个函数cvGetCaptureProperty(Capture* cap,int property_index)函数来获取视频文件的一些属性,这是其中的OpenCV中属性的一些宏定义: #define CV_CAP_PROP_POS_MSEC 0 #define CV_CAP_PROP_POS_FRAMES 1 #define CV_CAP_PROP_POS_AVI_RATIO 2 #define CV_CAP_PROP_FRAME_WIDTH 3 #define CV_CAP_PROP_FRAME_HEIGHT 4 #define CV_CAP_PROP_FPS 5 #define CV_CAP_PROP_FOURCC 6 #define CV_CAP_PROP_FRAME_COUNT 7 #define CV_CAP_PROP_FORMAT 8 #define CV_CAP_PROP_MODE 9 #define CV_CAP_PROP_BRIGHTNESS 10 #define CV_CAP_PROP_CONTRAST 11 #define CV_CAP_PROP_SATURATION 12 #define CV_CAP_PROP_HUE 13 #define CV_CAP_PROP_GAIN 14 #define CV_CAP_PROP_EXPOSURE 15 #define CV_CAP_PROP_CONVERT_RGB 16 #define CV_CAP_PROP_WHITE_BALANCE 17 #define CV_CAP_PROP_RECTIFICATION 18

通过创建一个Capture对象的指针后,调用cvGetCaptureProperty即可获取上述任何相关属性;但是我们不能太依赖这个函数;比如我们想获取一段视频的帧数,我们就不能太依赖于CV_CAP_PROP_FRAME_COUNT这个属性;因为cvGetCaptureProperty对属性的访问,其实访问的是关联视频文件的文件头信息,并不是真正去访问了视频的图像数据,这就带来一个问题:我们在讲其他视频格式转换为AVI格式的时候,图像帧数并没改变,只是视频文件头改变了,这时直接通过get函数读取的信息就可能不准确;最好的办法是迭代从视频中取出一帧,检查是否有数据,来确定该视频文件的总共帧数~~~ 不光是帧数,帧率也可能不对~~ 比如,自己在实验中庸狸窝转换器将一段视频转换为avi格式的视频文件后,用下面的两段代码,结果差距很大:

code 1.

CvCapture *cap = cvCaptureFromFile(videoName);//获取视频 int numFrames = (int) cvGetCaptureProperty(cap, CV_CAP_PROP_FRAME_COUNT);//得到视频帧数,笔者获得的结果为148

CODE 2. IplImage* pImg=NULL; int count=0; while((pImg=cvQueryFrame(cap))!=NULL) { count++;

}//得到的帧数只有60帧;

究其原因其实就是cvGetCaptureProperty实现的机制上,它只是读取视频文件头信

息,而不是真正读取了视频文件;因此在进行不同格式的视频文件转换为OpenCV支持的AVI时,可能获取的属性并不准确~~~ 因此在使用该函数时,要注意。自己的经验是对于原始的AVI文件,可以直接使用该函数(code1),而经过转换而得到的视频文件,最好使用code 2。

cvSetCaptureProperty 设置视频获取属性 int cvSetCaptureProperty( CvCapture* capture, int property_id, double value ); capture 视频获取结构。 property_id 属性标识符。可以是下面之一: CV_CAP_PROP_POS_MSEC - 从文件开始的位置,单位为毫秒 CV_CAP_PROP_POS_FRAMES - 单位为帧数的位置(只对视频文件有效) CV_CAP_PROP_POS_AVI_RATIO - 视频文件的相对位置(0 - 影片的开始,1 - 影片的结尾) CV_CAP_PROP_FRAME_WIDTH - 视频流的帧宽度(只对摄像头有效) CV_CAP_PROP_FRAME_HEIGHT - 视频流的帧高度(只对摄像头有效) CV_CAP_PROP_FPS - 帧率(只对摄像头有效) CV_CAP_PROP_FOURCC - 表示codec的四个字符(只对摄像头有效)value 属性的值。 函数cvSetCaptureProperty设置指定视频获取的属性。目前这个函数对视频文件只支持: CV_CAP_PROP_POS_MSEC, CV_CAP_PROP_POS_FRAMES, CV_CAP_PROP_POS_AVI_RATIO