adam-hassen
Ajout fonctionnalités de suivi
a3da09c
Raw
History Blame Contribute Delete
3.66 kB
import cv2
import numpy as np
import base64
def compare_faces(face1_base64, face2_base64, threshold=0.50): # Seuil plus haut
"""
Compare deux images de visages en base64
Retourne (is_match, score)
"""
try:
# Décoder les images base64
if ',' in face1_base64:
face1_bytes = base64.b64decode(face1_base64.split(',')[1])
else:
face1_bytes = base64.b64decode(face1_base64)
if ',' in face2_base64:
face2_bytes = base64.b64decode(face2_base64.split(',')[1])
else:
face2_bytes = base64.b64decode(face2_base64)
# Convertir en images OpenCV
nparr1 = np.frombuffer(face1_bytes, np.uint8)
nparr2 = np.frombuffer(face2_bytes, np.uint8)
img1 = cv2.imdecode(nparr1, cv2.IMREAD_COLOR)
img2 = cv2.imdecode(nparr2, cv2.IMREAD_COLOR)
if img1 is None or img2 is None:
print("❌ Impossible de décoder les images")
return False, 0
# Redimensionner
img1 = cv2.resize(img1, (100, 100))
img2 = cv2.resize(img2, (100, 100))
# Convertir en gris
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# MÉTHODE 1: Corrélation croisée (POIDS FORT)
try:
result = cv2.matchTemplate(gray1, gray2, cv2.TM_CCOEFF_NORMED)
corr_score = result[0][0]
except:
corr_score = 0.0
# MÉTHODE 2: MSE (Mean Squared Error) - moins de poids
mse = np.mean((gray1.astype(float) - gray2.astype(float)) ** 2)
max_mse = 255**2
mse_score = 1 - min(mse / max_mse, 1)
# MÉTHODE 3: Différence structurelle (Sobel) - NOUVEAU
sobel1 = cv2.Sobel(gray1, cv2.CV_64F, 1, 1, ksize=5)
sobel2 = cv2.Sobel(gray2, cv2.CV_64F, 1, 1, ksize=5)
sobel_diff = np.mean(np.abs(sobel1 - sobel2))
sobel_score = 1 - min(sobel_diff / 1000, 1)
# MÉTHODE 4: Histogrammes (poids FAIBLE car sensible aux couleurs)
hist1 = cv2.calcHist([gray1], [0], None, [256], [0, 256])
hist2 = cv2.calcHist([gray2], [0], None, [256], [0, 256])
hist_score = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
hist_score = max(0, min(1, hist_score))
# NOUVEAU: Détection de visage pour vérifier
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
faces1 = face_cascade.detectMultiScale(gray1, 1.1, 4)
faces2 = face_cascade.detectMultiScale(gray2, 1.1, 4)
is_face1 = len(faces1) > 0
is_face2 = len(faces2) > 0
# Score combiné avec NOUVEAUX POIDS
# On donne plus de poids à la corrélation et à Sobel (forme)
# Moins de poids aux histogrammes (couleur)
final_score = (corr_score * 0.5 + mse_score * 0.1 + sobel_score * 0.3 + hist_score * 0.1)
# Pénalité si ce n'est pas un visage
if not is_face1 or not is_face2:
final_score *= 0.5
print("⚠️ Image non faciale détectée - score réduit")
print(f"📊 Scores - Corr: {corr_score:.2%}, MSE: {mse_score:.2%}, Sobel: {sobel_score:.2%}, Hist: {hist_score:.2%}")
print(f"📈 Score final: {final_score:.2%}")
return final_score > threshold, final_score
except Exception as e:
print(f"❌ Erreur comparaison: {e}")
import traceback
traceback.print_exc()
return False, 0