![](https://img.haomeiwen.com/i7691822/960e37f07af562f5.png)
视频处理
OpenCV提供了cv2.VideoCapture类和cv2.VideoWriter类来支持各种类型的视频文件。在不同的操作系统中,它支持的文件类型可能有所不用,但是在各操作系统中均支持AVI格式的视频文件
1. VideoCapture类
OpenCV提供了cv2.VideoCapture类来处理视频。cv2.VideoCapture类处理视频的方式非常简单、快捷,而且它既能处理视频文件又能处理摄像头信息。cv2.VideoCapture类的常用函数包括初始化、打开、帧捕捉、释放、属性设置等,下面对这些函数进行简单的介绍
1.初始化
OpenCV为cv2.VideoCapture类提供了构造函数cv2.VideoCapture(),用于打开摄像头并完成摄像头的初始化工作。该函数的语法格式为:
捕捉对象 = cv2.VideoCapture(“摄像头ID号”)
-"摄像头ID号"就是摄像头的ID号码。需要注意的是,这个参数是摄像设备的ID编号,而不是文件名。其默认值为-1,表示随机选取一个摄像头;如果有多个摄像头,则用数字“0”表示第1个摄像头,用数字“1”表示第2个摄像头,以此类推。所以,如果只有一个摄像头,既可以使用“0”,也可以使用“-1”作为摄像头的ID号。在某些平台上,如果该参数值为“-1”,OpenCV会弹出一个窗口,让用户手动选择希望使用的摄像头
-“捕捉对象”为返回值,是cv2.VideoCapture类的对象
在使用cv2.VideoCapture()进行视频处理时,处理完成后,要释放摄像头对象。该构造函数也能够初始化视频文件,初始化视频文件是,参数为文件名。
捕捉对象 = cv2.VideoCapture(“文件名”)
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.
3.捕获帧
摄像头初始化成功后,就可以从摄像头中捕获信息了,捕获帧所使用的是函数cv2.VideoCapture.read()。该函数的语法是:
retval, img = cv2.VideoCapture.read()
- -img是返回的捕捉到的帧,如果没有帧被捕获,该值为空
- -retval表示捕获是否成功,如果成功则该值为True,不成功则为False
4.释放
在不需要摄像头时,要关闭摄像头。关闭摄像头使用的是函数cv2.VideoCapture.release()。该函数的语法格式是:
None = cv.VideoCapture.release()
例如,当前有一个VideoCapture类的对象cap,要将其释放,语句为:cap.release()
5.属性设置
有时,我们需要获取cv2.VideoCapture类对象的属性,或是更改该类对象的属性。函数cv2.VideoCapture.get()用于获取cv2.VideoCapture类对象的属性,该函数的语法格式是:
retval = cv.VideoCapture.get(propId)
-
-propId对应着cv2.VideoCapture类对象的属性
函数cv2.VideoCapture.set()用来设置cv2.VideoCapture类对象的属性。该函数的语法是:
etval = cv.VideoCapture.set(propId, value)
- -propId对应着cv2.VideoCapture类对象的属性
- -value对应属性propid的值
值 | propId | 含义 |
---|---|---|
cv2.CAP_PROP_POS_MSEC | 0 | 视频文件的当前位置(以ms为单位)或以视频被捕获时的时间戳 |
cv2.CAP_PROP_POS_FRAMES | 1 | 接下来要解码/捕获的帧的索引从0开始 |
cv2.CAP_PROP_POS_AVI_RATIO | 2 | 视频文件相对位置:0表示视频的开始,1表示视频的结束 |
cv2.CAP_PROP_FRAME_WIDTH | 3 | 帧的宽度 |
cv2.CAP_PROP_FRAME_HEIGHT | 4 | 帧的高度 |
cv2.CAP_PROP_FPS | 5 | 帧速 |
cv2.CAP_PROP_FOURCC | 6 | 用4个字符表示的视频编码器格式 |
cv2.CAP_PROP_FRAME_COUNT | 7 | 帧数 |
6.cv2.VideoCapture.grab()函数和cv2.VideoCapture.retrieve()函数
一般情况下,如果需要读取一个摄像头的视频数据,最简单的方法就是使用函数cv2.VideoCapture.read()。但是,如果需要同步一组或多个摄像头的视频数据时,该函数就无法胜任了。可以把函数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()用来解码,并返回函数cv2.VideoCapture.grab()捕获的视频帧。其函数语法格式为:
retval, image = cv2.VideoCapture.retrieve()
-
-image为返回的视频帧,如果未成功,则返回一个空图像
-
-retval为布尔值,若未成功,则返回False,否则,返回True
对于一组摄像头,可以使用如下代码捕获不同摄像头的视频帧:
success0 = cameraCapture0.grap()
success1 = cameraCapture1.grap()
if success0 and success1
frame0 = cameraCapture0.retrieve()
frame1 = cameraCapture1.retrieve()
cap = cv2.VideoCapture(0)
cap = cv2.VideoCapture('test.avi')
cap.isopened()
cap.open()
retval, img = cap.read()
cap.release()
cap.get(cv2.CAP_PROP_FRAME_WIDTH)
cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
cap.set(cv2.CAP_PROP_FRAME_WIDTH,640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
2. VideoWriter类
OpenCV中的cv2.VideoWriter类可以将图片序列保存成视频文件,也可以修改视频中各种属性,还可以完成对视频类型的转换。cv2.VideoWriter类常用的成员函数包括:构造函数、write()函数等
1.构造函数
OpenCV为cv2.VideoWriter类提供了构造函数,用它来实现初始化工作。该函数的语法格式是:
<VideoWriter, object> = cv.VideoWriter(filename, fourcc, fps, frameSize[, isColor])
- -filename指定输出目标视频的存放路径和文件名。如果指定的文件名已经存在,则会覆盖这个文件
- -fourcc表示视频编/解码类型(格式)。在OpenCV中用函数cv2.VideoWriter_fourcc()来指定视频编码格式。cv2.VideoWriter_fourcc()有4个字符参数。这4个字符参数构成了编/解码器“4字标记”,每个编/解码器都有一个这样的标记。下面列出几个常用的标记
cv2.VideoWriter_fourcc() | 意义 | 文件扩展名 |
---|---|---|
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视频 | .fly |
若想了解更多字符参数组合,可以在网站http://www.fourcc.org上查询。若参数fourcc为“-1”则程序运行时会弹出一个对话框。在该对话框中,用户可以根据自己的需要选择合适的压缩程序和压缩质量
- -fps为帧速率
- -frameSize为每一帧的长和宽
- -isColor表示是否为彩色图像
2.write函数
cv2.VideoWriter类中的函数cv2.VideoWriter.write()用于写入下一帧视频。该函数的语法格式为:
None = cv2.VideoWriter.write(img)
- -img要写入的视频帧。通常情况下,要求彩色图像的格式为RGB格式
3.释放
在不需要cv2.VideoWriter类对象时,需要将其释放。释放该对象所使用的函数是cv2.VideoWriter.release()。该函数的语法格式是:
None = cv2.VideoWriter.release()
out = cv2.VideoWriter(...)
out.write(img)
out.release()
播放视频文件
播放视频文件时,需要将函数cv2.VideoCapture()的参数值设置为视频文件的名称。在播放时,可以通过设置函数cv2.waitKey()中的参数值,来设置播放视频时每一帧(停留)时间。如果函数cv2.waitKey()中的参数值较小,则说明每一帧停留的时间较短,视频播放速度会较快;如果较大,则说明每一帧停留的时间较长,视频播放速度较慢。通常情况下设置为25(ms)
import cv2
import numpy as np
cap = cv2.VideoCapture("videoData/output.avi")
while(cap.isOpened()):
ret, frame = cap.read()
cv2.imshow("frame", frame)
c = cv2.waitKey(1)
if c == 27:
break
cap.release()
cv2.destroyAllWindows()
保存摄像头视频文件
import cv2
import numpy as np
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()
参考文献
《OpenCV轻松入门》 李立宗著
OpenCV官方文档:https://docs.opencv.org/4.1.2/dc/d4d/tutorial_py_table_of_contents_gui.html
网友评论