opencv-python 视频处理
视频是由图片组成的,视频的每一帧就是一幅图片,一般是30帧,表示一秒钟显示30张图片。
opencv中可以用 VideoCapture 来捕获摄像头,用数字表示不同的设备,比如0,1。如果是视频文件,直接指定路径即可。
VideoCapture 类提供了初始化,打开视频文件或设备,视频帧捕获,视频文件或设备关闭,属性设置或获取等功能。
其成员函数isOpened用来检查视频是否能成功打开。
其成员函数get用于获取视频的一些参数或属性,比如帧率(cv2.CAP_PROP_FPS),视频的宽(cv2.CAP_PROP_FRAME_WIDTH),视频的高(cv2.CAP_PROP_FRAME_HEIGHT),视频的总帧数(cv2.CAP_PROP_FRAME_COUNT)。
其成员函数read用于捕获,解码并返回下一帧的视频图像。
1 视频读取
首先用video = cv2.VideoCapture('test.mp4') 来捕获视频类,然后用video.isOpened() 判断是否打开成功,如果打开成功,用video.read() 来循环读取每一帧图片,然后依次显示图片,waitKey可以控制帧率。
import cv2 #打开/显示视频
video = cv2.VideoCapture('D:/05.OpenCV图像处理课程资料/第2-7章notebook课件/图像操作/test.mp4') #参数改成0可以直接打开设备的摄像头
if video.isOpened():
print('视频打开成功')
while True:
ret,frame = video.read() # ret 视频捕获成功的标志,没有视频帧时返回false;frame 返回视频帧图像
if ret == False: #只要视频帧还没结束就继续读取
break
else:
cv2.imshow('frame',frame) #显示视频帧
if cv2.waitKey(10) == ord('q'): #按q结束视频播放
break
else:
print('视频打开失败')
video.release() #释放设备资源然后关闭显示窗口
cv2.destroyAllWindows()

如果要打开摄像头并显示图像的话,直接把代码中的捕获视频类改成 device = cv2.VideoCapture(0) 即可。
2 获取视频某些帧保存为图片
1)获取视频前两帧的图片
import cv2
video = cv2.VideoCapture('D:/05.OpenCV图像处理课程资料/第2-7章notebook课件/图像操作/test.mp4') #初始化视频类
if video.isOpened(): #video视频对象的成员函数,判断视频是否成功打开,返回bool类型
print('视频打开成功')
fps = video.get(cv2.CAP_PROP_FPS) #获取视频的帧率
fcount = video.get(cv2.CAP_PROP_FRAME_COUNT) #获取视频的总帧数
width = video.get(cv2.CAP_PROP_FRAME_WIDTH) #获取视频的宽
height = video.get(cv2.CAP_PROP_FRAME_HEIGHT) #获取视频的高
print('fps:',fps,'fcount:',fcount,'width:',width,'height:',height)
i=0
while True:
if i==2:
break #获取视频的前两帧
else:
i=i+1
ret,frame = video.read() #读取视频
cv2.imshow('frame'+str(i),frame) #显示视频帧
cv2.waitKey(0)
else:
print('视频打开失败')
cv2.destroyAllWindows()

2)截取视频的前n帧图像,保存到文件夹中
import cv2 #截取视频的前n帧图像,保存到文件夹中
frameNum=20 #需要截取的视频帧数
video = cv2.VideoCapture('D:/05.OpenCV图像处理课程资料/第2-7章notebook课件/图像操作/test.mp4') #初始化视频类
if video.isOpened(): #video视频对象的成员函数,判断视频是否成功打开,返回bool类型
print('视频打开成功')
i=0
while True:
if i==frameNum:
break #获取视频的前两帧
else:
i=i+1
ret,frame = video.read() #读取视频
# cv2.imshow('frame'+str(i),frame) #显示视频帧
cv2.imwrite('C:/Users/86188/Desktop/opencv/images/'+str(i)+'.png',frame)
cv2.waitKey(0)
else:
print('视频打开失败')
cv2.destroyAllWindows()

3)将视频分割为单帧图片并保存到指定文件夹,方法一(视频结束就停止读取保存图片,最终的图片数量时是609)
import cv2
video = cv2.VideoCapture('D:/05.OpenCV图像处理课程资料/第2-7章notebook课件/图像操作/test.mp4') #初始化视频类
if video.isOpened(): #video视频对象的成员函数,判断视频是否成功打开,返回bool类型
print('视频打开成功')
i=0
while True:
ret,frame = video.read() #读取视频
if ret==False:
break #只要视频帧还没结束就继续读取
else:
i=i+1
cv2.imwrite('C:/Users/86188/Desktop/opencv/images1/'+str(i)+'.png',frame)
cv2.waitKey(0)
print('i:',i)
else:
print('视频打开失败')
cv2.destroyAllWindows()

4)将视频分割为单帧图片并保存到指定文件夹,方法二(先计算视频帧总数,将所有视频帧读取保存,最终的图片数量时是622,609之后的图像是空的)
import cv2
video = cv2.VideoCapture('D:/05.OpenCV图像处理课程资料/第2-7章notebook课件/图像操作/test.mp4') #初始化视频类
fcount = video.get(cv2.CAP_PROP_FRAME_COUNT) #获取视频的总帧数
if video.isOpened(): #video视频对象的成员函数,判断视频是否成功打开,返回bool类型
print('视频打开成功')
i=0
while True:
ret,frame = video.read() #读取视频
if i==fcount:
break #只要视频帧还没结束就继续读取
else:
i=i+1
cv2.imwrite('C:/Users/86188/Desktop/opencv/images2/'+str(i)+'.png',frame)
cv2.waitKey(0)
print('i:',i)
else:
print('视频打开失败')
cv2.destroyAllWindows()

3 视频保存
opencv中提供了用于视频保存的类VideoWriter,该类可以将图像文件写入到视频文件中。
VideoWriter第一个参数filename表示目标存储的文件名或路径;第二个参数是fourcc,该参数由cv2.VideoWriter_fourcc返回。
VideoWriter_fourcc(c1, c2, c3, c4) -> retval
c1, c2, c3, c4 表示4字符 编码,表示视频编码格式,常用的有:
‘I’,‘4’,‘2’,‘0’ 或 *'I420':未压缩的YUV颜色编码,4:2:0色度子采样,兼容性好,但文件较大,文件扩展名.avi。
‘P’,‘I’,‘M’,‘1’ 或 *‘PIM1‘:MPEG-1编码类型,文件扩展名.avi。随机访问,灵活的帧率、可变的图像尺寸。
‘X’,‘V’,‘I’,‘D’ 或 *'XVID':MPEG-4编码类型,视频大小为平均值,MPEG4所需要的空间是MPEG1的1/10,它对运动物体可以保证有良好的清晰度,间/时间/画质具有可调性。文件扩展名.avi。
‘M’,‘P’,‘4’,‘V’ 或 *'MP4V':MPEG-4编码,这种编码器常用于存储和传输视频文件,例如MP4格式。
1)保存相机采集的视频
import cv2
device = cv2.VideoCapture(0) #用相机设备初始化视频捕获类
fourcc = cv2.VideoWriter_fourcc('I','4','2','0') #创建视频编解码器
fps = device.get(cv2.CAP_PROP_FPS) #没法直接获取摄像头的fps,只能逐步遍历每一帧并将当前帧数除以当前时间获得fps
print(fps)
width = device.get(cv2.CAP_PROP_FRAME_WIDTH)
height = device.get(cv2.CAP_PROP_FRAME_HEIGHT)
size = (int(width),int(height))
video = cv2.VideoWriter('./video_capture.avi',fourcc,25,size) #创建视频写入对象,这里直接用fps会报错,返回的fps为0
if video.isOpened():
if device.isOpened():
print('摄像头打开成功')
while True:
ret,frame = device.read()
video.write(frame)
cv2.imshow('device_frame',frame)
if cv2.waitKey(1) == ord('q'):
break
device.release()
cv2.destroyAllWindows()
else:
print('摄像头打开失败')
else:
print('视频保存失败')
print(fps)
通过VideoWriter创建视频写入对象,然后循环中用write把每一帧图像保存到文件对象中。摄像头采集的视频保存到当前文件夹下,文件名为 video_capture,文件格式为avi类型。
可以自定义视频的尺寸,也可以保存为mp4格式:
import cv2
device = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'mp4v') #mp4格式的编码
video = cv2.VideoWriter('./output.mp4',fourcc,20,(640,480))
if device.isOpened():
print('success')
while True:
ret,frame = device.read()
if ret == False:
break
else:
video.write(frame)
cv2.imshow('frame',frame)
if cv2.waitKey(1) == ord('q'):
break
else:
print('failed')
device.release()
video.release()
cv2.destroyAllWindows()
2)用图片文件创建视频
方法一:知道图片路径和图片名,图片名命名规范(如1.png,2.png),可以直接根据图片文件名称依次读入到视频文件中。
import cv2 #将images2文件夹下的图像合并为视频,方法一
path = './images2/'
fourcc = cv2.VideoWriter_fourcc('I','4','2','0') ##创建视频编解码器
fps = 2 #视频帧,每秒钟2帧图像
size = (960,544) #设置带转换图像的尺寸
video = cv2.VideoWriter('./images2/img2video.avi',fourcc,fps,size) #创建视频写入对象
if video.isOpened():
for item in range(622): #遍历图像并将其写入视频文件
item = str(item+1)
item = path + item + '.png' #图片路径
img = cv2.imread(item) #把图片读取出来
video.write(img) #写入到视频对象中
print(item)
video.release()
print('sucess')
else:
print('video failed')
方法二:用listdir返回文件中的所有图片(注意:返回的list列表是按照二进制进行排序,所以对于其他字符来说可能是乱序的)。然后用sort函数对图片进行排序,最后根据图片文件名称依次读入到视频文件中。
import os #文件操作库 将images1文件夹下的图像合并为视频,方法二
import cv2
path = './images1/'
filelist = os.listdir(path) #返回一个list列表,列表包含path中的所有文件,按照二进制进行排序,所以对于其他字符来说可能是乱序的
# filelist.remove('img2video.avi') #删除filelist中的avi视频,否则下面切片分割的时候,img2video没法转换成int会报错
filelist.sort(key=lambda x:int(x.split('.')[0])) #sort是排序函数,参数key可以自定义排序的标准,lambda是匿名函数,split()是分割函数,[0]取第一个切片
# filelist.sort(key=lambda x:int(x[:-4]) # x[:-4] 取倒数第四个之前的字符
print(filelist)
fourcc = cv2.VideoWriter_fourcc('I','4','2','0') #创建视频编解码器
fps = 25 #视频帧,每秒钟25帧图像
size = (960,544) #设置带转换图像的尺寸
video = cv2.VideoWriter('./images1/img2video.avi',fourcc,fps,size) #创建视频写入对象
if video.isOpened():
for item in filelist: #遍历图像并将其写入视频文件
if item.endswith('.png'): #将后缀为png的图像写入视频
item = path + item
img = cv2.imread(item)
video.write(img)
video.release() #释放资源
print('sucess')
else:
print('video failed')


浙公网安备 33010602011771号