OpenCV学习笔记(十三)——视频处理

视频信号(以下简称为视频)是非常重要的视觉信息来源,它是视觉处理过程中经常要处理的一类信号。实际上,视频是由一系列图像构成的,这一系列图像被称为帧,帧是以固定的时间间隔从视频中获取的。获取(播放)帧的速度称为帧速率,其单位通常使用“帧/秒”表示,代表在1 秒内所出现的帧数,对应的英文是FPS(Frames Per Second)。如果从视频中提取出独立的帧,就可以使用图像处理的方法对其进行处理,达到处理视频的目的。

1. VideoCapture 类

cv2.VideoCapture 类的常用函数包括初始化、打开、帧捕获、释放、属性设置等,下面对这些函数进行简单的介绍。

1.1 类函数介绍
1.1.1 初始化

OpenCV 为cv2.VideoCapture 类提供了构造函数cv2.VideoCapture(),用于打开摄像头并完成摄像头的初始化工作。该函数的语法格式为:

捕获对象=cv2.VideoCapture("摄像头ID 号")

  • “摄像头ID 号”就是摄像头的ID 号码。需要注意的是,这个参数是摄像设备(摄像头)的ID 编号,而不是文件名。其默认值为-1,表示随机选取一个摄像头;如果有多个摄像头,则用数字“0”表示第1 个摄像头,用数字“1”表示第2 个摄像头,以此类推。所以,如果只有一个摄像头,既可以使用“0”,也可以使用“-1”作为摄像头ID 号。在某些平台上,如果该参数值为“-1”,OpenCV 会弹出一个窗口,让用户手动选择希望使用的摄像头。
  • “捕获对象”为返回值,是cv2.VideoCapture 类的对象。

OpenCV 官网在介绍函数cv2.VideoCapture()时,特别强调:视频处理完以后,要记得释放摄像头对象。

该(构造)函数也能够用于初始化视频文件,初始化视频文件时,参数为文件名。此时函数的形式为:

捕获对象=cv2.VideoCapture("文件名")

1.1.2 cv2.VideoCapture.open()函数和cv2.VideoCapture.isOpened()函数

一般情况下,使用cv2.VideoCapture()函数即可完成摄像头的初始化。有时,为了防止初始化发生错误,可以使用函数cv2.VideoCapture.isOpened()来检查初始化是否成功。该函数的语法格式为:

retval = cv2.VideoCapture.isOpened()

  • 如果成功,则返回值retval为True。
  • 如果不成功,则返回值retval为False。

如果摄像头初始化失败,可以使用函数 cv2.VideoCapture.open()打开摄像头。该函数的语法格式为:

retval = cv2.VideoCapture.open( index )

  • index 为摄像头ID 号。
  • retval 为返回值,当摄像头(或者视频文件)被成功打开时,返回值为True。

同样,函数 cv2.VideoCapture.isOpened()和函数cv2.VideoCapture.open()也能用于处理视频文件。在处理视频文件时,函数cv2.VideoCapture.open()的参数为文件名,其语法格式为:

retval = cv2.VideoCapture.open( filename )

1.1.3 捕获帧

摄像头初始化成功后,就可以从摄像头中捕获帧信息了。捕获帧所使用的是函数cv2.VideoCapture.read()。该函数的语法是:

retval, image=cv2.VideoCapture.read()

  • image 是返回的捕获到的帧,如果没有帧被捕获,则该值为空。
  • retval 表示捕获是否成功,如果成功则该值为True,不成功则为False。
1.1.4 释放

在不需要摄像头时,要关闭摄像头。关闭摄像头使用的是函数cv2.VideoCapture.release()。该函数的语法是:

None=cv2.VideoCapture.release()

1.1.5 属性设置

有时,我们需要获取cv2.VideoCapture 类对象的属性,或是更改该类对象的属性。函数cv2.VideoCapture.get()用于获取cv2.VideoCapture 类对象的属性,该函数的语法格式是:

retval = cv2.VideoCapture.get( propId )

式中,参数propId 对应着cv2.VideoCapture 类对象的属性。
例如,有一个cv2.VideoCapture 类对象cvc,则:

  • 通过 cvc.get(cv2.CAP_PROP_FRAME_WIDTH),就能获取当前帧对象的宽度。
  • 通过 cvc.get(cv2.CAP_PROP_FRAME_HEIGHT),就能获取当前帧对象的高度。

函数 cv2.VideoCapture.set()用来设置cv2.VideoCapture 类对象的属性。该函数的语法是:

retval = cv2.VideoCapture.set( propId, value )

式中,propId 对应cv2.VideoCapture 类对象的属性,value 对应属性propid 的值。例如,有一个cv2.VideoCapture 类对象cvc,则:

  • 语句 ret = cvc.set(cv2.CAP_PROP_FRAME_WIDTH, 640)将当前帧对象的宽度设置为640 像素。
  • 语句 ret = cvc.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)将当前帧对象的高度设置为480 像素。

cv2.VideoCapture 类对象的属性值及含义如表所示。
在这里插入图片描述
在这里插入图片描述

1.1.6 cv2.VideoCapture.grab()函数和cv2.VideoCapture.retrieve()函数

一般情况下,如果需要读取一个摄像头的视频数据,最简便的方法就是使用函数cv2.VideoCapture.read()。但是,如果需要同步一组或一个多头(multihead)摄像头(例如立体摄像头或Kinect)的视频数据时,该函数就无法胜任了。可以把函数cv2.VideoCapture.read()理解为是由函数cv2.VideoCapture.grab() 和函数cv2.VideoCapture.retrieve() 组成的。函数cv2.VideoCapture.grab()用来指向下一帧,函数cv2.VideoCapture.retrieve()用来解码并返回一帧。

因此,可以使用函数cv2.VideoCapture.grab()和函数cv2.VideoCapture.retrieve()获取多个摄像头的数据。

函数 cv2.VideoCapture.grab()用来指向下一帧,其语法格式是:

retval= cv2.VideoCapture.grab( )

如果该函数成功指向下一帧,则返回值retval 为True。

函数 cv2.VideoCapture.retrieve()用来解码,并返回函数v2.VideoCapture.grab()捕获的视频帧。该函数的语法格式为:

retval, image = cv2.VideoCapture.retrieve( )

  • image 为返回的视频帧,如果未成功,则返回一个空图像。
  • retval 为布尔型值,若未成功,返回False;否则,返回True。

对于一组摄像头,可以使用如下代码捕获不同摄像头的视频帧:

success0 = cameraCapture0.grab()
success1 = cameraCapture1.grab()
if success0 and success1:
	frame0 = cameraCapture0.retrieve()
	frame1 = cameraCapture1.retrieve()

与 VideoCapture 类内的其他函数一样,cv2.VideoCapture.grab()和cv2.VideoCapture.retrieve()也能用来读取视频文件。

1.2 捕获摄像头视频

计算机视觉要处理的对象是多种多样的。有时,我们需要处理的可能是某个特定的图像;有时,要处理的可能是磁盘上的视频文件;而在更多时候,要处理的是从摄像设备中实时读入的视频流。

import numpy as np
import cv2
cap = cv2.VideoCapture(0)
while(cap.isOpened()):
	ret, frame = cap.read()
	cv2.imshow('frame',frame)
	c = cv2.waitKey(1)
	if c==27: #ESC 键
		break
cap.release()
cv2.destroyAllWindows()
1.3 播放视频文件

播放视频文件时,需要将函数cv2.VideoCapture()的参数值设置为视频文件的名称。在播放视频时,可以通过设置函数cv2.waitKey()中的参数值,来设置播放视频时每一帧的持续(停留)时间。如果函数cv2.waitKey()中的参数值:

  • 较小,则说明每一帧停留的时间较短,视频播放速度会较快。
  • 较大,则说明每一帧停留的时间较长,视频播放速度会较慢。

该参数的单位是ms,通常情况下,将这个参数的值设置为25即可。

import numpy as np
import cv2
cap = cv2.VideoCapture('viptrain.avi')
while(cap.isOpened()):
	ret, frame = cap.read()
	cv2.imshow('frame',frame)
	c = cv2.waitKey(25)
	if c==27: #ESC 键
		break
cap.release()
cv2.destroyAllWindows()

在这里插入图片描述

2. VideoWriter 类

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

2.1 类函数介绍

cv2.VideoWriter 类常用的成员函数包括:构造函数、write 函数等。本节简单介绍这两个常用的函数。

2.1.1 构造函数

OpenCV 为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。
    · cv2.VideoWriter_fourcc(‘F’, ‘L’, ‘V’, ‘I’)表示Flash 视频,生成的文件的扩展名为.flv。

欲知更多的字符参数组合,可以在网站http://www.fourcc.org 上查询。若参数fourcc为“-1”,则程序运行时会弹出一个对话框,如图所示。在该对话框中,用户可以根据自己的需要选择合适的压缩程序和压缩质量。

在这里插入图片描述

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

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

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

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

None=cv2.VideoWriter.write(image)

式中,image 是要写入的视频帧。通常情况下,要求彩色图像的格式为BGR 模式。

在调用该函数时,直接将要写入的视频帧传入该函数即可。例如,有一个视频帧为frame,要将其写入上面的示例中名为out 的cv2.VideoWriter 类对象内,则使用语句:out.write(frame)

上述语句会把frame 传入名为output.avi 的out 对象内。

2.1.3 释放

在不需要cv2.VideoWriter 类对象时,需要将其释放。释放该类对象时所使用的是函数cv2.VideoWriter.release()。该函数的语法格式是:

None = cv2.VideoWriter.release( )

例如,当前有一个cv2.VideoWriter 类的对象out,可以用以下语句将其释放:out.release()

2.2 保存视频

保存视频包括创建对象、写入视频、释放对象等多个步骤,下面对各个步骤做简单的介绍。

2.2.1 创建对象

在创建对象前,首先需要设置好参数。

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

out = cv2.VideoWriter( filename , fourcc , fps , size )

当然,也可以直接在构造函数内用需要的参数值创建对象。例如:

out = cv2.VideoWriter('out.avi',fourcc, 20, (640,480))

2.2.2 写入视频

用函数 cv2.VideoWriter.write()在创建的对象out 内写入读取到的视频帧frame。使用的代码为:

out.write(frame)

2.2.3 释放对象

在完成写入后,释放对象out。代码为:

out.release()

import numpy as np
import cv2
cap = 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:
			break
	else:
		break
cap.release()
out.release()
cv2.destroyAllWindows()

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

3. 视频操作基础

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

import numpy as np
import cv2
cap = cv2.VideoCapture('viptrain.avi')
while(cap.isOpened()):
	ret, frame = cap.read()
	frame=cv2.Canny(frame,100,200)
	cv2.imshow('frame',frame)
	c = cv2.waitKey(1)
	if c==27: #ESC 键
		break
cap.release()
cv2.destroyAllWindows()

在这里插入图片描述

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值