前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于OpenCv-Python的视频组合

基于OpenCv-Python的视频组合

作者头像
月见樽
发布2018-04-27 11:38:00
1.7K0
发布2018-04-27 11:38:00
举报

step0:概述

  • 动机:手头有数个20秒左右的短视频(守望先锋最佳镜头),期望能组合成一个长视频

英雄不朽,图片来源http://upload-images.jianshu.io/upload_images/7241055-b71baeb2d99c0e77.jpg

  • 技术路线:opencv+python(opencv在Python中的封装库是cv2,依赖于numpy)

step1:打开并显示视频

要组合视频,首先需要打开视频并获取每一帧的图像,在opencv中可以使用VideoCapture这个类来打开视频,打开的视频也存在于这个类中,使用.read()方法也可以获得每一帧的图像,该方法的用法类似于生成器,每调用一次都会返回下一帧的图像。其中.waitKey()方法是延迟并获取键盘输入,传入参数是延迟时间数,单位是1/60s且必须是整数,因为原视频是60帧,所以间隔为1时是常速播放

代码语言:javascript
复制
import cv2

capture = cv2.VideoCapture(
    "../leviathan's highlight_17-08-16_00-52-33.mp4")
if capture.isOpened():
    while True:
        ret, prev = capture.read()
        if ret is True:
            cv2.imshow("", prev)
        else:
            break
        cv2.waitKey(1)

玩过守望先锋的小伙伴应该知道,那个最佳镜头的最后会一段浮现守望先锋logo的部分,我们需要切掉这一部分,方法是只截取前17.5秒的视频,因为不知道是否有24帧的视频,所以要先获得帧率再截取前17.5*fps的视频,现在的代码是

代码语言:javascript
复制
import cv2

capture = cv2.VideoCapture(
    "../leviathan's highlight_17-08-16_00-52-33.mp4")
print(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
print(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = capture.get(cv2.CAP_PROP_FPS)
if capture.isOpened():
    i = 0
    while i < fps * 17.5:
        i += 1
        ret, prev = capture.read()
        if ret is True:
            cv2.imshow("", prev)
        else:
            break
        cv2.waitKey(1)

顺便还看了下幕布的尺寸为1920*1080 参考python tools:计算视频的 FPS,以及总帧数

step2打开并显示一堆视频

因为视频一共有20个左右,所以可以使用os模块中的listdir()获取所有文件,并筛选带.mp4后缀的视频文件。这样获取的list是完全按顺序排列的,我们还可以使用random.shuffle()方法打乱整个视频列表

代码语言:javascript
复制
mp4list = [x for x in os.listdir("../") if x[-4:] == ".mp4"]
random.shuffle(mp4list)

于是遍历整个列表看所有视频了

代码语言:javascript
复制
import cv2
import os
import random

mp4list = [x for x in os.listdir("../") if x[-4:] == ".mp4"]
random.shuffle(mp4list)
print(mp4list)
for mp4file in mp4list:
    capture = cv2.VideoCapture("../%s" % mp4file)
    fps = capture.get(cv2.CAP_PROP_FPS)
    print(fps)
    if fps != 60:
        jump = 20
    else:
        jump = 1
    if capture.isOpened():
        i = 0
        while i < fps * 1:
            i += 1
            ret, prev = capture.read()
            if ret is True:
                cv2.imshow("", prev)
            else:
                break
            cv2.waitKey(jump)
cv2.destroyAllWindows()

step3:保存为一个大视频

保存视频首先需要创建一个视频容器,可以使用cv2.VideoWriter,输入参数为路径,压缩方式,帧率,幕布大小,随后使用该对象的write()方法即可写入一帧,写入完成后,使用release()方法释放容器并保存,若在次之前程序中断,那视频文件会是损坏状态,于是程序是这样的

代码语言:javascript
复制
import cv2
import os
import random

VideoWriter = cv2.VideoWriter(
    "./overwatch.avi",
    cv2.VideoWriter_fourcc('X', 'V', 'I', 'D'), 60,
    (1920, 1080))

mp4list = [x for x in os.listdir("../") if x[-4:] == ".mp4"]
random.shuffle(mp4list)
print(mp4list)
for mp4file in mp4list:
    print(mp4file)
    capture = cv2.VideoCapture("../%s" % mp4file)
    fps = capture.get(cv2.CAP_PROP_FPS)
    if capture.isOpened():
        i = 0
        while i < fps * 17.5:
            i += 1
            ret, prev = capture.read()
            if ret is True:
                if fps == 60:
                    VideoWriter.write(prev)
                else:
                    VideoWriter.write(prev)
                    VideoWriter.write(prev)
            else:
                break
VideoWriter.release()
cv2.destroyAllWindows()

其中为了补偿30帧左右的视频,非60帧图片一帧写入两次

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.08.26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • step0:概述
  • step1:打开并显示视频
  • step2打开并显示一堆视频
  • step3:保存为一个大视频
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档