Spaces:
Sleeping
Sleeping
File size: 3,355 Bytes
d888b34 de2634a 51e2b89 626beb9 de2634a b12ebb8 3724ecf de2634a 3724ecf b12ebb8 51e2b89 b12ebb8 de2634a 51e2b89 d350158 51e2b89 b12ebb8 51e2b89 de2634a b12ebb8 da7f914 de2634a d350158 b12ebb8 de2634a b12ebb8 d350158 b12ebb8 d350158 da7f914 d350158 de2634a 7d8ff14 b12ebb8 d350158 de2634a 51e2b89 b12ebb8 51e2b89 b12ebb8 a2e411b d350158 da7f914 b12ebb8 a2e411b de2634a b5fa44d de2634a 84927b1 de2634a b12ebb8 a2e411b 84927b1 da7f914 b12ebb8 |
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 |
import cv2
import numpy as np
import gradio as gr
from mtcnn import MTCNN
from tensorflow.keras.models import load_model
from tensorflow.keras.applications.xception import preprocess_input as xcp_pre
from tensorflow.keras.applications.efficientnet import preprocess_input as eff_pre
from huggingface_hub import hf_hub_download
# Load models
xcp_path = hf_hub_download(repo_id="Zeyadd-Mostaffa/deepfake-image-detector_final", filename="xception_model.h5")
eff_path = hf_hub_download(repo_id="Zeyadd-Mostaffa/deepfake-image-detector_final", filename="efficientnet_model.h5")
xcp_model = load_model(xcp_path)
eff_model = load_model(eff_path)
# Load MTCNN detector
detector = MTCNN()
# Filters
MIN_FACE_AREA = 6400 # 80x80 minimum face area
MIN_SHARPNESS = 20 # blur threshold
MIN_BRIGHTNESS = 30 # dark crop threshold
def is_blurry(image):
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
return cv2.Laplacian(gray, cv2.CV_64F).var() < MIN_SHARPNESS
def is_dark(image):
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
return np.mean(gray) < MIN_BRIGHTNESS
def predict(image):
faces = detector.detect_faces(image)
if not faces:
return "No face detected", image
output_image = image.copy()
results = []
face_count = 0
for idx, face in enumerate(faces):
x, y, w, h = face['box']
if w * h < MIN_FACE_AREA:
continue
margin = 0.2
img_h, img_w = image.shape[:2]
x = max(0, int(x - w * margin))
y = max(0, int(y - h * margin))
w = int(w * (1 + 2 * margin))
h = int(h * (1 + 2 * margin))
x2 = min(img_w, x + w)
y2 = min(img_h, y + h)
face_img = image[y:y2, x:x2]
if face_img.shape[0] < 40 or face_img.shape[1] < 40:
continue
if is_blurry(face_img) or is_dark(face_img):
continue
face_xcp = cv2.resize(face_img, (299, 299))
face_eff = cv2.resize(face_img, (224, 224))
xcp_tensor = xcp_pre(face_xcp.astype(np.float32))[np.newaxis, ...]
eff_tensor = eff_pre(face_eff.astype(np.float32))[np.newaxis, ...]
pred_xcp = xcp_model.predict(xcp_tensor, verbose=0).flatten()[0]
pred_eff = eff_model.predict(eff_tensor, verbose=0).flatten()[0]
avg = (pred_xcp + pred_eff) / 2
label = "Real" if avg > 0.41 else "Fake"
color = (0, 255, 0) if label == "Real" else (0, 0, 255)
face_count += 1
cv2.rectangle(output_image, (x, y), (x2, y2), color, 2)
cv2.putText(output_image, f"{label} ({avg:.2f})", (x, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)
results.append(f"Face {face_count}: {label} (Avg: {avg:.3f}, XCP: {pred_xcp:.3f}, EFF: {pred_eff:.3f})")
if not results:
return "No clear or confident face detected", output_image
return "\n".join(results), output_image
# Gradio Interface
interface = gr.Interface(
fn=predict,
inputs=gr.Image(type="numpy", label="Upload Image"),
outputs=[
gr.Textbox(label="Predictions"),
gr.Image(type="numpy", label="Annotated Image"),
],
title="Deepfake Detector (Multi-Face Ensemble)",
description="Detects all confident faces and classifies each one as real or fake using Xception and EfficientNetB4 ensemble."
)
interface.launch()
|