其实OpenCV已经提供了写视频的接口,但是编码和文件后缀的对应真是让人头疼,动不动就不支持。经过尝试,总结出目前两种可以正常写入视频的对应关系:
MJPG --> .avi
mp4v -->.mp4
一、编码MJPG、后缀.avi
MJPG是大写!!!
# coding=utf-8
from __future__ import absolute_import, division, print_function
import cv2
import warnings
import numpy as np
warnings.simplefilter("always")
class VideoWriter:
def __init__(self, name, width, height, fps=25):
# type: (str, int, int, int) -> None
if not name.endswith('.avi'): # 保证文件名的后缀是.avi
name += '.avi'
warnings.warn('video name should ends with ".avi"')
self.__name = name # 文件名
self.__height = height # 高
self.__width = width # 宽
fourcc = cv2.VideoWriter_fourcc(*'MJPG') # 如果是avi视频,编码需要为MJPG
self.__writer = cv2.VideoWriter(name, fourcc, fps, (width, height))
def write(self, frame):
if frame.dtype != np.uint8: # 检查frame的类型
raise ValueError('frame.dtype should be np.uint8')
# 检查frame的大小
row, col, _ = frame.shape
if row != self.__height or col != self.__width:
warnings.warn('长和宽不等于创建视频写入时的设置,此frame不会被写入视频')
return
self.__writer.write(frame)
def close(self):
self.__writer.release()
def main():
width = 512
height = 256
vw = VideoWriter('test.avi', width, height)
for i in range(25*50):
# 随机生成一幅图像
frame = np.random.randint(0, 255, (height, width, 3), dtype=np.uint8)
# 写入图像
vw.write(frame)
vw.close()
if __name__ == '__main__':
main()
二、编码mp4v、后缀.mp4
mp4v是小写!!!
# coding=utf-8
from __future__ import absolute_import, division, print_function
import cv2
import warnings
import numpy as np
warnings.simplefilter("always")
class VideoWriter:
def __init__(self, name, width, height, fps=25):
# type: (str, int, int, int) -> None
if not name.endswith('.mp4'): # 保证文件名的后缀是.mp4
name += '.mp4'
warnings.warn('video name should ends with ".mp4"')
self.__name = name # 文件名
self.__height = height # 高
self.__width = width # 宽
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 如果是mp4视频,编码需要为mp4v
self.__writer = cv2.VideoWriter(name, fourcc, fps, (width, height))
def write(self, frame):
if frame.dtype != np.uint8: # 检查frame的类型
raise ValueError('frame.dtype should be np.uint8')
# 检查frame的大小
row, col, _ = frame.shape
if row != self.__height or col != self.__width:
warnings.warn('长和宽不等于创建视频写入时的设置,此frame不会被写入视频')
return
self.__writer.write(frame)
def close(self):
self.__writer.release()
def main():
width = 512
height = 256
vw = VideoWriter('test.mp4', width, height)
for i in range(25*50):
# 随机生成一幅图像
frame = np.random.randint(0, 255, (height, width, 3), dtype=np.uint8)
# 写入图像
vw.write(frame)
vw.close()
if __name__ == '__main__':
main()
三、视频写入失败的原因
不支持对应的编码和后缀。目前我知道支持的是:
- mp4v–>.mp4
- MJPG–>.avi
frame的值类型不是uint8。
frame的高或者宽和新建cv2.VideoWriter设置的高或宽不对应。