Zeyadd-Mostaffa commited on
Commit
fac7f40
·
verified ·
1 Parent(s): 86e5b53

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +14 -16
app.py CHANGED
@@ -6,18 +6,16 @@ from tensorflow.keras.models import load_model, Model
6
  from tensorflow.keras.preprocessing.image import img_to_array
7
  from tensorflow.keras.applications.xception import preprocess_input as xcp_pre
8
  from tensorflow.keras.applications.efficientnet import preprocess_input as eff_pre
9
- from PIL import Image
10
- import matplotlib.pyplot as plt
11
-
12
  from huggingface_hub import hf_hub_download
 
13
 
 
14
  xcp_path = hf_hub_download(repo_id="Zeyadd-Mostaffa/deepfake-image-detector", filename="xception_model.h5")
15
  eff_path = hf_hub_download(repo_id="Zeyadd-Mostaffa/deepfake-image-detector", filename="efficientnet_model.h5")
16
-
17
  xcp_model = load_model(xcp_path)
18
  eff_model = load_model(eff_path)
19
 
20
- # Face detection
21
  def detect_face_opencv(pil_image):
22
  cv_img = np.array(pil_image.convert("RGB"))
23
  cv_img = cv_img[:, :, ::-1] # RGB to BGR
@@ -25,11 +23,11 @@ def detect_face_opencv(pil_image):
25
  gray = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
26
  faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=4)
27
  if len(faces) == 0:
28
- return pil_image # fallback
29
- (x, y, w, h) = max(faces, key=lambda b: b[2]*b[3]) # largest face
30
  return pil_image.crop((x, y, x+w, y+h))
31
 
32
- # Grad-CAM
33
  def grad_cam(model, img, size, preprocess_func):
34
  img_resized = img.resize(size)
35
  x = img_to_array(img_resized)
@@ -45,7 +43,7 @@ def grad_cam(model, img, size, preprocess_func):
45
  cam = np.mean(grads, axis=-1)
46
  cam = np.maximum(cam, 0)
47
  cam /= cam.max() if cam.max() != 0 else 1
48
- heatmap = cv2.resize(cam.numpy(), (size[0], size[1]))
49
  heatmap = np.uint8(255 * heatmap)
50
  heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
51
 
@@ -55,14 +53,14 @@ def grad_cam(model, img, size, preprocess_func):
55
  superimposed = cv2.addWeighted(img_np, 0.6, heatmap, 0.4, 0)
56
  return Image.fromarray(cv2.cvtColor(superimposed, cv2.COLOR_BGR2RGB))
57
 
58
- # Preprocessing
59
- def preprocess(img, size, preprocess_func):
60
  img = img.resize(size)
61
  arr = img_to_array(img)
62
  arr = np.expand_dims(arr, axis=0)
63
- return preprocess_func(arr)
64
 
65
- # Prediction logic
66
  def predict(image):
67
  face = detect_face_opencv(image)
68
 
@@ -72,17 +70,17 @@ def predict(image):
72
  xcp_pred = xcp_model.predict(xcp_input)[0][0]
73
  eff_pred = eff_model.predict(eff_input)[0][0]
74
  ensemble_prob = (xcp_pred + eff_pred) / 2
75
- label = "REAL" if ensemble_prob > 0.5 else "FAKE"
76
 
 
77
  cam_img = grad_cam(xcp_model, face, (299, 299), xcp_pre)
78
 
79
  return f"{label} ({ensemble_prob:.2%} confidence)", cam_img
80
 
81
- # Gradio interface
82
  gr.Interface(
83
  fn=predict,
84
  inputs=gr.Image(type="pil"),
85
  outputs=["text", "image"],
86
  title="Deepfake Image Detector (with Grad-CAM)",
87
- description="Upload an image. We detect the face, classify using an ensemble (Xception + EfficientNetB4), and explain the prediction with Grad-CAM."
88
  ).launch()
 
6
  from tensorflow.keras.preprocessing.image import img_to_array
7
  from tensorflow.keras.applications.xception import preprocess_input as xcp_pre
8
  from tensorflow.keras.applications.efficientnet import preprocess_input as eff_pre
 
 
 
9
  from huggingface_hub import hf_hub_download
10
+ from PIL import Image
11
 
12
+ # Load models from Hugging Face Hub
13
  xcp_path = hf_hub_download(repo_id="Zeyadd-Mostaffa/deepfake-image-detector", filename="xception_model.h5")
14
  eff_path = hf_hub_download(repo_id="Zeyadd-Mostaffa/deepfake-image-detector", filename="efficientnet_model.h5")
 
15
  xcp_model = load_model(xcp_path)
16
  eff_model = load_model(eff_path)
17
 
18
+ # Face detection using OpenCV
19
  def detect_face_opencv(pil_image):
20
  cv_img = np.array(pil_image.convert("RGB"))
21
  cv_img = cv_img[:, :, ::-1] # RGB to BGR
 
23
  gray = cv2.cvtColor(cv_img, cv2.COLOR_BGR2GRAY)
24
  faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=4)
25
  if len(faces) == 0:
26
+ return pil_image # fallback to original
27
+ (x, y, w, h) = max(faces, key=lambda b: b[2]*b[3])
28
  return pil_image.crop((x, y, x+w, y+h))
29
 
30
+ # Grad-CAM visualization (Xception only)
31
  def grad_cam(model, img, size, preprocess_func):
32
  img_resized = img.resize(size)
33
  x = img_to_array(img_resized)
 
43
  cam = np.mean(grads, axis=-1)
44
  cam = np.maximum(cam, 0)
45
  cam /= cam.max() if cam.max() != 0 else 1
46
+ heatmap = cv2.resize(cam, size)
47
  heatmap = np.uint8(255 * heatmap)
48
  heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
49
 
 
53
  superimposed = cv2.addWeighted(img_np, 0.6, heatmap, 0.4, 0)
54
  return Image.fromarray(cv2.cvtColor(superimposed, cv2.COLOR_BGR2RGB))
55
 
56
+ # Preprocessing helper
57
+ def preprocess(img, size, func):
58
  img = img.resize(size)
59
  arr = img_to_array(img)
60
  arr = np.expand_dims(arr, axis=0)
61
+ return func(arr)
62
 
63
+ # Prediction function
64
  def predict(image):
65
  face = detect_face_opencv(image)
66
 
 
70
  xcp_pred = xcp_model.predict(xcp_input)[0][0]
71
  eff_pred = eff_model.predict(eff_input)[0][0]
72
  ensemble_prob = (xcp_pred + eff_pred) / 2
 
73
 
74
+ label = "REAL" if ensemble_prob > 0.5 else "FAKE"
75
  cam_img = grad_cam(xcp_model, face, (299, 299), xcp_pre)
76
 
77
  return f"{label} ({ensemble_prob:.2%} confidence)", cam_img
78
 
79
+ # Gradio UI
80
  gr.Interface(
81
  fn=predict,
82
  inputs=gr.Image(type="pil"),
83
  outputs=["text", "image"],
84
  title="Deepfake Image Detector (with Grad-CAM)",
85
+ description="Upload an image. We detect the face, classify using an ensemble (Xception + EfficientNetB4), and explain the prediction using Grad-CAM on Xception."
86
  ).launch()