前言

当下,视频内容火爆,带有争议性或反差大的换脸视频总能吸引人视线。虽然 AI 换脸在市面上已经流行了许久,相关制作工具或移动应用也是数不胜数。但是多数制作工具多数情况下不是会员就是收费,而且替换模板有限。以下在实战的角度,用阿里 ModelScope 的图像人脸融合实现一下 AI 视频换脸。

流程

提供一段视频和一张替换的人脸图片,用 opencv-python 将视频根据帧率拆成图片,用 FFmpeg 提取视频里的音频为单独文件 (mp3)。遍历目录下的每一帧的图片,通过 ModelScope 的人脸融合模型,传入新的人脸和帧率图片,得到替换过人脸的帧图片。最后再通过 opencv-python 将替换的人脸图片组合成新视频,FFmpeg 添加提取出的音频文件。

环境

1. Python 3.7.16

2. ModelScope 1.4.2

3. OpenCV-Python 4.7.0

4. FFmpeg 12.2.0

环境安装

1. Python 虚拟环境添加

conda create -n modelscope python=3.7 && conda activate modelscope

2. 安装 ModelScope,使用了国内镜像源

pip install modelscope --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple

3. 安装 OpenCV

pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple

4. 安装 FFmpeg

因为单是图片用不上,所以安装方法放在下面视频换脸里

图片换脸

1. 素材准备

我这里分别准备了一个画面里出现正脸,侧脸和两张脸的图片,然后分别用一张图片替换,最后运行代码查看效果。(可能是模型原因,感觉光看图片的换脸好像相差不大,倒有点像只是开了个美颜,也有可能是俩演员有点像,认真看还有有点不同),模搭地址:www.modelscope.cn

2. 代码部分

import cv2
from modelscope.outputs import OutputKeys
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks image_face_fusion = pipeline(Tasks.image_face_fusion,
model='damo/cv_unet-image-face-fusion_damo')
template_path = '181.jpg'
user_path = 'face.jpg'
result = image_face_fusion(dict(template=template_path, user=user_path)) cv2.imwrite('result.png', result[OutputKeys.OUTPUT_IMG])
print('finished!')

视频换脸

1.  FFmpeg 安装

下载地址:http://ffmpeg.org/download.html#build-windows,如果是 windows10 可以按我下面的选择,shared 是动态版本,不带的是静态版本,所有的功能都集合在一起。

2. FFmpeg 环境配置

下载后解压会生成一下目录,将 bin 文件放入电脑环境变量中,然后通过 ffmpeg -version 查看是否安装成功。

3. FFmpeg 用法

3.1. 从视频中抽取音频 (输入视频和输出音频的地址可以是相对路径)

ffmpeg -i videos\11.mp4 -q:a 0 -map a audio\audio.mp3 

3.2. 将独立音频文件添加到视频里 (接收输入视频,输入音频,输出新视频)

ffmpeg -i videos/ldh.mp4 -i audio/audio.mp3 -c:v copy -c:a aac -strict experimental videos/new_ldh.mp4

4. 开始编码

from pathlib import Path
import cv2
import os def video2mp3_img(video_path, save_path):
def video_split(video_path, save_path): if not os.path.exists(save_path):
os.makedirs(save_path)
cap = cv2.VideoCapture(video_path)
i = 0
while True:
ret, frame = cap.read()
if ret:
cv2.imwrite(save_path + '/' + str(i) + '.jpg', frame)
i += 1
else:
break
cap.release()
if not os.path.exists(save_path):
os.makedirs(save_path) # 视频分割
video_split(video_path, save_path) # 视频转音频
os.system("ffmpeg -i {} -q:a 0 -map a {}/audio.mp3".format(video_path, save_path)) def face_replace(user_path=""): from pathlib import Path
import cv2
from modelscope.outputs import OutputKeys
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True' def my_function(img_path): image_face_fusion = pipeline(Tasks.image_face_fusion, model='damo/cv_unet-image-face-fusion_damo')
template_path = img_path
filename = os.path.splitext(os.path.basename(img_path))[0] # 替换面部依赖
result = image_face_fusion(dict(template=template_path, user=user_path))
cv2.imwrite(f'video_imgout/{filename}.jpg', result[OutputKeys.OUTPUT_IMG]) threads = []
BASE_PATH = os.path.dirname(__file__) for dirpath, dirnames, filenames in os.walk(r"D:\3code\3Python\modelscope\mv_face_change-main"):
for filename in filenames:
print(filename)
if filename.endswith('.jpg'):
file_path = Path(os.path.join(dirpath, filename))
print(file_path)
my_function(str(file_path)) def img2mp4(video_path, save_name):
BASE_PATH = "D:\3code\3Python\modelscope\mv_face_change-main"
img = cv2.imread("video_img/0.jpg")
imgInfo = img.shape
size = (imgInfo[1], imgInfo[0]) files = []
for dirpath, dirnames, filenames in os.walk(r"D:\3code\3Python\modelscope\mv_face_change-main\video_imgout"):
for filename in filenames:
fileName = Path(os.path.join(dirpath, filename))
files.append(os.path.join(dirpath, filename)) files = [file.replace('\\', '/') for file in files]
files.sort(key=lambda x: int(x.split('/')[-1].split('.')[0]))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
videoWrite = cv2.VideoWriter(r"D:\3code\3Python\modelscope\mv_face_change-main\videos\ldh.mp4", fourcc, 25, size) # 写入对象 1 file name 3: 视频帧率
for i in files:
print(i)
img = cv2.imread(str(i))
videoWrite.write(img) # 将video_img中的音频文件添加到视频中
os.system("ffmpeg -i {} -i {} -c:v copy -c:a aac -strict experimental {}".format("videos/ldh.mp4", "audio/audio.mp3", "videos/newlest_ldh.mp4")) if __name__ == '__main__':
BASE = os.path.dirname(__file__)
video_path = os.path.join(BASE, "videos/demo.mp4")
save_path = os.path.join(BASE, "video_img") # 视频 ==> imgs
video2mp3_img(video_path, save_path) # 人脸替换
face_replace(user_path='zsy.jpg') # imgs ==> 视频
img2mp4(video_path, save_name='zsy')

5. 报错汇总

当运行上面代码,如果出现 Output file does not contain any stream,那就是分离音频或追加音频到视频的这两个地方报的错误,大部分情况下输出路径不正确或命令参数不对。还有一个错误我没有记录,就是让视频压根没有声音,再执行分离操作时也会报错。这个是我上班时随便拿的视频测试 (因为不能戴耳机,刚好视频就是没声音的),所以使劲测使劲报错,换了视频就好了,关键是错误提示也没说是视频没声音。

6. 效果演示

由于时间原因,没有用杨过的视频,就用没有声音的视频做了换脸演示。以后还要对换脸图片替换做多线程处理。

如何用 ModelScope 实现 “AI 换脸” 视频的更多相关文章

  1. faceswap深度学习AI实现视频换脸详解

    给大家介绍最近超级火的黑科技应用deepfake,这是一个实现图片和视频换脸的app.前段时间神奇女侠加尔盖朵的脸被换到了爱情动作片上,233333.我们这里将会从github项目faceswap开始 ...

  2. AI换脸教程:DeepFaceLab使用教程(1.安装及分解视频)

    首先需要选择合适的DeepFaceLab下载(https://www.deepfacelabs.com/list-5-1.html),然后安装相应的显卡驱动,如果已经准备好这些工作,那么恭喜你,终于开 ...

  3. 程序员体验AI换脸就不要用ZAO了,详解Github周冠军项目Faceswap的变脸攻略

    本文链接:https://blog.csdn.net/BEYONDMA/article/details/100594136       上个月笔者曾在<银行家杂志>发文传统银行如何引领开放 ...

  4. Thiago2(TPO AI.ROSTO):集成式AI换脸软件(Autodesk Flame)

    如标题一样,Thiago2 是一款集成式AI换脸软件(TPO AI.ROSTO),需要与Autodesk Flame结合使用,从demo来看完成度还是很高的,算是一种完全GUI版的DeepFaceLa ...

  5. AI换脸教程:DeepFaceLab使用教程(2.训练及合成)

    如果前期工作已经准备完毕(DeepFaceLab下载(https://www.deepfacelabs.com/list-5-1.html),然后安装相应的显卡驱动,DeepFaceLab使用教程(1 ...

  6. 从Vehicle-ReId到AI换脸,应有尽有,解你所惑

    最近在做视频搜索的技术调研,已经初步有了一些成果输出,算法准确性还可以接受,基本达到了调研的预期.现将该技术调研过程中涉及到的内容总结一篇文章分享出来,内容比较多,初看起来可能关系不大,但是如果接触面 ...

  7. AI换脸实战教学(FaceSwap的使用)---------第一步Extration:提取人脸。

    市面上有多款AI换脸的方法,笔者这里节选了Github那年很火的开源项目FaceSwap: (很早就实践了,但是忘记记录啦hhh,请勿用于不正当用途哦) 做了一篇详细教学,包括配置,参数设置,换脸效果 ...

  8. Deepfakes:AI换脸技术自制明星XX片

    ps:亮瞎狗眼 去年开始就在国外网站上比较火的项目了,通过Deepfakes技术可以将视频中的人脸换成自己喜欢的明星, 当时就有不少人制作了换脸视频,其中大部分是替换了XX片的女主角. 国外网站Red ...

  9. 福利:42套AI技术视频免费领取

    <福利:33套AI技术视频免费领取> 视频获取方式:请加机器学习和自然语言(QQ群号:436303759)群后,私信群主获取(备注上自己想要获取是视频名称),仅限本群公众号粉丝成员,多套视 ...

  10. AI换脸必备知识:如何查看显卡型号以及显存大小!

    使用Deepfakes(AI换脸) 软件,拼的就是配置,耗的就是时间,考验的是耐心. 配置好了,时间就少了. 所以玩这种软件,硬核需求就是:配置,配置,配置.  我的电脑能跑这个软件么?也是很多新手的 ...

随机推荐

  1. Linux期末佛脚指南

    Linux的期末佛脚复习 常用文件操作命令 touch (创建文件) cat (查看文件内容) head (查看文件开头) tail (查看文件结尾) cp (复制文件) mv (移动文件) ls ( ...

  2. 波场(Tron) 网页版钱包开源

    之前做区块链项目太难了,很多组件.工具没有开源项目,需要自己写很麻烦. 我整理了几个自己给公司开发项目的时候,分离出来的几个工具,已经上传到 Gihub 了,感觉浏览量还行,在这里给园子里的朋友分享下 ...

  3. golang调用sdl2,播放yuv视频

    golang调用sdl2,播放yuv视频 win10 x64下测试成功,其他操作系统下不保证成功. 采用的是syscall方式,不是cgo方式. 见地址 代码如下: package main impo ...

  4. 2022-06-11:注意本文件中,graph不是邻接矩阵的含义,而是一个二部图。 在长度为N的邻接矩阵matrix中,所有的点有N个,matrix[i][j]表示点i到点j的距离或者权重, 而在二部

    2022-06-11:注意本文件中,graph不是邻接矩阵的含义,而是一个二部图. 在长度为N的邻接矩阵matrix中,所有的点有N个,matrix[i][j]表示点i到点j的距离或者权重, 而在二部 ...

  5. 使用vite的创建vue项目

    首先也是打开项目文件目录 在标签处快速打上cmd即可打开cmd窗口 然后按照顶部图进行操作即可完成 安装完成的样子如下图 紧接着输入 npm run dev 将Local 的IP复制到浏览器打开,出现 ...

  6. 利用简单的IO操作实现M3U8文件之间的合并

    先上代码: 1 @SneakyThrows //合并操作,最终文件不包含结束标识,方便多次合并 2 private static void mergeM3U8File(String source, S ...

  7. 选择结构do...while语句

    // do..while语句 #include<stdio.h> int main() { int a = 0; do { a++; printf("HelloWorld\n&q ...

  8. 2023.5.25 Linux系统Bash初识

    1.Linux系统终端概述2.Linux系统Bash管理2.1.Bash特性:命令补全2.2.Bash特性:命令快捷键2.3.Bash特性:命令别名2.4.Bash特性:命令流程2.5.Bash特性: ...

  9. 最小编译器和 UI 框架「GitHub 热点速览」

    如果有一个关键词来概述本周的 GitHub 热门项目的话,大概就是 van 和 sectorc 都用到的 smallest.只不过一个是前端的响应式框架,一个是搞编译的 C 编译器.它们除了轻量化这个 ...

  10. 今天在内部 Galaxy 分析平台操作探针引物设计小工具程序,调用 Ensembl API 获取相关序列和信息时,发现官网 MySQL server 异常,报告问题后当天晚上就收到了回复,并且修......

    本文分享自微信公众号 - 生信科技爱好者(bioitee).如有侵权,请联系 support@oschina.cn 删除.本文参与"OSC源创计划",欢迎正在阅读的你也加入,一起分 ...