ModelScopeを使って「AI顔チェンジ」を実現する方法動画

序文

        現在、ビデオ コンテンツが人気であり、物議を醸す、または対照的な顔交換ビデオは常に人々の注目を集めています。AI による顔の変更は市場で長い間人気がありましたが、関連する制作ツールやモバイル アプリケーションは無数にあります。しかし、ほとんどの制作ツールは会員制か有料の場合が多く、代替となるテンプレートも限られています。実戦の観点から、Ali ModelScope の画像と顔の融合を使用して、AI ビデオの顔の交換を実現します。

プロセス

       ビデオと置換の顔写真を提供し、opencv-python を使用してフレーム レートに従ってビデオを画像に分割し、FFmpeg を使用してビデオからオーディオを別のファイル (mp3) に抽出します。ディレクトリ内の各フレームの画像を走査し、ModelScope の顔融合モデルを通じて新しい顔とフレーム レートの画像を渡し、顔を置き換えたフレーム画像を取得します。最後に、置き換えられた顔写真が opencv-python を通じて新しいビデオに結合され、FFmpeg によって抽出された音声ファイルが追加されます。

環境

1. Python 3.7.16

2.モデルスコープ 1.4.2

3. OpenCV-Python 4.7.0

4.FFmpeg12.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.材料の準備

     ここでは、正面顔、横顔、および 2 つの顔が写っている写真を用意し、それを写真に置き換え、最後にコードを実行して効果を確認します。(モデルのせいか、写真で見る限り顔の変化はあまり変わらない気がしますが、ただ美化しただけというか、俳優の二人が少し似ているのかもしれませんが、よく見ると少し違います)。

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のインストール

Windows10の場合は、共有が動的版、ないものが静的版で、すべての機能がひとまとめにされているので選択できます。

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. エラーの概要

上記のコードを実行したときに、出力ファイルにストリームが含まれていない場合は、オーディオの分離またはビデオへのオーディオの追加の 2 か所でエラーが報告されており、ほとんどの場合、出力パスが間違っているか、コマンド パラメーターが間違っています。 。録画していない別のエラーがあります。つまり、ビデオに音声がまったくなく、分離操作が実行されるとエラーが報告されます。これは仕事中に何気なく受けたビデオ テストです (ヘッドフォンを着用できないのと、たまたまビデオに音声が入っていないため) ので、最善を尽くしてテストし、エラーを報告しました。ビデオを変更しても問題ありません。重要なのは、エラー メッセージにはビデオに音声がないことが示されていないということです。

6. 効果実証

        時間の都合上、楊国氏のビデオは使用されず、顔交換のデモンストレーションは音声なしのビデオで行われた。将来的には、顔変更画像の置換をマルチスレッドで処理する予定です。

おすすめ

転載: blog.csdn.net/qq_35704550/article/details/130196528