OpenCV的HighGUI库以统一地方式实现了对视频文件和摄像头数据的处理,如图4.22,图像信息检索使用了最简单的轮询模型(PollingModel):根据不同的视频源调用不同的方法创建CvCapture结构体对象,CvCapture结构体包含从摄像机或视频文件中读取帧所需的信息,然后循环调用函数cvQueryFrame不断地从CvCapture对象中获取帧数据,循环结束的条件是应用程序退出或者文件结束。
Kinect支持轮询模型和事件模型,如图4.23
OpenCV读取视频文件和摄像头的轮询模型代码如下:
while (1) { frame = cvQueryFrame(g_capture); if (!frame) break; cvShowImage(window_name, frame); char c = cvWaitKey(33); // delay... if (c == 27) break; }
视频文件还可以通过索引的方式,指定播放某一帧,通过cvGetCaptureProperty获取视频文件的帧数,通过cvSetCaptureProperty修改当前播放位置,然后继续调用cvQueryFrame函数获取当前帧数据。索引方式播放视频文件代码如下:
IplImage* get_frame(CvCapture* capture, int frame_idx) { cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frame_idx); return cvQueryFrame(capture); } int main(int argc,char** argv) { CvCapture* capture = 0; capture = cvCreateFileCapture(argv[1]); if (capture==NULL) return 0; int frames = (int) cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_COUNT ); const char* window_name = "VideoShow"; cvNamedWindow(window_name, CV_WINDOW_AUTOSIZE); const int delta = 5; for (int i=0; i<frames; i+=delta) { cvShowImage( window_name, get_frame(capture, i) ); char c = cvWaitKey(33); if (c == 27) break; } return 0; }代码中,get_frame函数获取指定帧,frame_idx为指定帧的索引号。cvWaitKey为delay函数,参数为延迟时长,毫秒单位。程序中通过delta参数控制播放速度,delta = 1正常播放,deleta > 1 是快进。
采用OpenCV实现简单视频播放器如下图,视频播放时,进度条滑动,用户可以拖拉进度条位置改变视频播放位置。
实现代码如下:视频文件名作为命令参数传入。
int g_slider_position = 0; CvCapture* g_capture = NULL; const char* window_name = "The Tom 'n Jerry Show"; const char* trackbar_name = "Position"; void onTrackbarSlide( int pos ) { cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos); g_slider_position = pos; } int main(int argc, char** argv) { cvNamedWindow(window_name, CV_WINDOW_AUTOSIZE); g_capture = cvCreateFileCapture(argv[1]); int frames = (int) cvGetCaptureProperty( g_capture, CV_CAP_PROP_FRAME_COUNT ); if (frames != 0) { cvCreateTrackbar( trackbar_name, window_name, &g_slider_position, frames, onTrackbarSlide ); } IplImage* frame; while (1) { frame = cvQueryFrame(g_capture); if (!frame) break; cvSetTrackbarPos( trackbar_name, window_name, g_slider_position+1 ); cvShowImage(window_name, frame); char c = cvWaitKey(33); if (c == 27) break; } cvReleaseCapture(&g_capture); cvDestroyWindow(window_name); return 0; }代码来源于: http://stackoverflow.com/questions/5047913/opencv-getting-the-slider-to-update-its-position-during-video-playback