Author:qyan.li
Date:2022.6.19
Topic:借助于OpenCV将多帧图像合并为视频及OpenCV录制视频并保存
一、写在前面
~~~~~~~~ 最近一直在网络上检索借助于OpenCV如何将多帧图像合并为视频,了解到可以借助于VideoWrite()函数实现,顺便学习一下VideoWriter函数使用,以及借助于此函数实现摄像头视频录制并保存以及将多帧图片合成为视频。
二、视频录制保存
老样子,先上代码,方便大家参考借鉴:
def VideoWrite_Function():
cap = cv2.VideoCapture(0)
# ## 输出摄像屏幕的大小尺寸
# width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# print("width:", width, "height:", height) ## width = 640,height = 480
fourcc = cv2.VideoWriter.fourcc('m', 'p', '4', 'v') # 指定输出视频的格式
## VideoWriter(fileName,fourcc,fps,frameSize[:,iscolor])创建VideoWriter对象
## 调用摄像头录制视频并保存时,文件后缀名为mp4无法正常播放,改为mp4v后可以正常进行播放
## 参考文献:https://blog.csdn.net/bgmcat/article/details/120751531
out = cv2.VideoWriter('./output.mp4v', fourcc, 20, (640,480))
while (cap.isOpened()):
## 添加判断,相机是否成功打开
ret, frame = cap.read()
if ret:
## 调用Canny进行图像的边缘检测
# frame = cv2.Canny(frame, 100, 200)
out.write(frame)
cv2.imshow('video', frame)
c = cv2.waitKey(1)
if c == 27:
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
关于此代码几处说明:
- cap = cv2.VideoCapture(0)用于获取笔记本电脑默认的内置摄像头,若外接的摄像头改变传入的参数即可
- fourcc = cv2.VideoWriter.fourcc(‘m’, ‘p’, ‘4’, ‘v’)用于指定输出视频的格式,还有其他诸多格式可供修改,请自行检索
- VideoWriter()构造函数->VideoWriter(filePath,Videotype,fps,frameSize),类的实例化完成后,借助于write()函数写入frame即可
- VideoWriter()构造函数中传入的frameSize必须与自身电脑相一致,可借助于注释的代码进行确定
- 输出视频的文件后缀必须为mp4v,而不是mp4,否则视频可以正常保存,但无法正常外部播放
三、多帧图片合成为视频
老样子,先上代码,方便大家参考借鉴:
def createVideo(filePath):
## 创建视频合成格式
fourcc = cv2.VideoWriter.fourcc('m', 'p', '4', 'v') # 指定输出视频的格式
## VideoWriter(fileName,fourcc,fps,frameSize[:,iscolor])创建VideoWriter对象
## 此处的图像大小必须与原始图像的大小保持一致,否则会报错
out = cv2.VideoWriter('./TestOutput.mp4', fourcc, 5, (220,480)) # 此处的frame.shape = (480, 220, 3)
## filePath即为图片保存路径
fileNames = os.listdir(filePath)
print(fileNames)
for file in fileNames:
## 错误:cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'
## 代码中出现任何问题基本上都会报此错误,检查代码即可,不必过分纠结于错误提示
# frame = cv2.imread('./' + str(file))
frame = cv2.imread(str(filePath) + '/' + str(file))
# print(frame.shape)
out.write(frame)
cv2.imshow('video',frame)
c = cv2.waitKey(1)
if c == 27:
break
out.release()
cv2.destroyAllWindows()
关于此代码的几点小说明:
- VideoWriter的write方法写入的对象为imread后返回的对象,图像必须经imread函数读取
- VideoWriter构造函数中frameSize也必须与图片大小相匹配,但与摄像头录制不同,此处需要变换下位置,即frame.shpe输出(480, 220, 3),构造函数中填入(220,480)
- 此处使用mp4的文件后缀名即可,不必使用mp4v
三、小总结
~~~~~~~~ 总结一下,代码的核心在于VideoWriter()类的构造和使用,使用有两个注意点:
-
VideoWriter()类中最后一个参数frameSzie需要与电脑屏幕,图片大小相适应,将多帧图片合成视频时需要将图片大小反序构成元组传入
-
VideoWriter()类的write方法传入的并非图片本身,而是cap.read或者imread后的对象
另外,有关图像保存的一个注意事项:
-
摄像头录制视频的保存文件后缀名不能为mp4,否则视频无法正常播放,改为mp4v,其他格式应该也可,自己并未尝试,注意需要与fourcc相匹配
最后,关于程序执行的一个注意事项:
-
报错
cv2.error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'
,根据自己的代码调试经验,无论程序出现什么错误,基本都会出现这个错误,不必过分纠结于报错信息,关注代码。