Update app.py
Browse files
app.py
CHANGED
@@ -1,33 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
import cv2
|
3 |
import torch
|
4 |
-
import dlib
|
5 |
import numpy as np
|
6 |
-
|
7 |
from torchvision import models, transforms
|
8 |
from tempfile import NamedTemporaryFile
|
9 |
-
import shutil
|
10 |
-
# Load face detector and landmark predictor
|
11 |
-
face_detector = dlib.get_frontal_face_detector()
|
12 |
-
PREDICTOR_PATH = "./shape_predictor_81_face_landmarks.dat"
|
13 |
-
face_predictor = dlib.shape_predictor(PREDICTOR_PATH)
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
resnet34.fc = torch.nn.Linear(resnet34.fc.in_features, 2)
|
21 |
-
ckpt_path = "./resnet34.pkl"
|
22 |
-
|
23 |
-
# Save model state dict
|
24 |
-
torch.save(resnet34.state_dict(), ckpt_path)
|
25 |
-
print(f"✅ Model saved at {ckpt_path}")
|
26 |
|
27 |
# Load deepfake detection model
|
28 |
model = models.resnet34()
|
29 |
model.fc = torch.nn.Linear(model.fc.in_features, 2)
|
30 |
-
model.load_state_dict(torch.load(
|
31 |
model.eval()
|
32 |
|
33 |
# Define transformation for face images
|
@@ -38,6 +146,12 @@ transform = transforms.Compose([
|
|
38 |
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
|
39 |
])
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
def process_video(video_path: str):
|
42 |
cap = cv2.VideoCapture(video_path)
|
43 |
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
@@ -53,29 +167,32 @@ def process_video(video_path: str):
|
|
53 |
break
|
54 |
|
55 |
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
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 |
output_video.write(frame)
|
81 |
|
@@ -83,27 +200,25 @@ def process_video(video_path: str):
|
|
83 |
output_video.release()
|
84 |
return output_path
|
85 |
|
|
|
86 |
def gradio_interface(video_file):
|
87 |
if video_file is None:
|
88 |
return "Error: No video uploaded."
|
89 |
|
90 |
-
# Create a temporary file and copy the uploaded video content
|
91 |
with NamedTemporaryFile(delete=False, suffix=".mp4") as temp_file:
|
92 |
temp_file_path = temp_file.name
|
93 |
-
# Read the uploaded video file using its path
|
94 |
with open(video_file, "rb") as uploaded_file:
|
95 |
temp_file.write(uploaded_file.read())
|
96 |
|
97 |
output_path = process_video(temp_file_path)
|
98 |
return output_path
|
99 |
|
100 |
-
# Gradio UI
|
101 |
iface = gr.Interface(
|
102 |
fn=gradio_interface,
|
103 |
inputs=gr.Video(label="Upload Video"),
|
104 |
outputs=gr.Video(label="Processed Video"),
|
105 |
title="Deepfake Detection",
|
106 |
-
description="Upload a video to detect deepfakes
|
107 |
)
|
108 |
|
109 |
if __name__ == "__main__":
|
|
|
1 |
+
# import gradio as gr
|
2 |
+
# import cv2
|
3 |
+
# import torch
|
4 |
+
# import dlib
|
5 |
+
# import numpy as np
|
6 |
+
# from imutils import face_utils
|
7 |
+
# from torchvision import models, transforms
|
8 |
+
# from tempfile import NamedTemporaryFile
|
9 |
+
# import shutil
|
10 |
+
# # Load face detector and landmark predictor
|
11 |
+
# face_detector = dlib.get_frontal_face_detector()
|
12 |
+
# PREDICTOR_PATH = "./shape_predictor_81_face_landmarks.dat"
|
13 |
+
# face_predictor = dlib.shape_predictor(PREDICTOR_PATH)
|
14 |
+
|
15 |
+
# import torch
|
16 |
+
# import torchvision.models as models
|
17 |
+
|
18 |
+
# # Load pretrained ResNet-34 model
|
19 |
+
# resnet34 = models.resnet34(weights=models.ResNet34_Weights.IMAGENET1K_V1)
|
20 |
+
# resnet34.fc = torch.nn.Linear(resnet34.fc.in_features, 2)
|
21 |
+
# ckpt_path = "./resnet34.pkl"
|
22 |
+
|
23 |
+
# # Save model state dict
|
24 |
+
# torch.save(resnet34.state_dict(), ckpt_path)
|
25 |
+
# print(f"✅ Model saved at {ckpt_path}")
|
26 |
+
|
27 |
+
# # Load deepfake detection model
|
28 |
+
# model = models.resnet34()
|
29 |
+
# model.fc = torch.nn.Linear(model.fc.in_features, 2)
|
30 |
+
# model.load_state_dict(torch.load(ckpt_path, map_location="cpu"))
|
31 |
+
# model.eval()
|
32 |
+
|
33 |
+
# # Define transformation for face images
|
34 |
+
# transform = transforms.Compose([
|
35 |
+
# transforms.ToPILImage(),
|
36 |
+
# transforms.Resize((224, 224)),
|
37 |
+
# transforms.ToTensor(),
|
38 |
+
# transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
|
39 |
+
# ])
|
40 |
+
|
41 |
+
# def process_video(video_path: str):
|
42 |
+
# cap = cv2.VideoCapture(video_path)
|
43 |
+
# width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
44 |
+
# height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
45 |
+
# fps = int(cap.get(cv2.CAP_PROP_FPS))
|
46 |
+
|
47 |
+
# output_path = video_path.replace(".mp4", "_processed.mp4")
|
48 |
+
# output_video = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (width, height))
|
49 |
+
|
50 |
+
# while cap.isOpened():
|
51 |
+
# ret, frame = cap.read()
|
52 |
+
# if not ret:
|
53 |
+
# break
|
54 |
+
|
55 |
+
# rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
56 |
+
# faces = face_detector(rgb_frame, 1)
|
57 |
+
|
58 |
+
# for face in faces:
|
59 |
+
# landmarks = face_utils.shape_to_np(face_predictor(rgb_frame, face))
|
60 |
+
# x_min, y_min = np.min(landmarks, axis=0)
|
61 |
+
# x_max, y_max = np.max(landmarks, axis=0)
|
62 |
+
|
63 |
+
# face_crop = rgb_frame[y_min:y_max, x_min:x_max]
|
64 |
+
# if face_crop.size == 0:
|
65 |
+
# continue
|
66 |
+
|
67 |
+
# face_tensor = transform(face_crop).unsqueeze(0)
|
68 |
+
# with torch.no_grad():
|
69 |
+
# output = torch.softmax(model(face_tensor), dim=1)
|
70 |
+
# fake_confidence = output[0, 1].item() * 100 # Fake confidence as a percentage
|
71 |
+
# label = "Fake" if fake_confidence > 50 else "Real"
|
72 |
+
# color = (0, 0, 255) if label == "Fake" else (0, 255, 0)
|
73 |
+
|
74 |
+
# # Annotating confidence score with label
|
75 |
+
# label_text = f"{label} ({fake_confidence:.2f}%)"
|
76 |
+
|
77 |
+
# cv2.rectangle(frame, (x_min, y_min), (x_max, y_max), color, 2)
|
78 |
+
# cv2.putText(frame, label_text, (x_min, y_min - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)
|
79 |
+
|
80 |
+
# output_video.write(frame)
|
81 |
+
|
82 |
+
# cap.release()
|
83 |
+
# output_video.release()
|
84 |
+
# return output_path
|
85 |
+
|
86 |
+
# def gradio_interface(video_file):
|
87 |
+
# if video_file is None:
|
88 |
+
# return "Error: No video uploaded."
|
89 |
+
|
90 |
+
# # Create a temporary file and copy the uploaded video content
|
91 |
+
# with NamedTemporaryFile(delete=False, suffix=".mp4") as temp_file:
|
92 |
+
# temp_file_path = temp_file.name
|
93 |
+
# # Read the uploaded video file using its path
|
94 |
+
# with open(video_file, "rb") as uploaded_file:
|
95 |
+
# temp_file.write(uploaded_file.read())
|
96 |
+
|
97 |
+
# output_path = process_video(temp_file_path)
|
98 |
+
# return output_path
|
99 |
+
|
100 |
+
# # Gradio UI
|
101 |
+
# iface = gr.Interface(
|
102 |
+
# fn=gradio_interface,
|
103 |
+
# inputs=gr.Video(label="Upload Video"),
|
104 |
+
# outputs=gr.Video(label="Processed Video"),
|
105 |
+
# title="Deepfake Detection",
|
106 |
+
# description="Upload a video to detect deepfakes. The model will process faces and classify them as real or fake."
|
107 |
+
# )
|
108 |
+
|
109 |
+
# if __name__ == "__main__":
|
110 |
+
# iface.launch()
|
111 |
+
|
112 |
+
|
113 |
+
|
114 |
+
|
115 |
+
|
116 |
+
|
117 |
+
|
118 |
+
|
119 |
+
|
120 |
+
|
121 |
import gradio as gr
|
122 |
import cv2
|
123 |
import torch
|
|
|
124 |
import numpy as np
|
125 |
+
import mediapipe as mp
|
126 |
from torchvision import models, transforms
|
127 |
from tempfile import NamedTemporaryFile
|
|
|
|
|
|
|
|
|
|
|
128 |
|
129 |
+
# Initialize MediaPipe Face Detection and Face Mesh
|
130 |
+
mp_face_detection = mp.solutions.face_detection
|
131 |
+
mp_face_mesh = mp.solutions.face_mesh
|
132 |
+
face_detection = mp_face_detection.FaceDetection(model_selection=1, min_detection_confidence=0.5)
|
133 |
+
face_mesh = mp_face_mesh.FaceMesh(static_image_mode=False, max_num_faces=1, min_detection_confidence=0.5)
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
|
135 |
# Load deepfake detection model
|
136 |
model = models.resnet34()
|
137 |
model.fc = torch.nn.Linear(model.fc.in_features, 2)
|
138 |
+
model.load_state_dict(torch.load("resnet34.pkl", map_location="cpu"))
|
139 |
model.eval()
|
140 |
|
141 |
# Define transformation for face images
|
|
|
146 |
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
|
147 |
])
|
148 |
|
149 |
+
def get_face_bbox(landmarks, frame_shape):
|
150 |
+
h, w = frame_shape[:2]
|
151 |
+
xs = [lm.x * w for lm in landmarks.landmark]
|
152 |
+
ys = [lm.y * h for lm in landmarks.landmark]
|
153 |
+
return int(min(xs)), int(min(ys)), int(max(xs)), int(max(ys))
|
154 |
+
|
155 |
def process_video(video_path: str):
|
156 |
cap = cv2.VideoCapture(video_path)
|
157 |
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
|
|
167 |
break
|
168 |
|
169 |
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
170 |
+
|
171 |
+
# Face detection
|
172 |
+
results = face_detection.process(rgb_frame)
|
173 |
+
if results.detections:
|
174 |
+
for detection in results.detections:
|
175 |
+
# Get face landmarks
|
176 |
+
mesh_results = face_mesh.process(rgb_frame)
|
177 |
+
if mesh_results.multi_face_landmarks:
|
178 |
+
for face_landmarks in mesh_results.multi_face_landmarks:
|
179 |
+
x_min, y_min, x_max, y_max = get_face_bbox(face_landmarks, frame.shape)
|
180 |
+
|
181 |
+
face_crop = rgb_frame[y_min:y_max, x_min:x_max]
|
182 |
+
if face_crop.size == 0:
|
183 |
+
continue
|
184 |
+
|
185 |
+
face_tensor = transform(face_crop).unsqueeze(0)
|
186 |
+
with torch.no_grad():
|
187 |
+
output = torch.softmax(model(face_tensor), dim=1)
|
188 |
+
fake_confidence = output[0, 1].item() * 100
|
189 |
+
label = "Fake" if fake_confidence > 50 else "Real"
|
190 |
+
color = (0, 0, 255) if label == "Fake" else (0, 255, 0)
|
191 |
+
label_text = f"{label} ({fake_confidence:.2f}%)"
|
192 |
+
|
193 |
+
cv2.rectangle(frame, (x_min, y_min), (x_max, y_max), color, 2)
|
194 |
+
cv2.putText(frame, label_text, (x_min, y_min - 10),
|
195 |
+
cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)
|
196 |
|
197 |
output_video.write(frame)
|
198 |
|
|
|
200 |
output_video.release()
|
201 |
return output_path
|
202 |
|
203 |
+
# Rest of the Gradio interface remains the same
|
204 |
def gradio_interface(video_file):
|
205 |
if video_file is None:
|
206 |
return "Error: No video uploaded."
|
207 |
|
|
|
208 |
with NamedTemporaryFile(delete=False, suffix=".mp4") as temp_file:
|
209 |
temp_file_path = temp_file.name
|
|
|
210 |
with open(video_file, "rb") as uploaded_file:
|
211 |
temp_file.write(uploaded_file.read())
|
212 |
|
213 |
output_path = process_video(temp_file_path)
|
214 |
return output_path
|
215 |
|
|
|
216 |
iface = gr.Interface(
|
217 |
fn=gradio_interface,
|
218 |
inputs=gr.Video(label="Upload Video"),
|
219 |
outputs=gr.Video(label="Processed Video"),
|
220 |
title="Deepfake Detection",
|
221 |
+
description="Upload a video to detect deepfakes using MediaPipe face detection and ResNet-34 model."
|
222 |
)
|
223 |
|
224 |
if __name__ == "__main__":
|