视频关键帧AI化的多种方法

视频关键帧AI化的逻辑是将视频切分成一帧帧的画面,然后使用SD绘画固定风格,最后统一在拼接在一起成为一个新的视频。

不管是Mov2Mov还是Multi Frame都能制作这种视频。但是这些操作起来比较麻烦,经过尝试处理较稳定的方法是可以通过img2imbatch_sizeControlNetADetailer进行控制修复以及批处理,这样操作会异常简单。

文章目录

  • Stable Diffusion 方法
  • After Effects 方法
  • Ebsynth 方法

Stable Diffusion 方法

安装视频转帧插件,在你的SD目录下的scripts文件夹下创建convert.py文件并复制下面的代码到文件中。

import cv2
import gradio as gr
import os
from tqdm import tqdm
from modules import script_callbacks


def add_tab():
    with gr.Blocks(analytics_enabled=False) as ui:
        with gr.Row().style(equal_height=False):
            with gr.Column(variant='panel'):
                gr.HTML(value="<p>Extract frames from video</p>")
                input_video = gr.Textbox(label="Input video path")
                output_folder = gr.Textbox(label="Output frames folder path")
                output_fps = gr.Slider(minimum=1, maximum=120, step=1, label="Save every N frame", value=1)
                extract_frames_btn = gr.Button(label="Extract Frames", variant='primary')

            with gr.Column(variant='panel'):
                gr.HTML(value="<p>Merge frames to video</p>")
                input_folder = gr.Textbox(label="Input frames folder path")
                output_video = gr.Textbox(label="Output video path")
                output_video_fps = gr.Slider(minimum=1, maximum=60, step=1, label="Video FPS", value=30)
                merge_frames_btn = gr.Button(label="Merge Frames", variant='primary')

            extract_frames_btn.click(
                fn=extract_frames,
                inputs=[
                    input_video,
                    output_folder,
                    output_fps
                ]
            )

            merge_frames_btn.click(
                fn=merge_frames,
                inputs=[
                    input_folder,
                    output_video,
                    output_video_fps
                ]
            )

    return [(ui, "视频<->帧", "vf_converter")]


def extract_frames(video_path: str, output_path: str, custom_fps=None):
    """从视频文件中提取帧并输出为png格式

    Args:
        video_path (str): 视频文件的路径
        output_path (str): 输出帧的路径
        custom_fps (int, optional): 自定义输出帧率(默认为None,表示与视频帧率相同)

    Returns:
        None
    """
    cap = cv2.VideoCapture(video_path)
    fps = int(cap.get(cv2.CAP_PROP_FPS))
    custom_fps = int(custom_fps)
    frame_count = 0

    print(f"Extracting {video_path} to {output_path}...")
    while True:
        ret, frame = cap.read()
        if not ret:
            break

        if custom_fps:
            if frame_count % custom_fps == 0:
                output_name = os.path.join(output_path, '{:06d}.png'.format(frame_count))
                cv2.imwrite(output_name, frame)
        else:
            output_name = os.path.join(output_path, '{:06d}.png'.format(frame_count))
            cv2.imwrite(output_name, frame)
        frame_count += 1

    cap.release()
    print("Extract finished.")


def merge_frames(frames_path: str, output_path: str, fps=None):
    """将指定文件夹内的所有png图片按顺序合并为一个mp4视频文件

    Args:
        frames_path (str): 输入帧的路径(所有帧必须为png格式)
        output_path (str): 输出视频的路径(需以.mp4为文件扩展名)
        fps (int, optional): 输出视频的帧率(默认为None,表示与输入帧相同)

    Returns:
        None
    """

    # 获取所有png图片
    frames = [f for f in os.listdir(frames_path) if f.endswith('.png')]
    img = cv2.imread(os.path.join(frames_path, frames[0]))
    height, width, _ = img.shape
    fps = fps or int(cv2.CAP_PROP_FPS)

    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    video_writer = cv2.VideoWriter(output_path, fourcc, fps, (width, height))

    print(f"Merging {len(frames)} frames to video...")
    for f in tqdm(frames):
        img = cv2.imread(os.path.join(frames_path, f))
        video_writer.write(img)

    video_writer.release()
    print("Merge finished")


script_callbacks.on_ui_tabs(add_tab)

准备好我们需要进行AI化处理的短视频,注意存放视频的路径中不要有中文。这里的视频尽量选择高清分辨率的,要不然最后合成出来的视频人物会变形。

在这里插入图片描述
打开SD选择视频和帧互换选项卡,填写视频路径和转换帧保存图片的路径,下面的数字1表示每一帧都截取,表示如果60帧的视频1秒就是60张图。
在这里插入图片描述
点击运行在对应的文件夹下会出现保存每一帧的图片。
在这里插入图片描述
选择其中一张图片拖到img2img选项卡,根据自己喜好选择模型和输出对应的关键词。你会发现第一次处理出来的图像和原图没啥关系。
在这里插入图片描述

这是由于没有选择ControlNet进行控制,点击下方的ControlNet选项卡,设置Canny。

在这里插入图片描述
然后再次点击生成图片,你会发现图像变过来了。
在这里插入图片描述
但是还会出现手脚崩坏的情况,需要在ADetailer中设置手脚修复功能。
在这里插入图片描述
设置好之后再次点击生成,来看看效果。
在这里插入图片描述
这里多生成几次记录下你满意的种子seed,记得将seed保存固定。
在这里插入图片描述
预处理这块就算完成了,接下来点击Batch批处理选项卡,这里要先把ControlNet中的图像叉掉。然后选择图片输入和输出路径。
在这里插入图片描述
这么操作是将out文件夹下的图片批处理之后保存到in文件夹下,然后点击执行,开始一张张处理图像吧。这个过程对于显卡不好的人来说比较痛苦,我这576张图片处理需要30分钟。
在这里插入图片描述
生成完所有图像后在in文件夹下删除后缀-1.png的轮廓图像。再回到视频帧互换选项卡设置需要拼接的图像目录,就是我们用SD绘画出来的图片文件夹,以及视频保存的目录,并且根据原有视频的帧数选择视频帧数。
在这里插入图片描述

点击运行之后会在test文件夹下生成一个video.mp4视频,就是我们要的结果了。
在这里插入图片描述
生成的视频会有闪烁的问题,后面会继续更新内容解决该问题。
在这里插入图片描述

After Effects 方法

使用AE转换需要下载StyleX插件。

在这里插入图片描述
然后设置参数进行预览。
在这里插入图片描述
整体效果其实和SD没有办法比,可以理解为用了简单的滤镜进行处理而已。最后添加到渲染队列输出即可。

Ebsynth 方法

Ebsynth主要可以处理SD生成动漫视频的画面闪烁的问题。

git 安装地址 https://gitcode.net/ranting8323/ebsynth_utility.git

在SD扩展中输入该网址进行安装即可。
在这里插入图片描述
安装完成后重启SD会在出现Ebsynth Utility选项卡。
在这里插入图片描述
进入Ebsynth官网根据你的系统下载安装程序。
在这里插入图片描述
然后在你的扩展目录下打开。
在这里插入图片描述
和SD处理方法一样,先要将视频按帧进行批量转换,首先拖入视频,然后指定提取关键帧的目录。视频的目录也可以手动输入。

configuration选择stage1。如果想要保持原视频尺寸默认选在-1即可。其他的不用操作,然后点击生成。
在这里插入图片描述在这里插入图片描述
在项目文件夹下自动创建video_frame文件夹,并将按帧的生成图片保存到该文件夹下,效果和之前视频转帧效果相同。
在这里插入图片描述
configuration选择stage2。这步是根据已经提取的关键帧按照间隔提取到Ebsynth中,关键帧间隔就是按照帧提取间隔,然后点击生成。
在这里插入图片描述
按照关键帧设置的配置提取关键帧Key到video_key中。
在这里插入图片描述
回到SD绘画中的img2img中,将这些图片批处理重绘和Stable Diffusion方法一样。生成完图像保存在img2img_key中。
在这里插入图片描述
configuration选择stage3.5中提取mask蒙版,也可以不提取。

configuration选择stage4中使用Extras将图片进行放大处理也可以不处理。

configuration选择stage5将关键帧处理好的图片文件放到img2img_upscale_key中,如果该文件夹不存在则手动创建。然后执行生成会生成对应 .ebs文件。
在这里插入图片描述

configuration选择stage6打开EbSynth.exe依次将对应 .ebs文件拖入。关闭蒙版on,点击Run All,等待关键帧生成。
在这里插入图片描述
会生成关键帧的处理过的批处理图片。
在这里插入图片描述

批处理之后点击Export to AE进行合成即可。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/35123.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言学习准备-编辑器选择

今天继续给大家更新C语言经典案例 今天的案例会比昨天稍微有一些难度&#xff0c;但是同时还是非常经典的案例 本来是想给大家继续更新C语言经典案例&#xff0c;但是有朋友反应C语言编辑器的选择&#xff0c;刚好我自己也是想更换一下C语言的编辑器&#xff0c;跟大家分享一下…

基于Web的智慧交通3D可视化系统

前言 城市交通是城市社会活动、经济活动的纽带和动脉&#xff0c;智慧交通系统对城市经济发展和人民生活水平起着极其重要的作用。 背景 随着我国城市化进程不断加快&#xff0c;现代城市交通问题日益受到人们的关注。特别是汽车数量的与日俱增&#xff0c;给城市带来了大量…

中国物流,驶入大航海时代

出海的一体化&#xff0c;不仅仅是物流的一体化&#xff0c;更是产业链、供应链的一体化。在诸多问题下&#xff0c;想要帮助企业更好地出海&#xff0c;就不能只专注于自身的长板&#xff0c;而是需要先补齐短板。 作者|斗斗 编辑|皮爷 出品|产业家 出海时代真的要来了。…

类Twitter风格的RSS阅读器

本文完成于 2 月中旬&#xff0c;其中的反代还是 frp npm 方案&#xff1b; 什么是 RSS ? RSS 是用 PHP、Laravel、Inertia.js、Tailwind 和 Vue.js 编写的简单的类Twitter 风格的 RSS阅读器&#xff0c;支持 RSS和ATOM 格式。 命令行安装 在群晖上以 Docker 方式安装。 官…

刷题日记06《回溯算法》

问题描述 力扣https://leetcode.cn/problems/Ygoe9J/ 给定一个无重复元素的正整数数组 candidates 和一个正整数 target &#xff0c;找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。 candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同…

【容器起不来~tomcat】

记录一次线上容器~tomcat起不来的场景: **部门由于资金有限,只能用tomcat去部署,话不多说直接贴图: Docker 镜像 Tomcat 启动失败– 查看线上日志,日志报错了,报错内容如下: 1,Error response from daemon: driver failed programming external connectivityon endpoint jen…

离线安装ffmpeg源码包【详细教程】

今天分享一下ffmpeg源码包的安装过程&#xff0c;针对在没有网络环境下&#xff0c;且不能直接使用yum如何成功安装ffmpeg源码包。博主本人通过正式服务器测试&#xff0c;记录整个安装过程。值得大家收藏 同时&#xff0c;我会分享一下如何使用ffmpeg对H.264格式视频(MP4)进行…

ss客服让您在Facebook 的客户服务更便捷

ss客服让您在Facebook Messenger 的客户服务更便捷 在这个信息时代&#xff0c;新兴通讯软件蓬勃兴起&#xff0c;比如Facebook Messenger。事实证明&#xff0c;这对企业来说非常有利&#xff0c;同时突出了电子邮件、网络聊天和电话等传统渠道的局限性。在传统渠道上&#xf…

PostGIS(2):PostGreSQL数据库空间扩展模块安装

正式开始解读PostGIS 3.1.10文档之前&#xff0c;我们还是先简单叙述一下如何安装PostGIS。 从引言篇已经了解到&#xff1a;PostGIS是对象关系型数据库PostGreSQL的一个拓展模块。既然如此&#xff0c;我们必须先安装PostGreSQL数据库&#xff08;详细教程可参考&#xff1a;P…

Cocos2dx学习笔记:浅谈游戏内的适配方案

前言 本篇在讲什么 Cocos2dx中的适配方案 本篇适合什么 适合初学Cocos的小白 本篇需要什么 对Lua语法有简单认知 依赖Cocos2dx3.15环境 依赖Sublime Text编辑器 依赖VS 2015编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手…

【软件测试】盘一盘工作中遇到的 Redis 异常测试

目录 前言&#xff1a; 一、更新 Key 异常 二、Key的删除和丢失 三、KEY 过期策略不当造成内存泄漏 四、查询Redis异常时处理 五、redis 穿透、击穿、雪崩 六、Redis死锁 七、Redis持久化 八、缓存与数据库双写时的数据一致性 前言&#xff1a; 在软件测试过程中&…

Centos安装RabbitMQ

#安装 yum install rabbitmq-server #启动 systemctl start rabbitmq-server #查看状态 systemctl status rabbitmg-server #安装管理插件 rabbitmg-plugins enable rabbitmg_management #新增admin账号 rabbitmqctl add_user admin admin #设置为管理员 rabbitmqctl set_user_…

计算机组成原理实验一:一位逻辑门构建

目录 一、实验目的 二、实验设备 三、实验原理 四、实验内容 1.一位非门 2.一位与门 3.一位或门 4.一位复用器 5.一位多路选择器 五、实验习题 如果只使用或非门搭建与、或和非门&#xff0c;该如何设计各芯片的物理结构&#xff1f; 六、自主设计——采用与或非门…

Word表格设置边框不生效的解决方法

1、这是新建并随意设置的表格&#xff0c;可以看出来上边框、内边框和下边框都是不同的粗细&#xff0c;很不协调。 2、选中表格&#xff0c;然后右击——>表格属性——>边框和底纹。 3、三线表&#xff0c;一般上边框和下边框都是1磅&#xff0c;内边框是0.5磅&#xff…

SpringSecurity对CSRF的支持实践

【1】什么是CSRF 跨站请求伪造&#xff08;英语&#xff1a;Cross-site request forgery&#xff09;&#xff0c;也被称为 one-click attack 或者 session riding&#xff0c;通常缩写为 CSRF 或者 XSRF&#xff0c; 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操…

【远程开发】VSCode使用Remote SSH远程连接Linux服务器

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 转载自cpolar极点云…

MSP432自主开发笔记2:八路寻迹模块的编程

今日得以继续我的MSP432学习之路&#xff0c;今日学习八路寻迹模块的编程与测试&#xff1a; 本章需要掌握的知识只有俩个&#xff1a;串口通信发送数据、GPIO基础初始化与获取电平状态 这俩个在我专栏里都可寻到&#xff0c;大家可以自行查找~~ 八路灰度寻迹模块的原理与应用…

MySQL:子查询(全面详解)

MySQL&#xff1a;子查询 前言一、需求分析与问题解决1、实际问题2、子查询的基本使用3、子查询的分类 二、单行子查询1、单行比较操作符2、代码示例3、HAVING 中的子查询4、CASE中的子查询5、子查询中的空值问题6、非法使用子查询 三、多行子查询1、多行比较操作符2、代码示例…

pyodbc读取.mdb文件时出现[ODBC Microsoft Access Driver] 网络访问已中断。请关闭数据库.....解决方法

在使用pyodbc读取.mdb文件时出现下面的错误 : ODBC Microsoft Access Driver] 网络访问已中断。若要继续&#xff0c;请关闭数据库&#xff0c;然后再将其打开。 (-1022) (SQLDriverConnect) 网上找了很多方法&#xff0c;最后通过下面的方法解决了&#xff0c;就是安装64位的…

Flink写入数据到ClickHouse

文章目录 1.ClickHouse建表1.ClickHouse依赖2.Bean实体类3.ClickHouse业务写入逻辑4.测试写入类5.发送数据 1.ClickHouse建表 ClickHouse中建表 CREATE TABLE default.test_write (id UInt16,name String,age UInt16 ) ENGINE TinyLog();1.ClickHouse依赖 Flink开发相关…