关于 ModelScope 的视频 “AI 换脸” 优化方案

发布时间 2023-04-18 11:29:20作者: 北桥苏

前言

        前面一文,初步完成了一下 “AI 换脸” 视频处理程序。完成了视频拆帧,拆帧图片人脸融合,已经音频提取和最后的人脸融合图片的整合(也就是将图片和音频组成视频)。但是在人脸融合部分由于是单线程,处理起来非常耗时,所以这里就对那部分进行优化。

 

优化前情况

        "敏捷开发,快速迭代",好像这种思维从多年前就埋在了脑子里 (借口)。所以前文算是个初版 demo,并且在环境中运行只是用 cmd 来完成,没有使用专门 Python 的 IDE。也很有可能是这个原因,在执行代码里,只要是关于获取当前目录的地方都不起效果,这是一点另一点就是上面重点要解决的,提升人脸替换的处理速度,这里要用到多线程。

 

编码

1. 人脸替换部分

用法就不多讲了,Py 相关的文档有讲,以下只是代码片段,可以用这个替换前面文章代码里的 face_replace 函数。经过测试,相同的张数的图片 (这里只有 403 张),处理时间比前者缩短了半小时。

def face_replace(user_path=""):
    import threading
    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'

    max_workers = 2
    semaphore = threading.Semaphore(max_workers)

    def my_function(img_path):

        with semaphore:
            print(f"{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])
            print(f"{filename}.png ok")

    threads = []
    BASE_PATH = os.path.dirname(__file__)
    for dirpath, dirnames, filenames in os.walk(BASE_PATH + "/video_img"):
        for filename in filenames:
            print(filename)
            if filename.endswith('.jpg'):
                file_path = Path(os.path.join(dirpath, filename))
                t = threading.Thread(target=my_function, args=(str(file_path),)).start()
                threads.append(t)

 

pycharm 部分

        由于也有一些没有接触过 python 的小伙伴留言,这里就再介绍一下 IDE 的运行,也为了解决在 cmd 中运行出现获取当前路径问题。前面也有文章介绍关于 Python 虚拟环境的创建,这里就跳过了,直接演示在 IDE 中配置虚拟环境和运行代码。

1. 查看当前环境下的环境列表。

2. 打开 IDE 创建项目后进入。

3. 选择 Project,选择已经创建好的虚拟环境。

4. 查看当前项目是否在该环境下

5. 最后就可以直接用于代码了。