视频抽帧实践---openCV和decord视频编解码

2022-08-11 20:02:31 浏览数 (1)

背景:

剪辑平台中需要处理大量的视频,对视频内容的理解,离不开对视频的降维操作,一般流程是进行抽帧。抽帧操作是很多视频处理的第一步,也是基础数据的一步,大量算法模型离不开帧数据的训练,而高质量的视频,它的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.

0 人点赞