Add Cog file to build Docker image

This commit is contained in:
Ben Firshman
2021-08-24 17:20:03 -07:00
parent 1adb7523c6
commit e6d64c1e06
3 changed files with 123 additions and 0 deletions

View File

@@ -56,6 +56,8 @@ If you find this project useful, please star it. It is the greatest appreciation
[Colab fo switching specific faces in multi-face videos](https://colab.research.google.com/github/neuralchen/SimSwap/blob/main/MultiSpecific.ipynb)
[Image face swapping demo & Docker image on Replicate](https://replicate.ai/neuralchen/simswap-image)
Training: **coming soon**

20
cog.yaml Normal file
View File

@@ -0,0 +1,20 @@
build:
gpu: true
python_version: "3.8"
system_packages:
- "libgl1-mesa-glx"
- "libglib2.0-0"
python_packages:
- "imageio==2.9.0"
- "torch==1.8.0"
- "torchvision==0.9.0"
- "numpy==1.21.1"
- "insightface==0.2.1"
- "ipython==7.21.0"
- "Pillow==8.3.1"
- "opencv-python==4.5.3.56"
- "Fraction==1.5.1"
- "onnxruntime-gpu==1.8.1"
- "moviepy==1.0.3"
predict: "predict.py:Predictor"

101
predict.py Normal file
View File

@@ -0,0 +1,101 @@
import cog
import tempfile
from pathlib import Path
import argparse
import cv2
import torch
from PIL import Image
import torch.nn.functional as F
from torchvision import transforms
from models.models import create_model
from options.test_options import TestOptions
from util.reverse2original import reverse2wholeimage
from util.norm import SpecificNorm
from test_wholeimage_swapmulti import _totensor
from insightface_func.face_detect_crop_multi import Face_detect_crop as Face_detect_crop_multi
from insightface_func.face_detect_crop_single import Face_detect_crop as Face_detect_crop_single
class Predictor(cog.Predictor):
def setup(self):
self.transformer_Arcface = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
@cog.input("source", type=Path, help="source image")
@cog.input("target", type=Path, help="target image")
@cog.input("mode", type=str, options=['single', 'all'], default='all',
help="swap a single face (the one with highest confidence by face detection) or all faces in the target image")
def predict(self, source, target, mode='all'):
app = Face_detect_crop_multi(name='antelope', root='./insightface_func/models')
if mode == 'single':
app = Face_detect_crop_single(name='antelope', root='./insightface_func/models')
app.prepare(ctx_id=0, det_thresh=0.6, det_size=(640, 640))
options = TestOptions()
options.initialize()
opt = options.parser.parse_args(["--Arc_path", 'arcface_model/arcface_checkpoint.tar', "--pic_a_path", str(source),
"--pic_b_path", str(target), "--isTrain", False, "--no_simswaplogo"])
str_ids = opt.gpu_ids.split(',')
opt.gpu_ids = []
for str_id in str_ids:
id = int(str_id)
if id >= 0:
opt.gpu_ids.append(id)
# set gpu ids
if len(opt.gpu_ids) > 0:
torch.cuda.set_device(opt.gpu_ids[0])
torch.nn.Module.dump_patches = True
model = create_model(opt)
model.eval()
crop_size = 224
spNorm = SpecificNorm()
with torch.no_grad():
pic_a = opt.pic_a_path
img_a_whole = cv2.imread(pic_a)
img_a_align_crop, _ = app.get(img_a_whole, crop_size)
img_a_align_crop_pil = Image.fromarray(cv2.cvtColor(img_a_align_crop[0], cv2.COLOR_BGR2RGB))
img_a = self.transformer_Arcface(img_a_align_crop_pil)
img_id = img_a.view(-1, img_a.shape[0], img_a.shape[1], img_a.shape[2])
# convert numpy to tensor
img_id = img_id.cuda()
# create latent id
img_id_downsample = F.interpolate(img_id, scale_factor=0.5)
latend_id = model.netArc(img_id_downsample)
latend_id = F.normalize(latend_id, p=2, dim=1)
############## Forward Pass ######################
pic_b = opt.pic_b_path
img_b_whole = cv2.imread(pic_b)
img_b_align_crop_list, b_mat_list = app.get(img_b_whole, crop_size)
swap_result_list = []
b_align_crop_tenor_list = []
for b_align_crop in img_b_align_crop_list:
b_align_crop_tenor = _totensor(cv2.cvtColor(b_align_crop, cv2.COLOR_BGR2RGB))[None, ...].cuda()
swap_result = model(None, b_align_crop_tenor, latend_id, None, True)[0]
swap_result_list.append(swap_result)
b_align_crop_tenor_list.append(b_align_crop_tenor)
net = None
out_path = Path(tempfile.mkdtemp()) / "output.png"
reverse2wholeimage(b_align_crop_tenor_list, swap_result_list, b_mat_list, crop_size, img_b_whole, None,
str(out_path), opt.no_simswaplogo,
pasring_model=net, use_mask=opt.use_mask, norm=spNorm)
return out_path