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

    Set实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员),操作方法有:add(value).delete(value).has(value).clear():遍历方法有:keys ...

  2. java Graphics2D绘制文字 本地正常服务器乱码问题

    先贴关键代码: 用Graphics2D画文字到图片,再生成图片文件,在本地运行正常,一部署到服务器就不正常,变成了正方框如下图 解决问题思路: 1.部署服务器的编码问题. 2.代码问题. 以上两点一直 ...

  3. ng-做一个简单的通讯录--学习使用路由和HTTP

    app.module import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@ang ...

  4. BIOS和DOS中断大全

    DOS中断: 1.字符功能调用类(Character-Oriented Function)01H.07H和08H —从标准输入设备输入字符02H —字符输出03H —辅助设备的输入04H —辅助设备的 ...

  5. How Many Answers Are Wrong HDU - 3038 带边权并查集

    #include<iostream> #include<cstring> using namespace std; ; int d[N],p[N]; int find(int ...

  6. P1268 树的重量【构造】

    题目描述 树可以用来表示物种之间的进化关系.一棵“进化树”是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异.现在,一个重要的问题是,根据物种之间的距离,重构相应的“进化树 ...

  7. win10专业工作站版密钥|win10专业工作站版key|win10专业工作站版激活码

    一.windows10专业工作站零售版密钥 永久激活 Win 10 ProfessionalWorkstation Retail [Key]:DXG7C-N36C4-C4HTG-X4T3X-2YV77 ...

  8. 0级搭建类012-Windows Server 2019安装(2019) 公开

    项目文档引子系列是根据项目原型,制作的测试实验文档,目的是为了提升项目过程中的实际动手能力,打造精品文档AskScuti. 项目文档引子系列目前不对外发布,仅作为博客记录.如学员在实际工作过程中需提前 ...

  9. C++常见编译问题记录

    1.类名重复问题 在同一个项目下,分文件编译时,所有的文件最后会被编译到一个可执行程序或dll中,所以同一个项目下文件中不能出现两个相同的类名,否则编译器无法区分使用的到底是那个类,就会出现LINK2 ...

  10. 133.在django中使用memcached

    1. 在django中使用memcached,可以在settings.py文件中DATABASES变量下面配置CACHES缓存相关配置信息,只允许本机连接memcached就可以设置LOCATION为 ...