视频是由一系列图像构成的,这一系列图像被称为帧,帧是以固定的时间间隔从视频中获取的,获取帧的速度称为帧速率,单位通常使用"帧/秒"表示,代表在1秒内所出现的帧数,对应英文FPS。Opencv提供了cv2.VideoCapture类和cv2.VideoWriter类来支持各种视频文件,在不同的操作系统中,它们支持的文件类型可能不同,但在所有操作系统中均支持AVI格式的视频文件。
一:VideoCapture类
它既能处理视频文件又能处理摄像头信息,该类的常用函数包含初始化、打开、帧捕获、释放、属性设置等
1、初始化
打开摄像头并完成对摄像头的初始化:
cap=cv2.VideoCapture("摄像头ID号")
"摄像头ID号":摄像头的ID编号,默认为-1,表示随机选择一个摄像头,如果有多个摄像头,则用数字"0"表示第一个摄
像头,"1"表示第二个摄像头,以此类推。若只有一个摄像头,既可以用"0",也可以用"-1"(个人建议用"0")。
cap:捕获对象,该类的对象
注:在视频处理完后,记得要释放摄像头对象
初始化视频文件:
cap=cv2.VideoCapture("视频地址")
2、cv2.VideoCapture.open()与cv2.VideoCapture.isopened()函数
在完成了摄像头初始化后,可以使用函数cv2.VideoCapture.isopened()来检查初始化是否成功。
retval=cv2.VideoCapture.isopened(cap)
cap:捕获对象
retval:若为True,表示获取成功,若为False,表示获取失败。
如果摄像头初始化失败,可以用cv2.VideoCapture.open()打开摄像头
retval=cv2.VideoCapture.open("摄像头ID号")
retval:若摄像头打开成功,则返回True
同样,cv2.VideoCapture.open()与cv2.VideoCapture.isopened()函数也可处理视频文件
3、捕获帧
初始化成功后就可以捕获帧信息
retval,image=cv2.VideoCapture.read()
retval:若捕获成功,返回True,否则False
image:捕获的帧,若没有帧被捕获,则该值为空
4、释放
当不使用摄像头时,需要将其关闭
None=cv2.VideoCapture.release()
如有一个VideoCapture类的对象cap,要将其释放。
cap.release()
5、属性设置
有是,我们需要获取cv.VideoCapture类对象的属性,或是更改该类对象的属性,可以直接用函数cv2.VideoCapture.get()获取cv2.VideoCapture类对象的属性。
retval=cv2.VideoCapture.get(propId)
propId:cv2.VideoCapture类对象属性。常见的如:宽、高、帧数等,具体的请自行查表
函数cv2.VideoCapture.set()用来设置cv2.VideoCapture类对象的属性
retval=cv2.VideoCapture.get(propId,value)
propId:cv2.VideoCapture类对象属性。
value:对应属性propId的值
如:cvc=cv.VideoCapture(0)
ret=cvc.set(cv2.CAP_PROP_FRAME_WIDTH,640)#设置当前帧的宽度为640像素
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()用来解码并返回一帧,故这两个函数可以用来获取多个摄像头的数据。
对于一组摄像头,可以使用如下代码来获取不同摄像头的视频帧:
success0=cameraCapture0.grab()#若成功指向下一帧,则返回True
success1=cameraCapture1.grab()
if success0 and success1:
retval0,image0=cameraCapture0.retrieve()#retval0:布尔值,若未成功,返回False,image2:返回的视频帧,如果未成功,则返回空图像
retval1,image1=cameraCapture1.retrieve()
二、捕获摄像头视频
import cv2
cap=cv2.VideoCapture(0)
while (cap.isOpened()):
ret,frame=cap.read()
cv2.imshow("frame",frame)
c=cv2.waitKey(1)#1ms一张,直到按下"ESC"键释放窗口
if c==27:
break
cap.release()
cv2.destroyAllWindows()
三、播放视频文件并保存为图片
import cv2
cap=cv2.VideoCapture('拜年.mp4') # 获取一个视频打开cap
isOpened=cap.isOpened # 判断是否打开
print(isOpened)
fps=cap.get(cv2.CAP_PROP_FPS)
# 获取宽度
width=int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# 获取高度
height=int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(fps,width,height)
i=0
while(isOpened):
# 保存前100帧
if i==100:
break
else:
i+=1
(flag,frame)=cap.read() # 读取每一帧
fileName='my_image\\'+str(i)+'.jpg'
print(fileName)
if flag==True:
cv2.imshow("frame",frame)#播放视频
cv2.waitKey(10)
cv2.imwrite(fileName,frame,[cv2.IMWRITE_JPEG_QUALITY,100])#保存图片
cap.release()
cv2.destroyAllWindows()
print('end!')
四、VideoWriter类
opencv中的cv2.VideoWriter类可以将图片序列保存成视频文件,也可以修改视频的各种属性,还可以对视频类型进行转换。
1、类函数介绍
该类常见的成员函数包括:构造函数、write函数等,下面对其做简单的介绍
A:构造函数
videoWriter = cv2.VideoWriter(filename, fourcc, fps, frameSize, isColor=None)
filename:指定输出目标视频的存放路径与文件名。若已存在,则会覆盖原有的。
fourcc:视频编解码格式,可以用函数cv2.VideoWriter_fourcc()来指定视频编码格式,cv2.VideoWriter_fourcc()有4个字符参数,它构成了编解码器的"4字标记",该标记可以缩写在一起(如:("I","4","2","0")可以缩写为(*"I420")),每个编解码器都有这样的一个标记。
常见的4字标记有:
(1):("I","4","2","0")表示未压缩的YUV颜色编码格式,该格式兼容性较好,但文件较大,扩展名:.avi
(2):("P","I","M","I"),表示MPEG-1编码格式,扩展名:.avi
(3):("X","V","I","D"),表示MPEG-4编码,该视频大小适中,扩展名:.avi
(4):("T","H","E","O"),表示Ogg Vorbis编码格式,扩展名为:.ogv
(5):("F","L","V","I"),表示Flash视频,扩展名为:.flv
fps:帧速率
frameSize:每一帧的长宽
isColor:是否为彩色图
B、write函数
cv2.VideoWriter类中的cv2.VideoWriter.write()用于写入下一帧视频,
None=cv2.VideoWriter.write(image)
image:要写入的视频帧,通常情况下,要求彩色图像格式为BGR
C、释放
在不需要cv2.VideoWriter类对象时,要将其释放。
None=cv2.cv2.VideoWriter.release()
如:当前有一个cv2.VideoWriter类对象out,则采用一下方法将其释放
out.release()
#########将文件夹下的图片保存为视频文件#######
import cv2
import os
videoWriter = cv2.VideoWriter('out.avi', cv2.VideoWriter_fourcc(*"I420"), 20, (720,720))
im_names=os.listdir("my_img_file/")
for filename in im_names:
imgname="F:\my_project\opencv\img\\"+filename
frame=cv2.imread(imgname)
frame=cv2.resize(frame,(720,720))
cv2.imshow("frame", frame)
videoWriter.write(frame)
cv2.waitKey(1)
videoWriter.release()
###########保存摄像头捕获的视频文件############
import cv2
cap = cv2.VideoCapture(0)
cap.set(3,640)#宽
cap.set(4,480)#高
#此处fourcc的在MAC上有效,如果视频保存为空,那么可以改一下这个参数试试, 也可以是-1
fourcc = cv2.VideoWriter_fourcc(*("I420"))
# 第三个参数则是镜头快慢的,10为正常,小于10为慢镜头
out = cv2.VideoWriter('out.avi', fourcc,10,(640,480))
while True:
ret,frame = cap.read()
if ret == True:
a = out.write(frame)
cv2.imshow("frame", frame)
if cv2.waitKey(1) & 0xFF == ord('1'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()