现在找一个能拍摄视频的设备真是太容易了。结果大家都用视频来代替以前的序列图像。视频可能由两种形式得到,一个是像网络摄像头那样实时视频流,或者由其他设备产生的压缩编码后的视频文件。幸运的是,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. unity目前学的一些操作

    目前是根据b站的一位迈扣老师的30集基础教学学习的,用的是sunny land这个资源包进行的教学,这位老师讲得很清晰,吐词清晰,思路也清晰,推荐哦.其实我比较喜欢这样的老师,思路 吐词清晰.就像以前 ...

  2. Java-算式填符号

    题目: 某批警察叔叔正在进行智力训练:1 2 3 4 5 6 7 8 9 = 110 请看上边的算式,为了使等式成立,需要在数字间填入加号或者减号(可以不填,但不能填入其它符号).之间没有填入符号的数 ...

  3. SQL server安装时显示重启计算机失败问题解决办法

    前几天在装SQL server2016的时候,一直显示重启计算机失败; 网上的方法也找来用了,但是重启完还是同样的问题,试了很多种方法,最后在一次测试中点关机的时候不小心点成了重启(win10有个毛病 ...

  4. Linux环境搭建及基础操作

    一.Linux环境搭建 1.安装虚拟机软件(VMWare,Parallel) 虚拟机的作用:将本来不是适合当前操作系统的分区虚拟化成适合当前操作系统的分区格式 2.新建虚拟机: 类似买了一台新的电脑, ...

  5. PIE-SDK For C++矢量数据空间索引的创建

    1.功能简介 空间索引的使用便于数据的查询:所以在创建矢量数据的时候创建空间索引,下面对矢量数据如何创建空间索引进行功能介绍. 2.功能实现说明 2.1 实现思路及原理说明 第一步 创建矢量要素数据集 ...

  6. jenkins - docker搭建jenkins

    jenkins镜像拉取 docker pull jenkins/jenkins 为jenkins镜像分配容器 docker run -d --name jenkins \ -p 8080:8080 \ ...

  7. 【Unity|C#】基础篇(21)——常用类

  8. Networking POJ - 1287 最小生成树板子题

    #include<iostream> #include<algorithm> using namespace std; const int N=1e5; struct edge ...

  9. 转载:polyphase filter

    http://www.ws.binghamton.edu/fowler/fowler%20personal%20page/ee521.htm http://www.ws.binghamton.edu/ ...

  10. <input type="file">文件上传

    <input> type 类型为 file 时使得用户可以选择一个或多个元素以提交表单的方式上传到服务器上,或者通过 Javascript 的 File API 对文件进行操作 . 常用i ...