opencv学习之路(2)、读取视频,读取摄像头
一、介绍
视频读取本质上就是读取图像,因为视频是由一帧一帧图像组成的。1秒24帧基本就能流畅的读取视频了。
①读取视频有两种方法:
A. VideoCapture cap;
cap.open(“1.avi”);
B. VideoCapture cap(“1.avi”);
②循环显示每一帧:
while(1)
{
Mat frame; //定义Mat变量,用来存储每一帧
cap>>frame; //读取当前帧方法一
//cap.read(frame); //读取当前帧方法二
imshow(“视频显示”, frame); //显示一帧画面
waitKey(30); //延时30ms
}
二、读取视频示例程序
#include<opencv2/opencv.hpp>
using namespace cv; void main(){
VideoCapture cap;
cap.open("E://2.avi"); //打开视频,以上两句等价于VideoCapture cap("E://2.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();//释放资源
}
三、读取视频说明
- 打开的视频可以是本地视频如:
VideoCapture cap(“1.avi”);
也可以是网络视频如:
VideoCapture cap(“http://www.laganiere.name/bike.avi“); - 读取视频一定要加异常判断
A.打开视频失败(各种原因)
B. 取帧失败异常(程序结尾判断)
ex1:
if(!cap.isOpened()) //检查打开是否成功
return;
ex2:
cap>>frame;
if(!frame.empty()) //判断当前 帧是否为空
{
imshow(“video”, frame);
waitKey(30);
}
else break;
四、获取指定视频类的相关参数信息
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std; void main(){
VideoCapture cap;
cap.open("E:\\2.avi"); //打开视频,等价于 VideoCapture cap("E://2.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();
}
五、读取摄像头
读取摄像头和读取视频大同小异,主要是这句代码有些许不同。
VideoCapture cap;
cap.open(0);
读取视频时可以传入视频路径,而读取摄像头传入的是index索引号。
注:
1)如果默认笔记本/台式机只有一个USB摄像头,Index=0; 如果有2个,一般Index为0和1,根据具体情况区分,摄像头接入和断开会改变Index值
2)如果接入2个以上,但只想用指定的一个,可以在设备管理器中禁用其他,同时Index设置为0
3)因为开启摄像头后一直在进行读取,所以需要用waitKey()返回值判断退出预览
imshow(“video”, frame);
if(waitKey(30)>0)//无按键按下返回-1,按键按下时退出
break;
也可以指定按键退出:
if(waitKey(30)==27) //Esc键退出,ESC的ASCLL码为27
break;
六、读取摄像头后加入简单处理效果
如果只是读取摄像头不进行处理的话,那毫无意义,现在以canny边缘检测以及颜色空间转换为目标进行处理。
#include<opencv2/opencv.hpp>
using namespace cv; void main(){
VideoCapture cap;
cap.open(); //打开摄像头 if(!cap.isOpened())
return; Mat frame;
while()
{
cap>>frame;//等价于cap.read(frame);
Canny(frame, frame, , );//canny边缘检测,去掉这一行就是纯粹的读取摄像头了
//cvtColor(frame, frame, CV_BGR2HSV);//BGR空间转为HSV颜色空间,注意,两者不能同时对同一张图片(在此为frame)进行处理,否则报错
if(frame.empty())
break;
imshow("video", frame);
if(waitKey()>)//按下任意键退出摄像头 因电脑环境而异,有的电脑可能会出现一闪而过的情况
break;
}
cap.release();
destroyAllWindows();//关闭所有窗口
}
针对第20行代码:最开始电脑配置的opencv2.x版本,上述代码打开摄像头没有问题;后来使用opencv3.x版本,重新编译了contrib包,发现摄像头打开后一闪而过。
原因是 waitkey() 如果不按键的时候是返回 oxff,oxff无符号时是255,有符号时是-1。windows vs 的环境默认了这个为非符号数 即255,而opencv的有些配置环境中是-1。
解决方案:把原始代码中循环读取帧的
if (waitKey(20)>=0) break;
改为
if (waitKey(20) != 255) break;
或者把waitkey的返回值用有符号数去读取。
uchar c=waitkey(20); if(c!=255) break;
七、写入视频
1、介绍
①VideoWriter: OpenCV提供VideoWriter类写视频文件,类的构造函数可以指定文件名、播放帧率、帧尺寸、是否创建彩色视频。
②两种写入帧方法:
1 ) writer.write(frame);
2)writer >>frame(这里的箭头方向应该相反,不知道为什么箭头不能向←);
③注意事项:
1)写入视频前需安装对应的编解码器
2)生成视频是否支持彩色应与构造函数设置一致
3)生成视频尺寸需与读取视频尺寸一致
2、代码示例
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std; void main(){
VideoCapture cap;
cap.open("E://2.avi");
Size size0=Size(cap.get(CV_CAP_PROP_FRAME_WIDTH),cap.get(CV_CAP_PROP_FRAME_HEIGHT));
VideoWriter writer("E://out.avi",-,cap.get(CV_CAP_PROP_FPS),size0,false); if(!cap.isOpened())
return; Mat frame;
while()
{
cap>>frame;
Canny(frame,frame,,);
if(frame.empty())
break;
writer<<frame;//等同于writer.write(frame);
imshow("video", frame);
if(waitKey()>)
break;
}
cout<<"write end!";
cap.release();
destroyAllWindows();
}
opencv学习之路(2)、读取视频,读取摄像头的更多相关文章
- 【OpenCV开发】OpenCV:使用VideoCapture类进行视频读取和显示
原文来自:http://blog.csdn.net/thefutureisour/article/details/7530344 -------------以下为原文---------------这次 ...
- OpenCV3读取视频或摄像头
我们可以利用OpenCV读取视频文件或者摄像头的数据,将其保存为图像,以用于后期处理.下面的实例代码展示了简单的读取和显示操作: // This is a demo introduces you to ...
- opencv学习之路(3)、批量读取图片、视频分解、视频合成
一.批量有序读取图片 #include<opencv2/opencv.hpp> using namespace cv; void main() { //批量读取图片(有序) ]; ]; M ...
- 【openCV学习笔记】【2】读取并播放一段视频
#include <iostream> #include <opencv/highgui.h> int main(int argc, char** argv){ cvNamed ...
- 第十二节,OpenCV学习(一)图像的读取、显示、保存
一.读取图像 所谓的图像就是一个数组,对图像的处理就是对数字的处理 import cv2 import numpy as np img = cv2.imread('dog.jpg') print(im ...
- opencv学习之路(6)、鼠标截图,滑动条播放视频
一.鼠标截图 #include<opencv2/opencv.hpp> #include<iostream> using namespace cv; using namespa ...
- OpenCV学习 2:播放AVI视频
原创文章,欢迎转载,转载请注明出处 第二个程序,播放视频.用opencv做起来是如此的简单..哈哈. 学Opencv,只是为了在它的基础上实现工程应用,而它里面高深的理论我等屌丝只 ...
- OpenCV成长之路(10):视频的处理
视频中包含的信息量要远远大于图片,对视频的处理分析也越来越成为计算机视觉的主流,而本质上视频是由一帧帧的图像组成,所以视频处理最终还是要归结于图像处理,但在视频处理中,有更多的时间维的信息可以利用.本 ...
- Opencv学习之路—Opencv下基于HOG特征的KNN算法分类训练
在计算机视觉研究当中,HOG算法和LBP算法算是基础算法,但是却十分重要.后期很多图像特征提取的算法都是基于HOG和LBP,所以了解和掌握HOG,是学习计算机视觉的前提和基础. HOG算法的原理很多资 ...
随机推荐
- python date time
//test.py import time ticks = time.time()print tickslocaltime = time.localtime(time.time())print loc ...
- cocos2d-x android工程接入第三方支付宝SDK
1. 首先去支付宝官网下载开发者文档 2. 然后按着开发者文档将支付宝的sdk导入到你的工程中,并关联到工程中,步骤入下图: (1)将从支付宝官方网站获得的支付宝的sdk的jar包拷贝到工程中的lib ...
- PyQT5速成教程-4 Qt Designer实战[上]
本文由 沈庆阳 所有,转载请与作者取得联系! 前言 在前面几节的学习中,我们对PyQt的基本使用.Qt Designer与Python编码的工作流程有了基本的学习.同时也掌握了Qt Designer中 ...
- php背景图片上生成二维码,二维码上带logo 代码示例 (原)
依赖库文件 phpqrcode.php (下载地址://www.jb51.net/codes/189897.html :或者在官网下载:http://phpqrcode.sourceforge.net ...
- mysql数据库表设计小数类型
float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位)double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E308(15个有效 ...
- 【网络设备】某防火墙基于IP地址的目的地址转换
由于来自Internet的对政府,企业的网络攻击日益频繁,因此需要对内网中向外网提供访问服务的关键设备进行有效保护.采用目的地址NAT可以有效地将内部网络地址对外隐藏. 图中:公网中Internet用 ...
- POJ 2155 Matrix(二维BIT)
Matrix [题目链接]Matrix [题目类型]二维BIT &题解: bit只能单点更新,恰好,这题可以想一下就可以用单点更新解决了. 只不过最后我交上去居然T了,想了10多分钟,试了一下 ...
- C# 基于Aspose.Cells的数据导出到Excel
using Aspose.Cells; void WriteToExcel(string filePath, List<object[]> datas, string sheetName ...
- mongodb中直接根据某个字段更新另外一个字段值
表:tblCard 要更新的字段:tPAFlow 值字段: pFlow 过滤 条件:{"lCycle":2} db.tblCard.find({"lCycle" ...
- Spring源码阅读(二)
我们先看AbstractBeanFactory.getBean方法,这个方法通过bean名称类型等信息获取类实例,如果实例不存在则生产并缓存. //-------------------------- ...