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可以控制帧率。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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)获取视频前两帧的图片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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帧图像,保存到文件夹中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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之后的图像是空的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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)保存相机采集的视频
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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),可以直接根据图片文件名称依次读入到视频文件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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函数对图片进行排序,最后根据图片文件名称依次读入到视频文件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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' ) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!