我们手机录制的视频一般都是1秒30帧的图像,也有24帧和60帧的。
有时候需要做数据集,需要进行录制视频,对图像提取出来。
那么如何提取呢。
我们可以看到一个每秒30帧的小猪佩奇视频,总时长不到3秒,最后被抽帧图片数量是74张,
看代码前,先来提示一下可能出现的错误。
当遇到以下报错:
cv2.error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-z4706ql7\opencv\modules\highgui\src\window.cpp:1274: error: (-2:Unspecified error) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Cocoa support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function 'cvShowImage'
这个估计是版本没下载好,删了重来
pip uninstall opencv-python
然后下载
pip3 install opencv-contrib-python
当然报错还有可能是路径带有中文或空格有时也会报错。
还有的保存是函数的版本不同,老版本返回的是三个参数,新版本却只有两个参数
比如
contours,heriachy = cv.findContours(binary,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
那么直接上本期代码
import cv2 import os if __name__ == "__main__": vc = cv2.VideoCapture('小猪佩奇.mp4') #读取需要处理的视频 if vc.isOpened(): #判读视频是否正常打开 print("打开ok") else: print("打开失败,程序退出") exit(-1) #如果不能正常打开则自动结束程序 savedpath = 'result/' #将生成的图片保存在result文件夹下面 isExists = os.path.exists(savedpath) #判断该存储图片的文件夹是否存在 if not isExists: #如果路径不存在则创建文件夹,否则提示文件夹已存在 os.makedirs(savedpath) print("创建存储路径") else: print("路径已经存在") c = 1 #设置抽帧图片的名称 while True: ok, frame = vc.read() #按帧读取视频,返回两个数值,第一个布尔值,False为读取到结尾,第二个是每帧图像 if ok: #如果能正常读取 cv2.imwrite(savedpath + str(c) + '.jpg', frame) # 保存图像,路径 加图像 print('完成第'+str(c)+'张图片的保存') #打印已保存的图片数量 c = c + 1 #每次命名加1 else: print("读取完成") #否则读取失败 break print("结束") #结束视频处理 vc.release() #需要释放
如果不想把每一帧都抽出来,比如只想一秒抽一帧的话,可以用以下代码,加个条件判断每隔30帧才进行图像抽帧
import cv2 import os if __name__ == "__main__": vc = cv2.VideoCapture('小猪佩奇.mp4') #读取需要处理的视频 if vc.isOpened(): #判读视频是否正常打开 print("打开ok") else: print("打开失败,程序退出") exit(-1) #如果不能正常打开则自动结束程序 savedpath = 'result/' #将生成的图片保存在result文件夹下面 isExists = os.path.exists(savedpath) #判断该存储图片的文件夹是否存在 if not isExists: #如果路径不存在则创建文件夹,否则提示文件夹已存在 os.makedirs(savedpath) print("创建存储路径") else: print("路径已经存在") c = 1 #设置抽帧图片的名称 i = 1 #设置第几帧图像 while True: ok, frame = vc.read() #按帧读取视频,返回两个数值,第一个布尔值,False为读取到结尾,第二个是每帧图像 if ok: #如果能正常读取 if i%30 == 0: #判断是否被30帧取余为0,来计算每隔一秒提取1帧图像 cv2.imwrite(savedpath + str(c) + '.jpg', frame) # 保存图像,路径 加图像 print('完成第'+str(c)+'张图片的保存') #打印已保存的图片数量 c = c + 1 #每次命名加1 i += 1 else: print("读取完成") #否则读取失败 break print("结束") #结束视频处理 vc.release() #需要释放
最后这个2秒多的视频只被抽出了两帧。
有需要写代码,或其他需求的可以加扣:334542894