文档章节

【OpenCV归纳】2 读写视频

NoMasp
 NoMasp
发布于 2015/09/08 21:52
字数 1374
阅读 65
收藏 0


除了读入图片之外,读写视频也足够简单易学,下面来看看如何读写视频吧。


播放硬盘中的视频:


#include "highgui.h"

int main(int argc,char** argv)
{
    cvNamedWindow("Test2",CV_WINDOW_AUTOSIZE);
   CvCapture* capture=cvCreateFileCapture(argv[1]);
    IplImage* frame;
    while(1)
    {
        frame=cvQueryFrame(capture);
        if(!frame)
            break;
        cvShowImage("Test2",frame);
        char c= cvWaitKey(33);
        if(c==27)
            break;
    }
    cvReleaseCapture(&capture);
    cvDestoryWindow("Test2");
}

CvCapture结构包含了从摄像机或视频文件中读取帧所需的信息。根据视频来源,我们可以使用下面两个函数之一来初始化CvCapture结构。

CvCapture* cvCreateFileCapture(const char* filename);

CvCapture* cvCreateCameraCapture(int index);

当时用cvCreateFileCapture()时,我们只需要将MPG或AVI视频文件名告诉该函数,OpenCV会打开并准备读取视频。如果打开成功,将返回一个指向已经初始化了的CvCapture结构的指针,随后便可以读入视频的帧。注意:在一些情况下(比如文件不存在)无法打开文件,函数会返回NULL指针;当压缩视频的编码未知时cvCreateFileCapture()也会返回NULL指针。函数cvCreateCameraCapture()的用法与cvCreateFileCapture()非常类似,但是没有处理视频编码解码的麻烦。



读视频


int cvGrabFrame(cvCapture* capture);

IplImage* cvRetrieveFrame(CvCapture* capture)

IplImage* cvQueryFrame(CvCapture* capture)


方法一:使用cvGrabFrame(),该函数以CvCapture*指针为参数,返回一个整数,当读取帧成功时返回1,否则返回0.cvGrabFrame()将视频帧复制到一个用户看不见的空间里,这是因为获取的视频帧数据是未经过处理的,cvGrabFrame()被设计为用于快速将视频帧读入内存。在cvGrabFrame()以后,可以调用cvRetrieveFrame()来处理cvGrabFrame()读入的视频数据。这个函数会对读入帧做所有必须的处理(包括图像解码操作),并且返回要给IplImage*指针,该指针指向另一块内存空间(不要过分依赖于这个指针所指向的图像,因为cvGrabFrame()下一次调用时,指针所指向的空间会被新的图像覆盖)。实现如下:

#include<highgui.h>

int main()
{
	CvCapture* capture;
	IplImage* frame;
	capture = cvCaptureFromFile("D:\\1.avi");           // 你应该选择自己硬盘avi视频的位置
	cvNamedWindow("Test2_0");

	while (true)
	{
		if (cvGrabFrame(capture))
		{
			frame = cvRetrieveFrame(capture);
			cvShowImage("Test2_0", frame);
			char c = cvWaitKey(33);
			if (c == 27)
				break;
		}				
	}
	cvReleaseCapture(&capture);
	cvDestroyWindow("Test2_0");
}

方法二:代码即为本文第一个实例。

对于CvCapture结构还可以执行很多其他的操作,比如可以查询与设置视频的各种属性:

double cvGetCaptureProperty
(
    CvCapture* capture,
    int property_id,
);

int cvSetCaptureProperty
(
    CvCapture* capture,
    int property_id,
    double value
};

cvGetCaptureProperty()可以接受的参数见下表。

视频捕捉属性 数值
CV_CAP_PROP_POS_MSEC 0
CV_CAP_PROP_POS_FRAME 1
CV_CAP_PROP_POS_AVI_RATIO 2
CV_CAP_PROP_FRAME_WIDTH 3
CV_CAP_PROP_FRAME_HEIGHT 4
CV_CAP_PROP_FPS 5
CV_CAP_PROP_FOURCC 6
CV_CAP_PROP_FRAME_COUNT 7


获得视频编码格式

double f=cvGetCaptureProperty
(
    capture,
    CV_CAP_PROP_FOURCC
);

char* fourcs=(char*) (&f);

double f=cvGetCaptureProperty
(
    capture,
    CV_CAP_PROP_FOURCC
);

char* fourcs=(char*) (&f);

写视频:


写视频就得创建一个CvVideoWriter结构,这是一个类似于CvCapture的视频写入结构。此结构与下面的函数一起使用。


CvVideoWriter* cvCreateVideoWriter
(
    const char* filename,
    int fourcc,
    double fps,
    CvSize frame_size,
    int is_color = 1
);

int cvWriteFrame
(
    CvVideoWriter* writer,
    const IplImage* image
);

void cvReleaseVideoWriter
(
    CvVideoWriter* writer
);

除了视频文件名称,还需要告诉视频写入结构视频编码结构,帧率以及每一帧的大小。还可以告诉OpenCV图像是否彩色(默认为彩色)。fourcc是将4个字符打包在一个整数,由于经常使用,OpenCV提供了一个宏CV_FOURCC(c0,c1,c2,c3)来实现这个打包操作。

视频写入结构建好后,需要调用cvWriteFrame()函数,并且为cvWriteFrame()函数传入一个CvVideoWriter*指针和要给IplImage*指针来写入文件。

写入完成后,为了关闭写入结构,必须调用CvReleaseVideoWriter()函数,如果平时不习惯释放不再使用的空间和结构,对这个结构千万别偷懒,因为不显示释放结构,视频文件可能会被损毁。


HighGUI工具包还包括了一个经常使用的滚动条,滚动条可以使我们方便的从视频的一帧跳到另外一帧。我们通过调用cvCreateTrackbar()来创建一个滚动条,并且通过设置参数来确定滚动条所属的窗口。为了获得所需的功能,只需要提供了一个回掉函数。

#include<cv.h>
#include<highgui.h>

int g_slider_position=0;
CvCapture* g_capture =NULL;

void onTrackbarSlide(int pos)
{
    cvSetCaptureProperty
    (  g_capture,
       CV_CAP_PROP_POS_FRAME,
       pos
    );
}

int main(int argc,char** argv)
{
    cvNamedWindow("Test2_1",CV_WINDOW_AUTOSIZE);;
    g_capture=cvCreateFileCapture(argv[1]);
    int frames=(int)cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_COUNT);
    if(frames!=0)
    {
         cvCreateTrackbar
         (
              "Position",
              "Test2_1",
              &g_slider_position,
               frames,
               onTrackbarSlide
           );
     }
     IplImage* frame;
     // While loop (as in Test1) capture & show video
     // ... 
     // Release memory and destroy window
     ...
     Return (0);
}

除了这些之外还有一个很重要的函数,cvConvertImage(),其用于在常用的不同图像格式之间转换。文件格式在src与dst的图像文件中指出(该函数还允许使用比IplImage更通用的CvArr类型)。源图像必须是单个、3个或者4个通道,也可以是8位或浮点型类型像素格式。目标图像必须是8位的单通道或者3个通道。函数也可以将彩色图像转换为灰度图或者将单通道的灰度图转换为3个通道的灰度图(彩色)。最后,flags参数可以垂直旋转图像。因为偶尔摄像机图像格式与图像显示格式会反转,因此这是很有用的。设置这个参数可以在内存中彻底旋转图像。




版权声明:本文为 NoMasp柯于旺 原创文章,未经许可严禁转载!欢迎访问我的博客:http://blog.csdn.net/nomasp

本文转载自:http://blog.csdn.net/nomasp/article/details/43601633

NoMasp
粉丝 7
博文 334
码字总数 0
作品 0
镇江
程序员
私信 提问
基于OpenCV和Python的文件操作——捕获摄像头的帧,在窗口显示图像,在窗口显示摄像头帧和视频文件的读/写

0 写在前面 这篇博客主要参考资料为《OpenCV 3计算机视觉Python语言实现》(Learning OpenCV 3 Computer Vison with Python)。 因为之前用Faster R-CNN做过一个红绿灯检测的小实践,但是Git...

learning_tortosie
2018/04/12
0
0
C++ 程序使用 OpenCV 实现视频捕获

下载 Capture.zip - 14.1 KB 前言 这是一个使用 Visual C++ 窗口表单编写的简单视频捕捉应用程序。这个工程既演示了窗口表单应用程序的创建,又演示了 OpenCV 的 Visual C++ 配置。 OpenCV 是...

oschina
2014/03/10
9.3K
6
OpenCV 2.4 正式版发布

OpenCV 2.4 正式版发布了,与 2.4 Beta 版比较,该版本主要改进: OpenCV 提供了通过 cv::getBuildInformation() 获取完整构建信息的方法 支持 Mac OS x 下用 ffmpeg 进行视频读写的操作 MO...

红薯
2012/05/02
4.4K
0
视频人脸检测——Dlib版(六)

往期目录 视频人脸检测——Dlib版(六) OpenCV添加中文(五) 图片人脸检测——Dlib版(四) 视频人脸检测——OpenCV版(三) 图片人脸检测——OpenCV版(二) OpenCV环境搭建(一) 更多更...

王磊的博客
2018/05/11
0
0
opencv-3.0.0在Ubuntu14.04下的配置与安装

original url: http://blog.csdn.net/surgewong/article/details/39078251 每次学习新东西或者换新的电脑,最让人头疼的就是环境的安装了。网上有一大堆教程,不过总地来讲,比较混乱,有些甚...

junmuzi
2015/11/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
昨天
5
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
昨天
8
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
昨天
10
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
昨天
6
0
PHP+Ajax微信手机端九宫格抽奖实例

PHP+Ajax结合lottery.js制作的一款微信手机端九宫格抽奖实例,抽奖完成后有收货地址添加表单出现。支持可以设置中奖概率等。 奖品列表 <div class="lottery_list clearfix" id="lottery"> ......

ymkjs1990
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部