背景:
剪辑平台中需要处理大量的视频,对视频内容的理解,离不开对视频的降维操作,一般流程是进行抽帧。抽帧操作是很多视频处理的第一步,也是基础数据的一步,大量算法模型离不开帧数据的训练,而高质量的视频,它的fps(每秒帧数)很大,这就造成了处理高清视频时,抽帧速度会成为整个视频处理的瓶颈,本文将对比目前主流的两个视频读取库, openCV和decord进行对比。
流程:
我们以m3u8文件流进行测试,m3u8视频流,是有多个连续的ts文件组成,浏览器加载ts序列,每个ts是一定的时间连续不断的进行播放,我们按照固定帧率进行抽取,并裁减,最后保存图片,流程如下:
一.使用opecv 进行抽帧
代码语言:javascript复制cap = cv2.VideoCapture(ts_url)
fra_num = cap.get(cv2.CAP_PROP_FRAME_COUNT) # 获取帧数
rate = cap.get(cv2.CAP_PROP_FPS) # 获取帧率
logger.info(f'帧数 {fra_num}')
logger.info(f'帧率 {rate}')
duration = fra_num / rate
logger.info(f'时长 {duration}')
logger.info('file_basename is {}'.format(file_basename))
for j in range(0, int(fra_num)):
if j % archive_fps == 0:
start_time = time.time()
cap.set(1, int(j))
rval, frame = cap.read()
if rval:
cv2.imwrite(os.path.join(pic_folder, image_name), frame)
二.使用decord进行抽帧
代码语言:javascript复制vr = VideoReader(BytesIO(res.content), ctx=cpu(0))
fra_num = len(vr)
try:
frames = vr.get_batch(list(range(fra_num))[::archive_fps]).asnumpy()
except Exception as exc:
logger.error('{} decord stream err {}'.format(req_id, exc))
for frame in frames:
frame = resize_image(frame)
image_name = file_basename '-' str(prefix) '-' str(count) config.PIC_SUFFIX
cv2.imwrite(os.path.join(pic_folder, image_name), frame)
logger.info('{} get frame and save {} done!'.format(req_id, image_name))
三.性能对比:
在decord github主页上(https://github.com/dmlc/decord),贴出了decord 的benchmark 性能对比
可以看到decord基本是opcv的10倍,
四.裁切代码
代码语言:javascript复制def resize_image(image):
"""
压缩大图片的大小
:param image:
:return:
"""
height, width = image.shape[0], image.shape[1]
if height > width:
n_width = 256
n_height = (height / width) * 256
else:
n_height = 256
n_width = (width / height) * 256
img_new = cv2.resize(image, (int(n_width), int(n_height)))
return img_new
五.结果对比
对于标准的硬编m3u8流,处理25fps 5分钟的视频片段,使用opecv抽帧裁剪保存图片大概需要20mins,而使用decord处理这个过程只需要2mins,基本也是符合官方10倍这个数量级的benchmark.
踩坑:
我电脑使用的是python base interpreter 是python3.9,所以虚拟环境pip也是3.9版本,使用公司内部的仓库进行安装decord,总是提示如下:
试了很多遍也不行,然后进到公司的python package仓库
可以看到是有decord的,但是为啥总是提示上面的错误。google了就说要重新安装下python,或者重新删掉venv都不是太靠谱,还有建议用源码裸装的,自己也不想太麻烦,总感觉这是个小问题,后来静下心来重新看下,发现公司的这个库里没有cp39这个包,难怪装不了,因为我是python3.9
然后果断换成python 3.7,一次性安装成功
pip install --index-url https://mirrors.aliyun.com/pypi/simple/ decord==0.6.0
根据截图显示所获取的中央仓库的decord python包安装,目前只支持3.6 3.7 3.8.