File size: 3,245 Bytes
8fed1b4
bf687e5
 
 
 
 
8fed1b4
bf687e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8fed1b4
 
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
import gradio as gr
import face_recognition
import numpy as np
import os
from PIL import Image
import dlib

# Verificar si CUDA está disponible y seleccionar el modelo adecuado
if dlib.DLIB_USE_CUDA:
    print("✅ CUDA está disponible. Se usará GPU para reconocimiento facial.")
    model_used = "cnn"  # Modelo optimizado para GPU
else:
    print("⚠ CUDA no está disponible. Se usará CPU para reconocimiento facial.")
    model_used = "hog"  # Modelo más adecuado para CPU

# 📂 Directorio donde se encuentran las imágenes
IMAGE_DIRECTORY = "dataset_faces/"

def load_images_and_encodings(directory):
    """
    Carga las imágenes y extrae sus embeddings.
    """
    known_encodings = []
    known_images = []
    known_names = []

    for filename in os.listdir(directory):
        if filename.lower().endswith((".jpg", ".png", ".jpeg")):
            path = os.path.join(directory, filename)
            image = face_recognition.load_image_file(path)
            encodings = face_recognition.face_encodings(image, model=model_used)
            if encodings:  # Si se detecta al menos una cara
                known_encodings.append(encodings[0])
                known_images.append(path)
                known_names.append(filename)
    return known_encodings, known_images, known_names

# Cargar los datos de la carpeta de imágenes
known_encodings, known_images, known_names = load_images_and_encodings(IMAGE_DIRECTORY)

def find_similar_faces_gradio(uploaded_image):
    """
    Dada una imagen subida, busca las imágenes similares del dataset.
    Devuelve una lista de diccionarios para la galería y un texto con detalles.
    """
    if uploaded_image is None:
        return [], "No se subió ninguna imagen."
    
    # Convertir la imagen subida a array de NumPy
    image_np = np.array(uploaded_image)
    face_encodings = face_recognition.face_encodings(image_np, model=model_used)
    if not face_encodings:
        return [], "⚠ No se detectó ningún rostro en la imagen subida."
    
    query_encoding = face_encodings[0]
    distances = face_recognition.face_distance(known_encodings, query_encoding)
    sorted_indices = np.argsort(distances)  # Ordenar por similitud (menor distancia = mayor similitud)
    
    # Mostrar las 5 imágenes más similares
    top_n = 5
    gallery_items = []
    details = ""
    for idx in sorted_indices[:top_n]:
        # Abrir la imagen del dataset
        img = Image.open(known_images[idx])
        similarity = 1 - distances[idx]  # Definir similitud (valor entre 0 y 1)
        caption = f"{os.path.basename(known_images[idx])}: Similitud: {similarity:.2f}"
        gallery_items.append({"image": img, "caption": caption})
        details += caption + "\n"
    
    return gallery_items, details

# Definir la interfaz con Gradio
demo = gr.Interface(
    fn=find_similar_faces_gradio,
    inputs=gr.Image(label="Sube una imagen", type="pil"),
    outputs=[
        gr.Gallery(label="Imágenes similares").style(grid=[2], height="auto"),
        gr.Textbox(label="Detalles de similitud", lines=5)
    ],
    title="🔍 Buscador de Rostros en un Directorio",
    description="Sube una imagen y se mostrarán las fotos más similares del directorio."
)

demo.launch()