OpenCV入门(十七)快速学会OpenCV 16 视频处理

  • 1.构造VideoCapture对象
  • 2.构造VideoWriter对象
  • 3.视频操作基础
    • 3.1 读取视频帧
    • 3.2 播放视频文件
    • 3.3 获取和设置视频属性
  • 4.播放摄像头视频

作者:Xiou

OpenCV的视频I/O模块提供了一组用于读写视频或图像序列的类和函数。该模块将cv::VideoCapture和cv::VideoWriter类作为一层接口面向用户,这两个类下面是很多不同种类的后端视频I/O API,有效地屏蔽了后端视频I/O的差异性,简化了用户层的编程。

在OpenCV中,视频的读操作是通过VideoCapture类来完成的,视频的写操作是通过VideoWriter类来实现的。

1.构造VideoCapture对象

类VideoCapture既支持从视频文件(.AVI、*.MP4、.MPG等格式)读取,也支持直接从摄像机(比如计算机自带的摄像头)中读取。要想获取视频,需要先创建一个VideoCapture对象。创建VideoCapture对象有以下三种方式:

(1)从视频文件中读取视频。如果是从文件(.MPG或.AVI格式)中读取视频,那么在定义对象的时候可以把视频文件的路径作为参数传给构造函数。对象创建以后,OpenCV将会打开该视频文件并做好准备读取它。如果打开成功,就可以开始读取视频的帧。

VideoCapture提供了成员函数isOpened来判断是否成功打开,若成功,则返回True(建议在打开视频或摄像头时都使用该成员函数判断是否成功打开)。下面的构造函数用于读取视频文件:

     VideoCapture(filename) → <VideoCapture object>

其中,参数filename是视频文件的文件名(可以包含路径),如果不包含路径,就在当前路径下打开文件。比如,我们定义一个VideoCapture对象并打开d盘上的test.avi文件:

     cv2.VideoCapture capture("d:/test.avi");  //从视频文件读取

(2)从摄像机中读取视频。如果是从摄像机中读取视频,那么这种情况下我们会给出一个标识符,用于表示我们想要访问的摄像机,及其与操作系统的握手方式。
对于摄像机而言,这个标志符就是一个标志数字:如果只有1个摄像机,就是0;如果系统中有多个摄像机,那么只要将其向上增加即可。
标识符的另外一部分是摄像机域(camera domain),用于表示摄像机的类型,这个域值可以是下面任一预定义常量。读取摄像头中的视频的构造函数如下:

     cv2.VideoCapture(device) → <VideoCapture object>

其中,参数device表示要打开的视频捕获设备(摄像头)的ID,如果使用默认后端的默认摄像头,就只需传递0。

(3)不带参数构造一个VideoCapture对象。使用类VideoCapture的不带参数的构造函数来创建一个VideoCapture对象,然后用成员函数open来打开一个视频文件或摄像头。open函数声明如下:

     VideoCapture.open(filename) → retvalVideoCapture.open(device) → retval

两个open函数的参数和前面的两个构造函数的参数含义一样。

当我们打开一个视频文件或摄像头视频后,可以用成员函数isOpened来判断是否打开成功。函数声明如下:

     VideoCapture.isOpened() → retval

打开成功就返回True,否则返回False。

     import cv2cap = cv2.VideoCapture("./Demo.avi")if cap.isOpened():  # 当成功打开视频时cap.isOpened()返回True,否则返回False...

2.构造VideoWriter对象

OpenCV中的cv2.VideoWriter类可以将图片序列保存成视频文件,也可以修改视频的各种属性,还可以完成对视频类型的转换。

penCV为cv2.VideoWriter类提供了构造函数,用它来实现初始化工作。该函数的语法格式是:

        <VideoWriter object> = cv2.VideoWriter( filename, fourcc, fps, frameSize[,isColor] )

式中:
● filename指定输出目标视频的存放路径和文件名。如果指定的文件名已经存在,则会覆盖这个文件。
● fourcc表示视频编/解码类型(格式)。在OpenCV中用函数cv2.VideoWriter_fourcc()来指定视频编码格式。cv2.VideoWriter_fourcc()有4个字符参数。这4个字符参数构成了编/解码器的“4字标记”,每个编/解码器都有一个这样的标记。下面列出几个常用的标记。

● cv2.VideoWriter_fourcc(‘I’, ‘4’, ‘2’,‘0’)表示未压缩的YUV颜色编码格式,色度子采样为4:2:0。该编码格式具有较好的兼容性,但产生的文件较大,文件扩展名为.avi。
● cv2.VideoWriter_fourcc(‘P’, ‘I’, ‘M’,‘I’)表示MPEG-1编码类型,生成的文件的扩展名为.avi。
● cv2.VideoWriter_fourcc(‘X’, ‘V’, ‘I’,‘D’)表示MPEG-4编码类型。如果希望得到的视频大小为平均值,可以选用这个参数组合。该组合生成的文件的扩展名为.avi。
● cv2.VideoWriter_fourcc(‘T’, ‘H’, ‘E’,‘O’)表示Ogg Vorbis编码类型,文件的扩展名为.ogv。

● fps为帧速率。
● frameSize为每一帧的长和宽。
● isColor表示是否为彩色图像。

下面的语句完成了cv2.VideoWriter类的初始化工作:

        fourcc = cv2.VideoWriter_fourcc(*'XVID')out = cv2.VideoWriter('output.avi', fourcc, 20, (1024,768))

cv2.VideoWriter类中的函数cv2.VideoWriter.write()用于写入下一帧视频。该函数的语法格式为:

        None=cv2.VideoWriter.write(image)

代码实例:使用cv2.VideoWriter类保存摄像头视频文件。

        import numpy as npimport cv2cap = cv2.VideoCapture(0)fourcc = cv2.VideoWriter_fourcc('I', '4', '2', '0')out = cv2.VideoWriter('output.avi', fourcc, 20, (640,480))while(cap.isOpened()):ret, frame = cap.read()if ret==True:out.write(frame)cv2.imshow('frame', frame)if cv2.waitKey(1) == 27:breakelse:breakcap.release()out.release()cv2.destroyAllWindows()

● 设置好要保存的具体文件名,例如:filename=‘‘out.avi’’。
● 使用cv2.VideoWriter_fourcc()确定编/解码的类型,例如:fourcc =cv2.VideoWriter_fourcc(*‘XVID’)。
● 确定视频的帧速率,例如:fps=20。
● 确定视频的长度和宽度,例如:size=(640,480)。

运行上述程序,程序就会捕获当前摄像头的视频内容,并将其保存在当前目录下名为“output.avi”的视频文件中。

3.视频操作基础

视频是由视频帧构成的,将视频帧从视频中提取出,对其使用图像处理的方法进行处理,就可以达到处理视频的目的。

3.1 读取视频帧

要播放视频,肯定要先读取每一帧的视频图像再显示出来。读取方法是使用函数read,该函数声明如下:

     VideoCapture.read([image]) → retval, image

其中,参数image用来存放读取到的当前视频帧。如果读取成功就返回True,否则返回False。

     vc = cv2.VideoCapture(“my.mp4”)rval, frame = vc.read()while success:cv2.setWindowTitle("test", "MyTest") # 设置标题frame = cv2.resize(frame, (960, 540)) # 根据视频帧大小进行缩放cv2.imshow('windows', frame)  # 显示cv2.waitKey(int(1000 / int(fps)))  # 设置延迟时间success, frame = video.read()  # 获取下一帧video.release()

3.2 播放视频文件

播放视频文件的基本步骤就是先构造VideoCapture对象,然后打开视频文件,接着用一个循环逐帧读取并显示读取到的视频帧,再间隔一段时间读取下一个视频帧并显示,依次循环,直到全部视频帧读取完毕。

import numpy as np
import cv2 video = cv2.VideoCapture('sea.mp4')# 获得码率及尺寸
fps = video.get(cv2.CAP_PROP_FPS)
size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)),  int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fNUMS = video.get(cv2.CAP_PROP_FRAME_COUNT)# 读帧
success, frame = video.read()
while success:cv2.setWindowTitle("test",  "I love sea.") # 设置标题frame = cv2.resize(frame, (960, 540)) # 根据视频帧大小进行缩放cv2.imshow('windows', frame)  # 显示cv2.waitKey(int(1000 / int(fps)))  # 设置延迟时间success, frame = video.read()  # 获取下一帧
video.release()

sea.mp4位于当前工程目录下。在上述代码中,我们首先定义了一个VideoCapture对象video,并传入了视频文件的文件名,因为没有加路径,所以sea.mp4要放在当前工程目录下才会被找到。然后利用成员函数get获得码率及尺寸,再用read读取帧,并用一个while不停地读取下一帧,当success为False时说明视频帧没有了,也就是播放完毕了,此时跳出循环。
每一帧其实就是一幅图片,可以用imshow函数把图片显示出来,速度快了以后多幅图片连续显示,看起来就是视频了。这里我们设置每个帧显示之间的时间间隔是int(1000/int(fps))毫秒。

值得注意的是,OpenCV是一个视觉库,目前不支持视频中的声音处理,因此播放的视频没有声音。如果需要声音,则需要使用ffpyplayer。

3.3 获取和设置视频属性

类VideoCapture的成员函数get可以用来获取视频文件的一些属性,比如帧数。该函数声明如下:

     VideoCapture.get(propId) → retval

其中,参数propId表示要获取的属性ID,通常取值是一个宏,比如CAP_PROP_FRAME_COUNT表示获取视频帧数,宏CAP_PROP_FRAME_COUNT的值是7。其他常用属性及其用法如下:

     cv2.VideoCapture.get(0) ; //视频文件的当前位置(播放)以毫秒为单位cv2.VideoCapture.get(1) ; //基于以0开始的被捕获或解码的帧索引cv2.VideoCapture.get(2) ; //视频文件的相对位置(播放):0表示电影开始,1表示影片的结尾cv2.VideoCapture.get(3) ; //在视频流的帧的宽度cv2.VideoCapture.get(4) ; //在视频流的帧的高度cv2.VideoCapture.get(5) ; //帧速率cv2.VideoCapture.get(6) ; //编解码的4字符代码cv2.VideoCapture.get(7) ; //视频文件中的帧数cv2.VideoCapture.get(8) ; //返回对象的格式cv2.VideoCapture.get(9) ; //返回后端特定的值,指示当前捕获模式cv2.VideoCapture.get(10) ; //图像的亮度(仅适用于照相机)cv2.VideoCapture.get(11) ; //图像的对比度(仅适用于照相机)cv2.VideoCapture.get(12) ; //图像的饱和度(仅适用于照相机)cv2.VideoCapture.get(13) ; //色调图像(仅适用于照相机)cv2.VideoCapture.get(14) ; //图像增益(仅适用于照相机)(Gain在摄影中表示白平衡提升)cv2.VideoCapture.get(15) ; //曝光(仅适用于照相机)cv2.VideoCapture.get(16) ; //指示是否应将图像转换为RGB布尔标志MyVideoCapture.get(17) ;   //暂时不支持cv2.VideoCapture.get(18); //立体摄像机的矫正标注(DC1394 v.2.x后端支持这个功能)

有获取属性的函数,自然也有设置属性的函数,具体函数声明如下:

     VideoCapture.set(propId, value) → retval

其中,参数propId表示要设置的属性ID;value表示要设置的属性值。

4.播放摄像头视频

播放摄像头视频和播放视频文件类似,也是通过类VideoCapture来实现的,只不过open的时候是传入摄像头的索引号,如果计算机中插入一个摄像头,那么open的第一个参数通常是700,比如:

     cap=cv2.VideoCapture.open(700, CAP_DSHOW);

打开成功后,就可以一帧一帧地读取并一帧一帧地播放了,其实就是在一个循环里间隔地显示一幅一幅的视频帧图片,间隔时间短,就像是在看视频。

最后播放完毕后,释放资源,比如:

     cap.release()

代码实例:

import cv2 as cv
#打开摄像头 默认为700
cap = cv.VideoCapture(700)
cap.set(cv.CAP_PROP_FRAME_WIDTH,320)
cap.set(cv.CAP_PROP_FRAME_HEIGHT,240)
while True:#每次读取一帧摄像头或者视频ret,frame = cap.read()#将一帧frame显示出来,第一个参数为窗口名cv.imshow('frame',frame)#每次等待1ms 当esc按键被按下时退出显示#ESC按键对应的键值为27if(cv.waitKey(1)&0xff) == 27:break
#常规操作 释放资源
cap.release()
cv.destroyAllWindows()

运行结果:

这个视频是彩色的,下面我们来播放黑白视频。

代码实例:

import numpy as np
import cv2capture = cv2.VideoCapture(700)# 获取 capture 的一些属性
frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)
print(frame_width, frame_height, fps)if capture.isOpened() is False:print('Error openning the camera')frame_index = 0
while capture.isOpened():ret, frame = capture.read()if ret:# 显示摄像头捕获的帧cv2.imshow('Input frame from the camera', frame)# 把摄像头捕捉到的帧转换为灰度gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 显示处理后的帧cv2.imshow('Grayscale input camera', gray_frame)# cv2.waitKey()这个函数是在一个给定的时间内(单位ms)等待用户按键触发# 如果用户没有按下按键,则继续等待(循环)if (cv2.waitKey(10) & 0xFF) == ord('q'):breakif (cv2.waitKey(10) & 0xFF) == ord('c'):frame_name = f'camera_frame_{frame_index}.png'gray_frame_name = f'grayscale_camera_frame_{frame_index}.png'cv2.imwrite(frame_name, frame)cv2.imwrite(gray_frame_name, gray_frame)frame_index += 1else:breakcapture.release()
cv2.destroyAllWindows()

运行结果:

OpenCV入门(十七)快速学会OpenCV 16 视频处理相关推荐

  1. 【OpenCV入门教程之一】 OpenCV 2.4.8 +VS2010的开发环境配置

    目录(?)[-] 因为读研期间的研究方向是图像处理所以浅墨这段时间闭门研究了很多OpenCV和图像处理相关的知识与内容眼看自己积累到一定的程度了于是决定开始开设这个OpenCV系列专栏总结自己所学也分 ...

  2. 只要掌握这两个方法便可快速学会怎么剪裁视频尺寸

    当我们在制作视频时,偶尔会出现画面周边携带水印,或是尺寸比例不合适等情况,这时候就需要对视频的画面进行剪裁. 但是许多小伙伴还不明白怎么剪裁视频尺寸,其实很简单,只要借助工具即可轻松完成.所以我今天带 ...

  3. 缺流量、没创意?B站UP主如何快速学会爆款视频制作方法?

    当今时代是飞速发展的信息时代,尤其是短视频蓬勃发展,因为自媒体的起点是比较简单的,一台电脑.一部手机.一个人都可以玩转自媒体,所以现在自媒体作为热门行业,吸引了越来越多的人加入,各个平台上的热门作品也 ...

  4. 【OpenCV学习笔记2】OpenCV 完全安装 新增VS2010+OpenCV2.1,新增VS2010+OpenCV2.3.1

    OpenCV 完全安装 SkySeraph  Jun.1st 2010  HQU zgzhaobo@gmail.com  452728574 Latest Modified Date:Dec.12nd ...

  5. OpenCV入门(七)快速学会OpenCV6色彩空间

    OpenCV入门(七)快速学会OpenCV6色彩空间 作者:Xiou 1.色彩空间概述 色彩空间 (Color Space) 即以同的空间维度来表示某一色彩 (通常使用 3 个或者 4 个 值). R ...

  6. OpenCV入门(三)快速学会OpenCV2图像处理基础(一)

    OpenCV入门(三)快速学会OpenCV2图像处理基础(一) 作者:Xiou 1.颜色变换cvtColor imgproc的模块名称是由image(图像)和process(处理)两个单词的缩写组合而 ...

  7. 【OpenCV入门教程之十七】OpenCV重映射 SURF特征点检测合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/30974513 作者:毛星云(浅墨) ...

  8. 《OpenCV3编程入门-毛星云》第一部分 快速上手OpenCV

    平台:Win7 64bits + Visual Studio 2012 + OpenCV 2.4.10 接下来的很长一段时间我将沿着学习,记录整个学习过程和心得,既是自己的学习笔记,也为后来人提供一份 ...

  9. 【opencv入门篇】 10个程序快速上手opencv【上】

    导言:本系列博客目的在于能够在vs快速上手opencv,理论知识涉及较少,大家有兴趣可以查阅其他博客深入了解相关的理论知识,本博客后续也会对图像方向的理论进一步分析,敬请期待:) PS:官方文档永远是 ...

最新文章

  1. tf卡低级格式化_华为授权雷克沙nCARD评测:用了这么多年TF卡,该换换了
  2. 十个用Python实现的简单算法
  3. GDCM:gdcm::Dicts的测试程序
  4. 簡單SQL存儲過程實例
  5. Last non-zero Digit in N! HDU - 1066
  6. k8s源码Client-go中Reflector解析
  7. 解决VScode无法输出中文的问题
  8. 本地Markdown编辑器推荐
  9. 基于单片机无线防丢报警器设计过程分享
  10. Python 文字转语音(TTS)
  11. windows局域网共享文件
  12. bluescreen view-windows 蓝屏分析原因
  13. 机器学习(六)统计学习理论
  14. Redis——Lettuce的主从哨兵模式
  15. Emgucv不完整图像分割试验(十八)——Emgucv或opencv连接海康/萤石网络4G摄像头
  16. Java输出九九乘法表(99乘法)
  17. 通用Excel数据导入功能模板
  18. css template download
  19. 什么是BGP线路,跟普通线路有什么不同
  20. c语言整点报时,C语言编写一个简单整点报时工具源代码

热门文章

  1. 站在原地就是退步——除了死磕通道,云通讯服务商还该做些什么?
  2. Power Point常用快捷键
  3. 【计算机组成原理】:计算机系统概述
  4. XMLHttpRequest.onreadystatechange.readyState一直是1解决的一些方法
  5. MOOC浙江大学陈月、何钦铭老师《数据结构》学习笔记01
  6. K线形态识别_早晨(希望)之星和早晨(希望)十字星
  7. 场位方程——静电场问题(静电场的高斯定律+法拉第传导定律) | 偏微分方程(四)
  8. C语言循环水题,科学网—水文模型大本营 - 陈昌春的博文
  9. Lenovo win10触控板设置消失的解决办法
  10. H5页面底部前进、后退横栏怎么去除?