satoshiNakomoroReal's picture
Deploy shared three-method Gradio app (part 3)
0cb7061 verified
Raw
History Blame Contribute Delete
6.4 kB
import argparse
import pdb
import matplotlib.pyplot as plt
import torch
from Models.Swapper_AlphaFace import build_AlphaFace
from utils.utils_config import get_config
from utils.utils_distributed_sampler import setup_seed
import os
from dataset.get_dataloader import get_dataloader
import torchvision.transforms as transforms
from PIL import Image
from Objectives.Loss import *
from torchvision.utils import make_grid
from torch.optim.lr_scheduler import CosineAnnealingLR, StepLR
from torch.utils.tensorboard import SummaryWriter
import numpy as np
from tqdm import tqdm
from pathlib import Path
from typing import Iterable, List, Union
def list_images(
directory: Union[str, Path],
extensions: Union[Iterable[str], None] = None,
recursive: bool = False
) -> List[Path]:
"""
Return a sorted list of image files found in *directory*.
Parameters
----------
directory : str | pathlib.Path
Folder to search.
extensions : Iterable[str] | None, default None
File-name extensions to keep (case-insensitive, with or without the dot).
If None, a sensible default set is used.
recursive : bool, default False
If True, search all nested sub-directories; otherwise, look only at the top
level of *directory*.
Returns
-------
list[pathlib.Path]
Absolute, sorted paths to the matching image files.
"""
# Default, widely-used image extensions
default_exts = {".jpg", ".jpeg", ".png", ".bmp", ".tif", ".tiff",
".gif", ".webp", ".ppm", ".pgm"}
exts = default_exts if extensions is None else {
(e.lower() if e.startswith(".") else f".{e.lower()}") for e in extensions
}
directory = Path(directory).expanduser().resolve()
if recursive:
paths = (p for p in directory.rglob("*") if p.is_file())
else:
paths = (p for p in directory.iterdir() if p.is_file())
return sorted(p for p in paths if p.suffix.lower() in exts)
def count_parameters(model):
return sum(p.numel() for p in model.parameters() if p.requires_grad)
def normalize_by_127_5(img):
"""
Normalize a tensor image by dividing by its maximum value.
Args:
img (torch.Tensor): Input image tensor.
Returns:
torch.Tensor: Normalized image tensor with values in [0, 1].
"""
img = (img * 255.0).int()
return (img / 127.5) - 1.0 # Return unchanged if max is 0 (e.g., all-zero image)
# Return unchanged if max is 0 (e.g., all-zero image)
def tensor2img(tensor):
"""
Normalize a tensor image by dividing by its maximum value.
Args:
img (torch.Tensor): Input image tensor.
Returns:
torch.Tensor: Normalized image tensor with values in [0, 1].
"""
return (tensor * 255.0).int() # Return unchanged if max is 0 (e.g., all-zero image)
def eval_alphaface(config, model):
writer = SummaryWriter(config.tb_dir)
if not os.path.exists(config.output):
os.makedirs(config.output)
print(f"Directory '{config.output}' created.")
else:
print(f"Directory '{config.output}' already exists.")
print('Resuming from checkpoint...from %s'%(config.model_path))
dict_checkpoint = torch.load(config.model_path)
print('from '+config.model_path)
model.Swapper.load_state_dict(dict_checkpoint["swapper"])
# Get source identity code for specific face identity swapping
model = model.cuda()
print(f"Number of parameters in Swapper: {count_parameters(model.Swapper)}")
model.Swapper.eval()
model.Id_encoder.eval()
t_transform = transforms.Compose([
transforms.Resize((256, 256)),
transforms.ToTensor()
])
s_transform =transforms.Compose([
transforms.Resize((112, 112)),
transforms.ToTensor(),
transforms.Lambda(normalize_by_127_5)
])
src_img_list = list_images(config.src_path)
tar_img_list = list_images(config.tar_path)
#pdb.set_trace()
#pdb.set_trace()
for src_img_file in src_img_list:
img1_s = s_transform(Image.open(src_img_file)).unsqueeze(0)
img1_s = img1_s.cuda()
for tar_img_file in tar_img_list:
img2_t = t_transform(Image.open(tar_img_file)).unsqueeze(0)
img2_t = img2_t.cuda()
swapped_2_1 = model(img2_t, img1_s)
# If the tensor is batched, take the first item
if swapped_2_1.dim() == 4:
swapped_2_1 = swapped_2_1[0]
# If the tensor is in [C, H, W] format, convert to [H, W, C]
if swapped_2_1.shape[0] in {1, 3, 4}:
swapped_2_1 = swapped_2_1.permute(1, 2, 0)
# Clamp to valid range and convert to uint8
if swapped_2_1.max() <= 1.0:
swapped_2_1 = swapped_2_1 * 255.0
swapped_2_1 = swapped_2_1.clamp(0, 255).byte()
# Convert to numpy and PIL
np_image = swapped_2_1.cpu().numpy()
img = Image.fromarray(np_image)
# If single channel, convert to 'L' mode explicitly
if np_image.shape[2] == 1:
img = img.convert("L")
#pdb.set_trace()
save_img_path = str(src_img_file).split('/')[-1].split('.')[0]+'_'+str(tar_img_file).split('/')[-1]
img.save(os.path.join(config.output,save_img_path))
print(f"Saved image to {os.path.join(config.output,save_img_path)}")
#print('source: %s | target: %s > %s'%(src_img_file,tar_img_list,os.path.join(config.output,save_img_path)))
def main(args):
cfg = get_config(args.config)
setup_seed(seed=cfg.seed, cuda_deterministic=False)
if cfg.tensorboard == True:
writer = SummaryWriter(cfg.tb_path)
else:
writer = None
os.makedirs(cfg.log_dir, exist_ok=True)
# Get dataloader for train
# Model initialisation
print('Preparing the student model')
alphaface = build_AlphaFace(config=cfg).to('cuda')
eval_alphaface(cfg, alphaface)
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description="Distributed Arcface Training in Pytorch")
parser.add_argument("config", type=str, default='./configs/test_config', help="py config file")
main(parser.parse_args())