API_MC_AI / SimSwap /predict.py
duyv's picture
Upload 204 files
f884940 verified
raw
history blame
4.02 kB
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 = opt.crop_size
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, size=(112,112))
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