DeepSwapFace / app.py
Artysgor's picture
Update app.py
1e2d680 verified
raw
history blame contribute delete
No virus
5.05 kB
import os
import cv2
import torch
import base64
import argparse
import numpy as np
import insightface
import onnxruntime
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from face_swapper import Inswapper, paste_to_whole
from face_analyser import get_analysed_data
from face_parsing import init_parsing_model, get_parsed_mask
# Глобальные константы и переменные
USE_COLAB = user_args.colab
USE_CUDA = user_args.cuda
PROVIDER = ["CPUExecutionProvider"]
DETECT_SIZE = 640
DETECT_THRESH = 0.6
FACE_ANALYSER = None
FACE_SWAPPER = None
FACE_PARSER = None
## ------------------------------ USER ARGS ------------------------------
parser = argparse.ArgumentParser(description="Swap-Mukham Face Swapper")
parser.add_argument("--out_dir", help="Default Output directory", default=os.getcwd())
parser.add_argument("--batch_size", help="Gpu batch size", default=32)
parser.add_argument("--cuda", action="store_true", help="Enable cuda", default=False)
parser.add_argument(
"--colab", action="store_true", help="Enable colab mode", default=False
)
user_args = parser.parse_args()
## ------------------------------ SET EXECUTION PROVIDER ------------------------------
# Note: Non CUDA users may change settings here
PROVIDER = ["CPUExecutionProvider"]
if USE_CUDA:
available_providers = onnxruntime.get_available_providers()
if "CUDAExecutionProvider" in available_providers:
print("\n********** Running on CUDA **********\n")
PROVIDER = ["CUDAExecutionProvider", "CPUExecutionProvider"]
else:
USE_CUDA = False
print("\n********** CUDA unavailable running on CPU **********\n")
else:
USE_CUDA = False
print("\n********** Running on CPU **********\n")
device = "cuda" if USE_CUDA else "cpu"
EMPTY_CACHE = lambda: torch.cuda.empty_cache() if device == "cuda" else None
# Функции загрузки моделей
def load_face_analyser_model(name="buffalo_l"):
global FACE_ANALYSER
if FACE_ANALYSER is None:
FACE_ANALYSER = insightface.app.FaceAnalysis(name=name, providers=PROVIDER)
FACE_ANALYSER.prepare(
ctx_id=0, det_size=(DETECT_SIZE, DETECT_SIZE), det_thresh=DETECT_THRESH
)
def load_face_swapper_model(path="./assets/pretrained_models/inswapper_128.onnx"):
global FACE_SWAPPER
if FACE_SWAPPER is None:
FACE_SWAPPER = Inswapper(model_file=path, batch_size=1, providers=PROVIDER)
def load_face_parser_model(path="./assets/pretrained_models/79999_iter.pth"):
global FACE_PARSER
if FACE_PARSER is None:
FACE_PARSER = init_parsing_model(path, device=device)
# Загрузка всех моделей
load_face_analyser_model()
load_face_swapper_model()
load_face_parser_model()
def base64_to_image(base64_string):
img_data = base64.b64decode(base64_string)
nparr = np.frombuffer(img_data, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
return img
def image_to_base64(image):
_, buffer = cv2.imencode('.png', image)
return base64.b64encode(buffer).decode('utf-8')
def process_images(source_img_base64, target_img_base64):
# Декодирование base64 в изображения
source_img = base64_to_image(source_img_base64)
target_img = base64_to_image(target_img_base64)
# Анализ лиц
analysed_targets, analysed_sources, _, _ = get_analysed_data(
FACE_ANALYSER,
[target_img],
source_img,
swap_condition="First",
detect_condition="best detection"
)
# Замена лица
preds = []
matrs = []
for batch_pred, batch_matr in FACE_SWAPPER.batch_forward([target_img], analysed_targets, analysed_sources):
preds.extend(batch_pred)
matrs.extend(batch_matr)
# Парсинг лица и создание маски
masks = get_parsed_mask(FACE_PARSER, preds, classes=["skin", "l_brow", "r_brow", "l_eye", "r_eye", "nose", "u_lip", "l_lip", "mouth"], device='cpu')
# Наложение результата обратно на изображение
result_img = paste_to_whole(preds[0], target_img, matrs[0], mask=masks[0])
# Кодирование результата в base64
result_base64 = image_to_base64(result_img)
return result_base64
# Создание FastAPI приложения
app = FastAPI(title="Faceswap API", description="API для замены лица. Отправьте два изображения в формате base64.")
# Определение модели запроса
class SwapRequest(BaseModel):
source_img: str
target_img: str
@app.post("/swap_face")
async def swap_face(request: SwapRequest):
try:
result = process_images(request.source_img, request.target_img)
return {"result": result}
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
# Запуск сервера
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)