Deepfake-Shield / src /process_video.py
leoorb's picture
Upload 23 files
9c1a6bf verified
Raw
History Blame Contribute Delete
2.99 kB
import cv2
import torch
import torch.nn.functional as F
from PIL import Image
def analyze_video(video_path, vision_model, transform):
"""
Extrait 1 frame par seconde sur max 10 secondes.
Détecte le visage, recadre et analyse avec vision_model.
"""
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise Exception("Impossible de lire la vidéo.")
fps = cap.get(cv2.CAP_PROP_FPS)
if fps <= 0:
fps = 30 # Fallback approximatif
# Initialisation du détecteur de visage OpenCV (Haar Cascade)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
frames_extracted = []
max_seconds = 10
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
for sec in range(max_seconds):
frame_idx = int(fps * sec)
if frame_idx >= total_frames:
break
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_idx)
ret, frame = cap.read()
if not ret:
break
# Conversion du frame en niveaux de gris pour la détection
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Détection des visages
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
if len(faces) == 0:
# Si on ne trouve pas de visage, on ignore simplement la frame
continue
# Recadrage sur le premier pseudo-visage (le plus saillant)
(x, y, w, h) = faces[0]
face_roi = frame[y:y+h, x:x+w]
# Conversion BGR -> RGB du visage recadré
face_rgb = cv2.cvtColor(face_roi, cv2.COLOR_BGR2RGB)
# Conversion en PIL Image
img_pil = Image.fromarray(face_rgb)
frames_extracted.append(img_pil)
cap.release()
if not frames_extracted:
raise Exception("Aucune frame avec un visage n'a pu être extraite. La vidéo est soit vide, soit aucun visage n'est visible.")
# Device où le modèle est chargé
device = next(vision_model.parameters()).device
fake_probs = []
for img in frames_extracted:
img_tensor = transform(img).unsqueeze(0).to(device)
with torch.no_grad():
outputs = vision_model(img_tensor)
# Calcul explicite des probabilités via softmax
probabilities = F.softmax(outputs, dim=1)[0]
# Index 0 = Fake/IA
prob_fake = float(probabilities[0].item())
fake_probs.append(prob_fake)
# Le score moyen de probabilité "Fake"
average_fake_prob = sum(fake_probs) / len(fake_probs)
# Décision stricte : la moyenne des probabilités IA doit dépasser 75%
if average_fake_prob > 0.75:
return {"prediction": "IA", "probability": average_fake_prob}
else:
return {"prediction": "Humain", "probability": 1.0 - average_fake_prob}