我是靠谱客的博主 呆萌冷风,最近开发中收集的这篇文章主要介绍Opencv--视频操作基础从视频序列中抓取一帧获取/设定帧信息存储视频文件读取方式需要注意:,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

从视频序列中抓取一帧

  • OpenCV支持从摄像头或视频文件(AVI)中抓取图像.
  • 从摄像头获取初始化:

CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0

  • 从视频文件获取初始化:

CvCapture* capture = cvCaptureFromAVI("infile.avi");

  • 抓取帧:

IplImage* img = 0; 
if(!cvGrabFrame(capture)){              // 抓取一帧 
  printf("Could not grab a frame/n/7");
  exit(0);
}
img=cvRetrieveFrame(capture);           // 恢复获取的帧图像

要从多个摄像头同时获取图像, 首先从每个摄像头抓取一帧. 在抓取动作都结束后再恢复帧图像. 

  • 释放抓取源:

cvReleaseCapture(&capture);

注意由设备抓取的图像是由capture函数自动分配和释放的. 不要试图自己释放它.

获取/设定帧信息

  • 获取设备特性:

cvQueryFrame(capture); // this call is necessary to get correct 
                       // capture properties
int frameH    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
int frameW    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
int fps       = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
int numFrames = (int) cvGetCaptureProperty(capture,  CV_CAP_PROP_FRAME_COUNT);

  • 获取帧信息:

float posMsec   =       cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC);
int posFrames   = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
float posRatio  =       cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO);

获取所抓取帧在视频序列中的位置, 从首帧开始按[毫秒]算. 或者从首帧开始从0标号, 获取所抓取帧的标号. 或者取相对位置,首帧为0,末帧为1, 只对视频文件有效.

  • 设定所抓取的第一帧标号:

// 从视频文件相对位置0.9处开始抓取
cvSetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO, (double)0.9);

只对从视频文件抓取有效. 不过似乎也不成功!!!

存储视频文件

  • 初始化视频存储器:

CvVideoWriter *writer = 0;
int isColor = 1;
int fps     = 25;  // or 30
int frameW  = 640; // 744 for firewire cameras
int frameH  = 480; // 480 for firewire cameras
writer=cvCreateVideoWriter("out.avi",CV_FOURCC('P','I','M','1'),
                           fps,cvSize(frameW,frameH),isColor);

其他有效编码:

CV_FOURCC('P','I','M','1')    = MPEG-1 codec
CV_FOURCC('M','J','P','G')    = motion-jpeg codec (does not work well)
CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec
CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec
CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec
CV_FOURCC('U', '2', '6', '3') = H263 codec
CV_FOURCC('I', '2', '6', '3') = H263I codec
CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec

若把视频编码设为-1则将打开一个编码选择窗口(windows系统下).

  • 存储视频文件:

IplImage* img = 0; 
int nFrames = 50;
for(i=0;i<nFrames;i++){
  cvGrabFrame(capture);          // 抓取帧
  img=cvRetrieveFrame(capture);  // 恢复图像
  cvWriteFrame(writer,img);      // 将帧添加入视频文件
}

若想在抓取中查看抓取图像, 可在循环中加入下列代码:

cvShowImage("mainWin", img); 
key=cvWaitKey(20);           // wait 20 ms

若没有20[毫秒]延迟,将无法正确显示视频序列.

  • 释放视频存储器:

cvReleaseVideoWriter(&writer);


读取方式需要注意:

CvCapture* captrue = cvCreateFileCapture(test_video_path.c_str());
IPLImage* input_image=cvQueryFrame(captrue);
所获取图像input_image是倒着的,虽然cvShowImage显示为正着的,以及cvSaveImage都为正着的,是因为这两个函数先进行了数据排列判断,但实际数据是倒着排列的。可以查看input_image.origin是1。而正常cvLoadImage进来的图像input_image.origin是0。
因此,对于cvQueryFrame后获取的图像input_image先要进行flip,即:cvFlip(input_image);此时图像数据为直观所显示的图像一致了。

最后

以上就是呆萌冷风为你收集整理的Opencv--视频操作基础从视频序列中抓取一帧获取/设定帧信息存储视频文件读取方式需要注意:的全部内容,希望文章能够帮你解决Opencv--视频操作基础从视频序列中抓取一帧获取/设定帧信息存储视频文件读取方式需要注意:所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部