Spaces:
Runtime error
Runtime error
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 | |
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) |