给视频里的人换脸

DeepFakeLab-Colab

以下代码都是ipynb的md导出,代码源自这里,用于便携的在Colab上调用DFL项目的源码进行快捷方便的换脸

DFL-Colab

Step 1. 配置环境

  • 选择clone
  • 自动安装相关依赖文件
#@title 看不懂就选克隆

Mode = "克隆" #@param ["克隆", "拉取"]

if (Mode == "克隆"):
  !git clone https://github.com/iperov/DeepFaceLab.git
else:
  %cd /content/DeepFaceLab
  !git pull

!pip install -r /content/DeepFaceLab/requirements-colab.txt
!pip install --upgrade scikit-image

Step 2. 从谷歌云盘中上传素材

  • 挂载谷歌云盘
  • 解压素材文件
  • 复制到Colab环境中
#@title 输入素材在谷歌云盘中的路径
Filename = "workspace.zip" #@param {type:"string"}

#Mount Google Drive as folder
from google.colab import drive
drive.mount('/content/drive', force_remount=True)

#Create command
cmd = "/content/drive/My\ Drive/"+Filename+" /content"


#Copy zip archive of your workspace from Drive
%cp $cmd
%cd "/content"
!unzip -q $Filename
cmd = "/content/"+Filename
!rm $cmd

Step 3. 提取

  • 把视频切成一帧一帧的图
  • 每帧做人脸检测和对齐
  • (可选)手动将这步的结果暂存到谷歌云盘
#@title 提取帧
Video = "目标视频" #@param ["源视频", "目标视频"]

%cd "/content"

cmd = "DeepFaceLab/main.py videoed extract-video"

if Video == "目标视频":
  cmd+= " --input-file workspace/data_dst.* --output-dir workspace/data_dst/"
else:
  cmd+= " --input-file workspace/data_src.* --output-dir workspace/data_src/"

!python $cmd
#@title 去除视频噪音
Data = "\u6E90\u89C6\u9891" #@param ["源视频", "目标视频"]
Factor = 1 #@param {type:"slider", min:1, max:20, step:1}

if Data == "目标视频":
  cmd = "DeepFaceLab/main.py videoed denoise-image-sequence --input-dir workspace/data_dst --factor "+str(Factor)
else:
  cmd = "DeepFaceLab/main.py videoed denoise-image-sequence --input-dir workspace/data_src --factor "+str(Factor)
%cd "/content"
!python $cmd
#@title 人脸检测
Data = "\u6E90\u89C6\u9891" #@param ["源视频", "目标视频"]
Detector = "S3FD" #@param ["S3FD", "MT"]
Debug = False #@param {type:"boolean"}

detect_type = "s3fd"
if Detector == "S3FD":
  detect_type = "s3fd"
elif Detector == "MT":
  detect_type = "mt"
if Data == "目标视频":
  folder = "workspace/data_dst"
else:
  folder = "workspace/data_src"
folder_align = folder+"/aligned"
debug_folder = folder_align+"/debug"

cmd = "DeepFaceLab/main.py extract --input-dir "+folder+" --output-dir "+folder_align

if Debug:
  cmd+= " --debug-dir "+debug_folder

cmd+=" --detector "+detect_type

%cd "/content"
!python $cmd
#@title 人脸对齐
Data = "\u6E90\u89C6\u9891" #@param ["源视频", "目标视频"]
sort_type = "hist" #@param ["hist", "hist-dissim", "face-yaw", "face-pitch", "blur", "final"]
if Data == "目标视频":
  folder = "data_dst"
else:
  folder = "data_src"
cmd = "DeepFaceLab/main.py sort --input-dir workspace/"+Data+"/aligned --by "+sort_type

%cd "/content"
!python $cmd

Step 4. 训练模型

  • 自由选择模型
  • SAE: 推荐,可自定义很多参数.
  • H64: 快,操作简单,使用低配置参数可以在低显存的情况下运行.
  • H128: H64的高清版,细节更加丰富,适合3~4G显存,比较适合扁平的亚洲脸型.
  • DF: 全脸型的H128模型.
  • LIAEF128: 结合了DF, IAE的改进型128全脸模型.但模型存在闭眼识别问题,适合5G以上显存.
  • 无法在当前页面预览输出.(可选)若要手动预览,可以在Colab文件管理器中的模型文件夹下找到preview.jpg文件
  • (可选)手动将这步的结果暂存到谷歌云盘
#@title 训练模型
Model = "SAE" #@param ["SAE", "H128", "LIAEF128", "DF"]

#Mount Google Drive as folder
from google.colab import drive
drive.mount('/content/drive')

import psutil, os, time

p = psutil.Process(os.getpid())
uptime = time.time() - p.create_time()

if (round(39600-uptime) > 0):
  backup_time = str(round(39600-uptime))
  print("Time to backup: "+str(round((39600-uptime)/3600))+" hours")
  cmd = "DeepFaceLab/main.py train --training-data-src-dir workspace/data_src/aligned --training-data-dst-dir workspace/data_dst/aligned --model-dir workspace/model --model "+Model
  backup_cmd = " --execute-program "+backup_time+" \"import os; os.system('zip -r -q workspace.zip workspace'); os.system('cp /content/workspace.zip /content/drive/My\ Drive/'); print(' Backuped!') \""
else:
  cmd = "DeepFaceLab/main.py train --training-data-src-dir workspace/data_src/aligned --training-data-dst-dir workspace/data_dst/aligned --model-dir workspace/model --model "+Model
  backup_cmd = ""

if (backup_cmd != ""):
  train_cmd = (cmd+backup_cmd)
else:
  train_cmd = (cmd)

%cd "/content"
!python $train_cmd

Step 5. 换脸

使用上一步训练出的模型来换脸

#@title 换脸
Model = "SAE" #@param ["SAE", "H128", "LIAEF128", "DF"]

cmd = "DeepFaceLab/main.py convert --input-dir workspace/data_dst --output-dir workspace/data_dst/merged --aligned-dir workspace/data_dst/aligned --model-dir workspace/model --model "+Model

%cd "/content"
!python $cmd
#@title 将结果保存到谷歌云盘

!python DeepFaceLab/main.py videoed video-from-sequence --input-dir workspace/data_dst/merged --output-file workspace/result.mp4 --reference-file workspace/data_dst.mp4
!cp /content/workspace/result.mp4 /content/drive/My\ Drive/

工作区调整工具

由于Colab的计算存储资源会定时释放,也有可能意外断掉,所以增加暂存和对工作区进行暂存,回滚,导入,导出是必要的.

#@title 从谷歌云盘下载到Colab工作区

Mode = "workspace" #@param ["workspace", "data_src", "data_dst", "data_src aligned", "data_dst aligned", "models"]
Archive_name = "workspace.zip" #@param {type:"string"}

#Mount Google Drive as folder
from google.colab import drive
drive.mount('/content/drive', force_remount=True)

def zip_and_copy(path, mode):
  unzip_cmd=" -q "+Archive_name

  %cd $path
  copy_cmd = "/content/drive/My\ Drive/"+Archive_name+" "+path
  !cp $copy_cmd
  !unzip $unzip_cmd
  !rm $Archive_name

if Mode == "workspace":
  zip_and_copy("/content", "workspace")
elif Mode == "data_src":
  zip_and_copy("/content/workspace", "data_src")
elif Mode == "data_dst":
  zip_and_copy("/content/workspace", "data_dst")
elif Mode == "data_src aligned":
  zip_and_copy("/content/workspace/data_src", "aligned")
elif Mode == "data_dst aligned":
  zip_and_copy("/content/workspace/data_dst", "aligned")
elif Mode == "models":
  zip_and_copy("/content/workspace", "model")

print("Done!")
#@title 从Colab工作区上载到谷歌云盘
Mode = "workspace" #@param ["workspace", "data_src", "data_dst", "data_src aligned", "data_dst aligned", "merged", "models"]
Archive_name = "workspace.zip" #@param {type:"string"}

#Mount Google Drive as folder
from google.colab import drive
drive.mount('/content/drive', force_remount=True)

def zip_and_copy(path, mode):
  zip_cmd="-r -q "+Archive_name+" "

  %cd $path
  zip_cmd+=mode
  !zip $zip_cmd
  copy_cmd = " "+Archive_name+"  /content/drive/My\ Drive/"
  !cp $copy_cmd
  !rm $Archive_name

if Mode == "workspace":
  zip_and_copy("/content", "workspace")
elif Mode == "data_src":
  zip_and_copy("/content/workspace", "data_src")
elif Mode == "data_dst":
  zip_and_copy("/content/workspace", "data_dst")
elif Mode == "data_src aligned":
  zip_and_copy("/content/workspace/data_src", "aligned")
elif Mode == "data_dst aligned":
  zip_and_copy("/content/workspace/data_dst", "aligned")
elif Mode == "merged":
  zip_and_copy("/content/workspace/data_dst", "merged")
elif Mode == "models":
  zip_and_copy("/content/workspace", "model")

print("Done!")
#@title 从远端服务器下载到Colab工作区
URL = "服务器地址" #@param {type:"string"}
Mode = "unzip to content" #@param ["unzip to content", "unzip to content/workspace", "unzip to content/workspace/data_src", "unzip to content/workspace/data_src/aligned", "unzip to content/workspace/data_dst", "unzip to content/workspace/data_dst/aligned", "unzip to content/workspace/model", "download to content/workspace"]

import urllib
from pathlib import Path

def unzip(zip_path, dest_path):


  unzip_cmd = " unzip -q " + zip_path + " -d "+dest_path
  !$unzip_cmd
  rm_cmd = "rm "+dest_path + url_path.name
  !$rm_cmd
  print("Unziped!")


if Mode == "unzip to content":
  dest_path = "/content/"
elif Mode == "unzip to content/workspace":
  dest_path = "/content/workspace/"
elif Mode == "unzip to content/workspace/data_src":
  dest_path = "/content/workspace/data_src/"
elif Mode == "unzip to content/workspace/data_src/aligned":
  dest_path = "/content/workspace/data_src/aligned/"
elif Mode == "unzip to content/workspace/data_dst":
  dest_path = "/content/workspace/data_dst/"
elif Mode == "unzip to content/workspace/data_dst/aligned":
  dest_path = "/content/workspace/data_dst/aligned/"
elif Mode == "unzip to content/workspace/model":
  dest_path = "/content/workspace/model/"
elif Mode == "download to content/workspace":
  dest_path = "/content/workspace/"

if not Path("/content/workspace").exists():
  cmd = "mkdir /content/workspace; mkdir /content/workspace/data_src; mkdir /content/workspace/data_src/aligned; mkdir /content/workspace/data_dst; mkdir /content/workspace/data_dst/aligned; mkdir /content/workspace/model"
  !$cmd

url_path = Path(URL)
urllib.request.urlretrieve ( URL, dest_path + url_path.name )

if (url_path.suffix == ".zip") and (Mode!="download to content/workspace"):
  unzip(dest_path + url_path.name, dest_path)


print("Done!")
#@title 从Colab工作区上载到远端服务器
URL = "服务器地址" #@param {type:"string"}
Mode = "upload workspace" #@param ["upload workspace", "upload data_src", "upload data_dst", "upload data_src aligned", "upload data_dst aligned", "upload merged", "upload model"]

cmd_zip = "zip -r -q "

def run_cmd(zip_path, curl_url):
  cmd_zip = "zip -r -q "+zip_path
  cmd_curl = "curl --silent -F "+curl_url+" -D out.txt > /dev/null"
  !$cmd_zip
  !$cmd_curl


if Mode == "upload workspace":
  %cd "/content"
  run_cmd("workspace.zip workspace/","'data=@/content/workspace.zip' "+URL)
elif Mode == "upload data_src":
  %cd "/content/workspace"
  run_cmd("data_src.zip data_src/", "'data=@/content/workspace/data_src.zip' "+URL)
elif Mode == "upload data_dst":
  %cd "/content/workspace"
  run_cmd("data_dst.zip data_dst/", "'data=@/content/workspace/data_dst.zip' "+URL)
elif Mode == "upload data_src aligned":
  %cd "/content/workspace"
  run_cmd("data_src_aligned.zip data_src/aligned", "'data=@/content/workspace/data_src_aligned.zip' "+URL )
elif Mode == "upload data_dst aligned":
  %cd "/content/workspace"
  run_cmd("data_dst_aligned.zip data_dst/aligned/", "'data=@/content/workspace/data_dst_aligned.zip' "+URL)
elif Mode == "upload merged":
  %cd "/content/workspace/data_dst"
  run_cmd("merged.zip merged/","'data=@/content/workspace/data_dst/merged.zip' "+URL )
elif Mode == "upload model":
  %cd "/content/workspace"
  run_cmd("model.zip model/", "'data=@/content/workspace/model.zip' "+URL)


!rm *.zip

%cd "/content"
print("Done!")
#@title 工作区手动调整
Mode = "重置工作区" #@param ["重置工作区","删除模型","删除源视频的帧文件","删除源视频","删除目标视频的帧文件","删除换好脸的帧文件"]
dic={"重置工作区":"Delete and recreate workspace","删除模型":"Delete models","删除源视频的帧文件":"Delete data_src","删除源视频":"Delete data_src video","删除目标视频的帧文件":"Delete data_dst","删除换好脸的帧文件":"Delete merged frames"}
Mode = dic[Mode]
%cd "/content"

if Mode == "Delete and recreate workspace":
  cmd = "rm -r /content/workspace ; mkdir /content/workspace; mkdir /content/workspace/data_src; mkdir /content/workspace/data_src/aligned; mkdir /content/workspace/data_dst; mkdir /content/workspace/data_dst/aligned; mkdir /content/workspace/model"
elif Mode == "Delete models":
  cmd = "rm -r /content/workspace/model/*"
elif Mode == "Delete data_src":
  cmd = "rm -r /content/workspace/data_src/*"
elif Mode == "Delete data_src video":
  cmd = "rm -r /content/workspace/data_src.*"
elif Mode == "Delete data_dst":
  cmd = "rm -r /content/workspace/data_dst/*"
elif Mode == "Delete merged frames":
  cmd = "rm -r /content/workspace/data_dst/merged"

!$cmd
print("Done!")
本文总字数: 9703