Поиск
GHOST-image

GHOST

Модель состоит из нескольких основных блоков: Identity Encoder (кодируется форма лица-источника), Attribute Encoder (кодируются отличительные особенности лица-источника) и механизм блендинга (встраивание лица в целевое изображение или видео). Отличительная особенность — перенос лица производится с одного фото (one shot модель), дополнительные ракурсы не требуются. Модель GHOST в составе пайплайна переноса содержит несколько этапов постобработки, которые позволяют добиться лучшего качества итогового изображения: специальная процедура блендинга с размытием маски, а также повышение разрешения лица позволяют получить более высокую детализацию.

Лицензия

Other

Модель GHOST в составе пайплайна переноса содержит несколько этапов постобработки, которые позволяют добиться лучшего качества итогового изображения: специальная процедура блендинга с размытием маски, а также повышение разрешения лица позволяют получить более высокую детализацию.

Изображение

Подробную информацию о модели можно прочитать в статье на Хабре и в соответствующем репозитории:

Информация об использовании модели:

Версия модели GHOST принимает на вход изображение-источник, а также целевое изображение или видео, в которое будет выполняться перенос. Результатом является изображение или видео с перенесенным лицом.

Отправка запроса к сервису

Обращение к модели требует правильно сформированного json-запроса. Далее указан пример универсального запроса к модели, который может быть использован как для переноса на изображение, так и на видео.

Импорт необходимых библиотек

import json
import requests
import boto3
import base64
import time
import uuid
from io import BytesIO
import numpy as np

Определяем, переносим ли мы на изображение или видео

image_to_image = True

Объявляем вспомогательные функции

jpg_img = cv2.imencode(".jpg", img)
img_b64 = base64.b64encode(jpg_img[1]).decode("utf-8")
return img_b64

def decode_img(img_b64):
"""
Decode bs64 image to np.ndarray format
"""
bin_img = base64.b64decode(img_b64)
buff = BytesIO(bin_img)
img = cv2.imdecode(np.frombuffer(buff.getbuffer(), np.uint8), -1)
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
return img

def get_update_session(auth_url, 
x_api_key,
x_workspace_id, 
email, 
password, 
sess=None):
if sess is None:
sess = requests.Session()
sess.headers.update({
"Content-Type": "application/json",
"x-api-key": x_api_key
})
resp = sess.post(auth_url, json=dict(email=email, password=password))
token = resp.json()["token"]["access_token"]
sess.headers.update({"authorization": token})
sess.headers.update({"x-workspace-id": x_workspace_id})
return sess

Задаем параметры s3

Инструкция для получения credentials доступна по ссылке

s3_credentials = {
"endpoint_url" : "endpoint_url",
"namespace" : "namespace",
"bucket" : "bucket",
"access_key_id" : "access_key_id",
"security_access_key" : "security_access_key",}

Указываем путь до source фотографии и target источника

PATH_TO_IMAGE = "path/to/source/image"
if image_to_image:
PATH_TO_TARGET_IMAGE = "path/to/target/image"
else:
PATH_TO_VIDEO = "path/to/target/video"

Загружаем видео на s3 или кодируем изображение в зависимости от поставленной задачи

if not image_to_image:
s3 = boto3.client(
service_name="s3",
endpoint_url=s3_credentials["endpoint_url"],
aws_access_key_id=s3_credentials["access_key_id"],
aws_secret_access_key=s3_credentials["security_access_key"],
)

if not image_to_image:
FOLDER_TO_SAVE = "videos/original" # папка, куда этот файл будет загружен на s3
s3.upload_file(PATH_TO_VIDEO, s3_credentials["bucket"], f"{FOLDER_TO_SAVE}/{PATH_TO_VIDEO.split("/")[-1]}")
Xs_raw = cv2.imread(PATH_TO_IMAGE)
source_encoded = encode_img(Xs_raw[:, :, ::-1])
if  image_to_image:
Xt_raw = cv2.imread(PATH_TO_TARGET_IMAGE)
target_encoded = encode_img(Xt_raw[:, :, ::-1])

Составляем json-запрос

if  image_to_image:
request_json = {"source_image" : source_encoded,
"target_image" : target_encoded,
"use_sr" : True}
else:
request_json = {"source_image" : source_encoded,
"path_to_video" : f"{FOLDER_TO_SAVE}/{PATH_TO_VIDEO.split("/")[-1]}", # путь до видео на s3
"s3_credentials": s3_credentials, # параметры s3 
"folder_to_save": "videos/result", # путь до директории сохранения
"fast_cpu": True,
"use_sr" : True}

Отправляем запрос модели

LOCAL = False # надо поставить True, если app.py запущен локально
deploy_id = "deploy_id" 

if LOCAL:
start = time.time()
results_from_cristo = requests.post("http://00.00.00.00:8080/v1/models/kfserving-default:predict", json=request_json)
print(time.time() - start)
else:
start = time.time()
sess = get_update_session("https://api.aicloud.sbercloud.ru/public/v2/service_auth", 
"x_api_key", 
"x_workspace_id",
"email", # email=ID
"password") # password=secret

results_from_cristo = sess.post(
"https://api.aicloud.sbercloud.ru/public/v2/inference/v1/predict/kfserving-{deploy_id}/kfserving-{deploy_id}/",
json=request_json
)

print(time.time() - start)

Сохраняем результаты

from matplotlib import pyplot as plt
if image_to_image:
result = results_from_cristo.json()["result"]
result_image = decode_img(result)
plt.imshow(result_image[:,:,::-1])
else:
path_to_result = results_from_cristo.json()["path_to_result"]
result_name = path_to_result.split("/")[-1]
s3.download_file(s3_credentia["bucket"], path_to_result, result_name)
print(result_name) 

Оценки модели на популярных датасетах /n Примеры переноса лица на изображениях из датасетов VGG Face 2 и CelebA HQ.

Изображение

Было проведено сравнение GHOST модели и известных SoTA решений. Все метрики рассчитываются так, как описано в статьях FaceShifter,  SimSwap, Hifiswap,  Smooth-Swap. Не углубляясь в математические формулировки, используемые метрики можно описать следующим образом:

  • ID retrieval и shape_ringnet — отвечают за сохранение identity (форма головы и т.д.);
  • exp_ringnet — отвечает за выражение лица и сохранение эмоций;
  • pose_ringnet и poseHN — отвечают за сохранение позы с помощью моделей Ringnet и Hopenet;
  • eye_ldmk — за сохранение направления взгляда.

По ряду метрик разработанная модель имеет существенное преимущество при оценке на датасете FaceForensics++. Звездочками показаны наилучшие значения для каждой метрики.

methodID retrievalexp_ringneteye_ldmkposeHNpose_ringnetshape_ringnet
FaceSwap (2016)58.820.305 💥4.221.940.0450.75
DeepFakes (2018)72.420.69611.67.350.1100.65
FaceShifter (2019)82.020.4202.481.93 💥0.0400.67
SimSwap (2021)87.420.3402.912.130.035 💥0.72
HifiFace (2021)89.170.5102.042.130.0480.64 💥
Ours90.61 💥0.4362.02 💥2.260.0470.64 💥

Обратная связь

Круглосуточная поддержка по телефону 8 800 444-24-99, почте support@cloud.ru и в Telegram