File size: 5,303 Bytes
123fe15 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
import gradio as gr
import os
import uuid
import cv2
from mask import FaceSwapper # الكلاس اللي عملناه قبل كده
# تحميل الموديل مره واحده
swapper = FaceSwapper(
model_path="models/inswapper_128.onnx",
gfpgan_model_path="gfpgan/weights/GFPGANv1.4.pth"
)
# دالة للتعامل مع Gradio
def swap_faces(source_img, target_img):
try:
# حفظ الصور المرفوعة مؤقتاً
source_path = f"temp_source_{uuid.uuid4().hex}.jpg"
target_path = f"temp_target_{uuid.uuid4().hex}.jpg"
output_path = f"img/result_{uuid.uuid4().hex}.jpg"
cv2.imwrite(source_path, cv2.cvtColor(source_img, cv2.COLOR_RGB2BGR))
cv2.imwrite(target_path, cv2.cvtColor(target_img, cv2.COLOR_RGB2BGR))
# تنفيذ face swap
result_path = swapper.merge_face_into_image(source_path, target_path, output_path)
# تحميل الصورة الناتجة وعرضها
result_img = cv2.cvtColor(cv2.imread(result_path), cv2.COLOR_BGR2RGB)
# مسح الملفات المؤقتة
os.remove(source_path)
os.remove(target_path)
return result_img
except Exception as e:
return f"❌ حصل خطأ: {str(e)}"
# واجهة Gradio
demo = gr.Interface(
fn=swap_faces,
inputs=[
gr.Image(type="numpy", label="Source Image (الطفل)"),
gr.Image(type="numpy", label="Target Image (المشهد)")
],
outputs=gr.Image(type="numpy", label="النتيجة"),
title="FaceSwap with GFPGAN",
description="ارفع صورتين: (1) صورة الطفل (2) المشهد اللي عايز تدخله فيه. وهنرجعلك صورة face swap محسّنة بـ GFPGAN."
)
if __name__ == "__main__":
demo.launch(server_name="127.0.0.1", server_port=7860)
"""import cv2
import insightface
import numpy as np
import os
from gfpgan import GFPGANer # pip install gfpgan"""
"""class FaceSwapper:
def __init__(self,
model_path="models/inswapper_128.onnx",
gfpgan_model_path="gfpgan/weights/GFPGANv1.4.pth"):
# ============ تحميل FaceAnalysis ============
self.app = insightface.app.FaceAnalysis(name="buffalo_l", providers=['CPUExecutionProvider'])
self.app.prepare(ctx_id=0, det_size=(640, 640))
# ============ تحميل inswapper ============
if not os.path.exists(model_path):
raise FileNotFoundError(f"❌ الموديل مش موجود في: {model_path}")
self.swapper = insightface.model_zoo.get_model(model_path, providers=['CPUExecutionProvider'])
# ============ تحميل GFPGAN ============
self.gfpganer = GFPGANer(
model_path=gfpgan_model_path,
upscale=1,
arch="clean",
channel_multiplier=2
)
# ============ دالة مساعدة لاختيار أكبر وجه ============
@staticmethod
def get_biggest_face(faces):
return max(faces, key=lambda f: (f.bbox[2]-f.bbox[0]) * (f.bbox[3]-f.bbox[1]))
# ============ دالة الدمج ============
def merge_face_into_image(self, source_img_path, target_img_path, output_path):
source_img = cv2.imread(source_img_path)
target_img = cv2.imread(target_img_path)
if source_img is None or target_img is None:
raise ValueError("❌ مشكلة في قراءة الصور")
source_faces = self.app.get(source_img)
target_faces = self.app.get(target_img)
if not source_faces or not target_faces:
#raise ValueError("❌ مش لاقي وش في الصورة!")
print("⚠️ No faces detected, returning target image as-is.")
cv2.imwrite(output_path, target_img)
return output_path
source_face = self.get_biggest_face(source_faces)
target_face = self.get_biggest_face(target_faces)
# استبدال الوجه
swapped_img = self.swapper.get(target_img.copy(), target_face, source_face, paste_back=True)
# قص الوجه من الصورة
x1, y1, x2, y2 = target_face.bbox.astype(int)
x1, y1 = max(0, x1), max(0, y1)
x2, y2 = min(swapped_img.shape[1], x2), min(swapped_img.shape[0], y2)
face_crop = swapped_img[y1:y2, x1:x2]
if face_crop.size == 0:
raise ValueError("❌ الوجه المقطوع فاضي (bbox مش مظبوط)")
# ماسك بنفس حجم الوجه
mask = 255 * np.ones(face_crop.shape, face_crop.dtype)
mask = cv2.GaussianBlur(mask, (25, 25), 30)
# مركز الوجه
center = ((x1 + x2) // 2, (y1 + y2) // 2)
# دمج الوجه في الصورة
blended = cv2.seamlessClone(face_crop, swapped_img, mask, center, cv2.NORMAL_CLONE)
# تحسين الصورة بالـ GFPGAN
_, _, enhanced = self.gfpganer.enhance(blended, has_aligned=False, only_center_face=False, paste_back=True)
final_img = enhanced # أو blended لو GFPGAN مش موجود
return cv2.cvtColor(final_img, cv2.COLOR_BGR2RGB)"""
|