File size: 3,992 Bytes
85fa7d2 |
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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
"""
Face Comparator - Comparaci贸n de embeddings con niveles de confianza adaptativos
"""
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from loguru import logger
class FaceComparator:
"""
Compara embeddings faciales con umbrales adaptativos.
Implementa el sistema de 3 niveles: Seguro, Probable, Descartado.
"""
def __init__(self, threshold=0.75):
"""
Args:
threshold: Umbral base de similitud (0.0-1.0)
"""
self.threshold = threshold
# Umbrales adaptativos
self.SECURE_MATCH = 0.85 # >85% = Match Seguro
self.PROBABLE_MATCH = 0.72 # 72-85% = Coincidencia Probable
# <72% = Descartado
def calculate_similarity(self, embedding1, embedding2):
"""
Calcula la similitud coseno entre dos embeddings.
Args:
embedding1: Vector de embedding 1
embedding2: Vector de embedding 2
Returns:
Similitud entre 0.0 y 1.0
"""
emb1 = np.array(embedding1).reshape(1, -1)
emb2 = np.array(embedding2).reshape(1, -1)
similarity = cosine_similarity(emb1, emb2)[0][0]
return float(similarity)
def verify_identity(self, source_emb, target_emb):
"""
Verifica identidad con an谩lisis de confianza adaptativo.
Returns:
Tupla (nivel_confianza: str, similitud: float)
"""
similarity = self.calculate_similarity(source_emb, target_emb)
if similarity > self.SECURE_MATCH:
confidence_level = "Match Seguro"
logger.info(f"Match Seguro: {similarity:.3f}")
elif similarity > self.PROBABLE_MATCH:
confidence_level = "Coincidencia Probable (Requiere revisi贸n)"
logger.info(f"Coincidencia Probable: {similarity:.3f}")
else:
confidence_level = "Descartado"
logger.debug(f"Descartado: {similarity:.3f}")
return confidence_level, similarity
def compare_embeddings(self, query_embedding, candidate_results):
"""
Compara el embedding query con m煤ltiples candidatos.
Args:
query_embedding: Embedding de la imagen query
candidate_results: Lista de resultados con embeddings
Returns:
Lista de matches verificados ordenados por similitud
"""
verified_matches = []
for candidate in candidate_results:
if 'embedding' not in candidate:
continue
# Calcular similitud
similarity = self.calculate_similarity(
query_embedding,
candidate['embedding']
)
# Solo incluir si supera el umbral
if similarity >= self.threshold:
# Determinar nivel de confianza
if similarity > self.SECURE_MATCH:
confidence_level = "Match Seguro"
elif similarity > self.PROBABLE_MATCH:
confidence_level = "Coincidencia Probable"
else:
confidence_level = "Baja confianza"
candidate['similarity'] = similarity
candidate['confidence_level'] = confidence_level
candidate['embedding_distance'] = 1 - similarity
candidate['verified'] = True
verified_matches.append(candidate)
logger.debug(f"Match verificado: {similarity:.3f} - {confidence_level}")
# Ordenar por similitud descendente
verified_matches.sort(key=lambda x: x['similarity'], reverse=True)
logger.info(f"Comparaci贸n completada: {len(verified_matches)}/{len(candidate_results)} verificados")
return verified_matches
|