现在找一个能拍摄视频的设备真是太容易了。结果大家都用视频来代替以前的序列图像。视频可能由两种形式得到,一个是像网络摄像头那样实时视频流,或者由其他设备产生的压缩编码后的视频文件。幸运的是,OpenCV可以使用相同的C++类、用同一种方式处理这些视频信息。在接下来的教程里你将学习如何使用摄像头或者视频文件。

  • 如何打开和读取视频流
  • 两种检查相似度的方法:PSNR和SSIM

如何读取一个视频流(摄像头或者视频文件)?

总的来说,视频捕获需要的所有函数都集成在 VideoCapture C++ 类里面。虽然它底层依赖另一个FFmpeg开源库,但是它已经被集成在OpenCV里所以你不需要额外地关注它的具体实现方法。你只需要知道一个视频由一系列图像构成,我们用一个专业点儿的词汇来称呼这些构成视频的图像:“帧”(frame)。此外在视频文件里还有个参数叫做“帧率”(frame rate)的,用来表示两帧之间的间隔时间,帧率的单位是(帧/秒)。这个参数只和视频的播放速度有关,对于单独的一帧图像来说没有任何用途。

你需要先定义一个 VideoCapture 类的对象来打开和读取视频流。具体可以通过 constructor 或者通过 open 函数来完成。如果使用整型数当参数的话,就可以将这个对象绑定到一个摄像机,将系统指派的ID号当作参数传入即可。例如你可以传入0来打开第一个摄像机,传入1打开第二个摄像机,以此类推。如果使用字符串当参数,就会打开一个由这个字符串(文件名)指定的视频文件。

结构体 CvCapture

CvCapture 是一个结构体,用来保存图像捕获所需要的信息。 opencv提供两种方式从外部捕获图像:

一种是从摄像头中,
一种是通过解码视频得到图像。
     两种方式都必须从第一帧开始一帧一帧的按顺序获取,因此每获取一帧后都要保存相应的状态和参数。
     比如从视频文件中获取,需要保存视频文件的文件名,相应的解码器类型,下一次如果要获取将需要解码哪一帧等。
 这些信息都保存在CvCapture结构中,每获取一帧后,这些信息都将被更新,获取下一帧需要将新信息传给获取的 api接口

cvCreateFileCapture(char*name)
通过输入要读取的avi文件的路径,然后,该函数返回一个指向 CvCapture结构体的指针。
cvQueryFrame(capture)
输入一个CvCapture 类型的指针,该函数主要功能是将视频文件的下一帧加载到内存。与 cvLoadImage的不同之处是,该函数不重新分配内存空间。
C=cvWaitKey(33)
当前帧被显示后,等待 33毫秒。如果用户触发了一个按键, c会被设置成这个按键的 ASCII码,否则会被设置成 -1。
cvWaitKey(33) 在此处的另外一个作用是,控制帧率。
cvReleaseCapture(&capture)
释放为 CvCapture结构体开辟的内存空间
关闭打开的 AVI文件相关的文件句柄
VideoCapture类
用于从视频文件或摄像机捕获视频.该类提供了用于从摄像机捕获视频或者读取视频文件的C++ API。 注意:在C API中使用黑盒子结构CvCapture来代替VideoCapture。 构造函数
VideoCapture::VideoCapture()
VideoCapture::VideoCapture(const string& filename)//filename – 文件名
VideoCapture::VideoCapture(int device)//device – 捕获视频的编号. 如果只有一个设备,默认编号为0
open函数
打开视频文件或捕获设备进行视频捕获
bool VideoCapture::open(const string& filename)//filename – 文件名
bool VideoCapture::open(int device)//device – 捕获视频的编号. 如果只有一个设备,默认编号为0
isopened函数
如果视频捕获已经初始化,则返回true。
bool VideoCapture::isOpened()
release函数
关闭视频文件或捕获设备
void VideoCapture::release()
grap函数
从视频文件或捕获设备中捕获下一帧
bool VideoCapture::grab()
retrieve函数
解码并返回抓取的视频帧
bool VideoCapture::retrieve(Mat& image, int channel=0)
read函数
抓取,解码并返回下一个视频帧
bool VideoCapture::read(Mat& image)
get函数
返回指定的VideoCapture属性
double VideoCapture::get(int propId)//propId - 属性标识符
CV_CAP_PROP_POS_MSEC - 视频文件的当前位置(以毫秒为单位)或视频捕获时间戳。
CV_CAP_PROP_POS_FRAMES - 下一个要解码/捕获的帧的基于0的索引。
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 - 编解码器的4个字符代码。
CV_CAP_PROP_FRAME_COUNT - 视频文件中的帧数。
CV_CAP_PROP_FORMAT - retrieve()返回的Mat对象的格式。
CV_CAP_PROP_MODE - 指示当前捕获模式的后端特定值。
CV_CAP_PROP_BRIGHTNESS - 图像的亮度(仅适用于相机)。
CV_CAP_PROP_CONTRAST - 图像的对比度(仅适用于相机)。
CV_CAP_PROP_SATURATION - 图像的饱和度(仅适用于相机)。
CV_CAP_PROP_HUE - 图像的色调(仅适用于摄像机)。
CV_CAP_PROP_GAIN - 图像的增益(仅适用于摄像机)。
CV_CAP_PROP_EXPOSURE - 曝光(仅适用于相机)。
CV_CAP_PROP_CONVERT_RGB - 指示图像是否应转换为RGB的布尔标志。
CV_CAP_PROP_WHITE_BALANCE - 目前不支持
CV_CAP_PROP_RECTIFICATION - 立体相机的校正标志(注意:目前仅由DC1394 v 2.x后端支持)
set函数
设置VideoCapture中的属性。
bool VideoCapture::set(int propertyId, double value)//propId - 属性标识符,同get;value - 属性的值。

  

简单的读写视频程序
#include<opencv2/opencv.hpp>
using namespace cv; void main() {
VideoCapture cap;
cap.open("E:\\VS2015Opencv\\vs2015\\project\\video\\01.avi"); //打开视频,以上两句等价于VideoCapture cap("E://01.avi"); //cap.open("http://www.laganiere.name/bike.avi");//也可以直接从网页中获取图片,前提是网页有视频,以及网速够快
if (!cap.isOpened())//如果视频不能正常打开则返回
return ;
Mat frame;
while ()
{
cap >> frame;//等价于cap.read(frame);
if (frame.empty())//如果某帧为空则退出循环
break;
imshow("video", frame);
waitKey();//每帧延时20毫秒
}
cap.release();//释放资源
}

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std; void main() {
VideoCapture cap;
cap.open("E:\\VS2015Opencv\\vs2015\\project\\video\\01.avi"); if (!cap.isOpened())
return; int width = cap.get(CV_CAP_PROP_FRAME_WIDTH); //帧宽度
int height = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //帧高度
int frameRate = cap.get(CV_CAP_PROP_FPS); //帧率 x frames/s
int totalFrames = cap.get(CV_CAP_PROP_FRAME_COUNT); //总帧数 cout << "视频宽度=" << width << endl;
cout << "视频高度=" << height << endl;
cout << "视频总帧数=" << totalFrames << endl;
cout << "帧率=" << frameRate << endl; Mat frame;
while ()
{
cap >> frame;//等价于cap.read(frame);
if (frame.empty())
break;
imshow("video", frame);
if (waitKey() != )
break;
}
cap.release();
}

将左边的waitkey(33)改成右边的if(waitKey(20)>0)break;

程序会直接跳出,不放视频

opencv学习之等待按键事件-waitKey函数

waitkey(20) 如果不按键的时候是返回 oxff,这个无符号就是255,有符号就是-1

windows vs 的环境默认了这个为非符号数 即255,而opencv的新手书中,往往作者环境会认为是-1

解决方案:把原始代码中循环读取帧的

if (waitKey(33)>=0)break;

改为

if (waitKey(33) != 255)break;

或者把waitkey的返回值用有符号数去读取。

参考:opencv学习之路(2)、读取视频,读取摄像头

OpenCV的视频读取的更多相关文章

  1. 基于OpenCV之视频读取,处理和显示框架的搭建(一)

    主要包括以下内容: 1.使用的主要函数的说明. 2.两个实例:视频读取和显示.搭建视频读取和处理框架,调用canny函数提取边缘并显示. 3.一些注意事项和代码说明. 一.使用的主要函数 1.延时函数 ...

  2. OpenCV学习笔记(2)——如何用OpenCV处理视频

    如何用OpenCV处理视频 读取视频文件,显示视频,保存视频文件 从摄像头获取并显示视频 1.用摄像头捕获视频 为了获取视频,需要创建一个VideoCapature对象.其参数可以是设备的索引号,也可 ...

  3. python + opencv: 解决不能读取视频的问题

    博主一开始使用python2.7和Opencv2.4.10来获取摄像头图像,程序如下: cap = cv2.VideoCapture(0) ret, frame = cap.read() 使用这个程序 ...

  4. OpenCV视频读取播放,视频转换为图片

    转载请注明出处!!! http://blog.csdn.net/zhonghuan1992 OpenCV视频读取播放,视频转换为图片 介绍几个有关视频读取的函数: VideoCapture::Vide ...

  5. OpenCV计算机视觉学习(1)——图像基本操作(图像视频读取,ROI区域截取,常用cv函数解释)

    1,计算机眼中的图像 我们打开经典的 Lena图片,看看计算机是如何看待图片的: 我们点击图中的一个小格子,发现计算机会将其分为R,G,B三种通道.每个通道分别由一堆0~256之间的数字组成,那Ope ...

  6. 使用opencv显示视频的方法

    下面对使用opencv显示视频做一个简单的记录.当然,网上这方面的资料已经数不胜数了,我只是将其简单记录,总结一下. 在opencv中显示视频主要有: (1)从本地读取视频和调用摄像头读取视频 (2) ...

  7. 基于opencv将视频转化为字符串Java版

    基于opencv将视频转化为字符串Java版 opencv java  先上一个效果图吧 首先,弄清一下原理 我们要将视频转化为字符画,那么就需要获取画面的每一帧,也就是每一张图片,然后将图片进行转化 ...

  8. Atitit Java OpenCV 捕获视频

    Atitit Java  OpenCV 捕获视频 ,打开一段视频或默认的摄像头 有两种方法,一种是在定义类的时候,一种是用open()方法. 一. 读取视频序列 OpenCV提供了一个简便易用的框架以 ...

  9. OpenCV读写视频文件解析

    OpenCV读写视频文件解析 一.视频读写类 视频处理的是运动图像,而不是静止图像.视频资源可以是一个专用摄像机.网络摄像头.视频文件或图像文件序列. 在 OpenCV 中,VideoCapture ...

随机推荐

  1. jquery-进度条

    function process_bar(s_date, e_date, data) { $('.modal-body').text('你选择的时期范围是:' + s_date + '到' + e_d ...

  2. LNMP环境配置(1)

    安装Nginx.MySQL.PHP 概念 LNMP是Linux Nginx MySQL PHP 的简写,把Nginx.MySQL以及PHP安装在Linux系统上,组成一个环境来运行PHP的脚本语言. ...

  3. Local changes were not restore

    问题是这样的: 更新代码的时候出现这个弹框,不能更新最新代码 解决如下: 直接点击Clear [注意:这个操作是放弃本地所有的修改,如果要找回代码千万不要点击] 再点击Apply Stash  就可以 ...

  4. P2048 [NOI2010]超级钢琴 [堆+st表]

    考虑只能取长度为 [L,R] 的,然后不难想到用堆搞. 搞个前缀和的st表,里面维护的是一个 最大值的位置 struct rmq { int mx[N][20] ; void qwq(int n) { ...

  5. windows密码抓取工具-mimikatz

    前言 介绍一下windows的密码hash值的组成: Windows系统下的hash密码格式为:用户名称:RID:LM-HASH值:NT-HASH值,例如: Administrator::C8825D ...

  6. Spring 理解和开始

    1.先看看Spring的历史吧 https://baijiahao.baidu.com/s?id=1620099105315862154&wfr=spider&for=pc 2.Spr ...

  7. 异常处理_python

    一.异常处理格式: name=[1,2]data={}try: name[3] data['name']except (KeyError,IndexError) as e : #捕捉指定的几个错误类型 ...

  8. java8的ConcurrentHashMap为何放弃分段锁,为什么要使用CAS+Synchronized取代Segment+ReentrantLock

    原文地址:https://cloud.tencent.com/developer/article/1509556 推荐一篇 ConcurrentHashMap 和 HashMap 写的比较的的文章 j ...

  9. mybatis一级缓存和二级缓存(一)

    一级缓存: 就是Session级别的缓存.一个Session做了一个查询操作,它会把这个操作的结果放在一级缓存中. 如果短时间内这个session(一定要同一个session)又做了同一个操作,那么h ...

  10. 我的python笔记05

    Python 之路 Day5 - 常用模块学习 本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & picle shelve ...