Segizu commited on
Commit
d9e1976
·
1 Parent(s): ea437dd

funcionando con DEeepface

Browse files
Files changed (3) hide show
  1. .gitignore +13 -0
  2. app.py +151 -30
  3. requirements.txt +6 -4
.gitignore ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .env
2
+ .venv
3
+ .env.local
4
+ .env.development.local
5
+ .env.test.local
6
+ .env.production.local
7
+
8
+ /venv
9
+ /embeddings
10
+ /batches
11
+ /metadata.csv
12
+ /metadata.csv.gz
13
+ /metadata.csv.gz.part
app.py CHANGED
@@ -15,6 +15,29 @@ import shutil
15
  import tarfile
16
  import tensorflow as tf
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  # 🔁 Limpiar almacenamiento temporal si existe
19
  def clean_temp_dirs():
20
  print("🧹 Limpiando carpetas temporales...")
@@ -28,7 +51,7 @@ def clean_temp_dirs():
28
  clean_temp_dirs()
29
 
30
  # 📁 Parámetros
31
- DATASET_ID = "Segizu/facial-recognition"
32
  EMBEDDINGS_SUBFOLDER = "embeddings"
33
  LOCAL_EMB_DIR = Path("embeddings")
34
  LOCAL_EMB_DIR.mkdir(exist_ok=True)
@@ -48,8 +71,47 @@ def get_folder_size(path):
48
  return total / (1024 ** 3)
49
 
50
  def preprocess_image(img: Image.Image) -> np.ndarray:
51
- img_rgb = img.convert("RGB")
52
- img_resized = img_rgb.resize((160, 160), Image.Resampling.LANCZOS)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  return np.array(img_resized)
54
 
55
  # ✅ Cargar CSV desde el dataset
@@ -60,7 +122,6 @@ dataset = load_dataset(
60
  column_names=["image"],
61
  header=0
62
  )
63
- @GPU
64
  def build_database():
65
  print(f"📊 Uso actual de almacenamiento temporal INICIO: {get_folder_size('.'):.2f} GB")
66
  print("🔄 Generando embeddings...")
@@ -171,49 +232,109 @@ def build_database():
171
 
172
  # 🔍 Buscar similitudes
173
  def find_similar_faces(uploaded_image: Image.Image):
 
 
 
174
  try:
 
 
 
 
 
 
 
 
175
  img_processed = preprocess_image(uploaded_image)
176
- query_embedding = DeepFace.represent(
177
- img_path=img_processed,
178
- model_name="Facenet",
179
- enforce_detection=False
180
- )[0]["embedding"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  del img_processed
182
  gc.collect()
 
183
  except Exception as e:
 
184
  return [], f"⚠ Error procesando imagen: {str(e)}"
185
 
186
  similarities = []
 
187
 
188
  try:
189
  embedding_files = [
190
  f for f in list_repo_files(DATASET_ID, repo_type="dataset", token=HF_TOKEN)
191
- if f.startswith(f"{EMBEDDINGS_SUBFOLDER}/") and f.endswith(".pkl")
192
  ]
 
193
  except Exception as e:
 
194
  return [], f"⚠ Error obteniendo archivos: {str(e)}"
195
 
196
- for file_path in embedding_files:
197
- try:
198
- file_bytes = requests.get(
199
- f"https://huggingface.co/datasets/{DATASET_ID}/resolve/main/{file_path}",
200
- headers=headers,
201
- timeout=10
202
- ).content
203
- record = pickle.loads(file_bytes)
204
-
205
- name = record["name"]
206
- img = record["img"]
207
- emb = record["embedding"]
208
-
209
- dist = np.linalg.norm(np.array(query_embedding) - np.array(emb))
210
- sim_score = 1 / (1 + dist)
211
- similarities.append((sim_score, name, np.array(img)))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
- except Exception as e:
214
- print(f"⚠ Error con {file_path}: {e}")
215
- continue
216
 
 
217
  similarities.sort(reverse=True)
218
  top = similarities[:5]
219
  gallery = [(img, f"{name} - Similitud: {sim:.2f}") for sim, name, img in top]
@@ -234,5 +355,5 @@ with gr.Blocks() as demo:
234
  build_btn = gr.Button("⚙️ Construir base de embeddings (usa GPU)")
235
  build_btn.click(fn=build_database, inputs=[], outputs=[])
236
 
237
- demo.launch()
238
 
 
15
  import tarfile
16
  import tensorflow as tf
17
 
18
+ # Configuración de GPU
19
+ print("Dispositivos GPU disponibles:", tf.config.list_physical_devices('GPU'))
20
+
21
+ # Configurar memoria GPU
22
+ gpus = tf.config.list_physical_devices('GPU')
23
+ if gpus:
24
+ try:
25
+ # Permitir crecimiento de memoria
26
+ for gpu in gpus:
27
+ tf.config.experimental.set_memory_growth(gpu, True)
28
+ print("✅ GPU configurada correctamente")
29
+
30
+ # Configurar para usar solo GPU
31
+ tf.config.set_visible_devices(gpus[0], 'GPU')
32
+ print(f"✅ Usando GPU: {gpus[0]}")
33
+ except RuntimeError as e:
34
+ print(f"⚠️ Error configurando GPU: {e}")
35
+ else:
36
+ print("⚠️ No se detectó GPU, usando CPU")
37
+
38
+ # Configurar para usar mixed precision
39
+ tf.keras.mixed_precision.set_global_policy('mixed_float16')
40
+
41
  # 🔁 Limpiar almacenamiento temporal si existe
42
  def clean_temp_dirs():
43
  print("🧹 Limpiando carpetas temporales...")
 
51
  clean_temp_dirs()
52
 
53
  # 📁 Parámetros
54
+ DATASET_ID = "Segizu/facial-recognition-preview"
55
  EMBEDDINGS_SUBFOLDER = "embeddings"
56
  LOCAL_EMB_DIR = Path("embeddings")
57
  LOCAL_EMB_DIR.mkdir(exist_ok=True)
 
71
  return total / (1024 ** 3)
72
 
73
  def preprocess_image(img: Image.Image) -> np.ndarray:
74
+ # Convertir a RGB si no lo es
75
+ if img.mode != 'RGB':
76
+ img = img.convert('RGB')
77
+
78
+ # Obtener la orientación EXIF si existe
79
+ try:
80
+ exif = img._getexif()
81
+ if exif is not None:
82
+ orientation = exif.get(274) # 274 es el tag de orientación en EXIF
83
+ if orientation is not None:
84
+ # Rotar la imagen según la orientación EXIF
85
+ if orientation == 3:
86
+ img = img.rotate(180, expand=True)
87
+ elif orientation == 6:
88
+ img = img.rotate(270, expand=True)
89
+ elif orientation == 8:
90
+ img = img.rotate(90, expand=True)
91
+ except:
92
+ pass # Si no hay EXIF o hay error, continuamos con la imagen original
93
+
94
+ # Intentar detectar la orientación del rostro
95
+ try:
96
+ # Convertir a array numpy para DeepFace
97
+ img_array = np.array(img)
98
+ # Detectar rostros con GPU
99
+ face_objs = DeepFace.extract_faces(
100
+ img_path=img_array,
101
+ target_size=(160, 160),
102
+ detector_backend='retinaface',
103
+ enforce_detection=False
104
+ )
105
+
106
+ if face_objs and len(face_objs) > 0:
107
+ # Si se detecta un rostro, usar la imagen detectada
108
+ img_array = face_objs[0]['face']
109
+ return img_array
110
+ except:
111
+ pass # Si falla la detección, continuamos con el procesamiento normal
112
+
113
+ # Si no se detectó rostro o falló la detección, redimensionar la imagen original
114
+ img_resized = img.resize((160, 160), Image.Resampling.LANCZOS)
115
  return np.array(img_resized)
116
 
117
  # ✅ Cargar CSV desde el dataset
 
122
  column_names=["image"],
123
  header=0
124
  )
 
125
  def build_database():
126
  print(f"📊 Uso actual de almacenamiento temporal INICIO: {get_folder_size('.'):.2f} GB")
127
  print("🔄 Generando embeddings...")
 
232
 
233
  # 🔍 Buscar similitudes
234
  def find_similar_faces(uploaded_image: Image.Image):
235
+ if uploaded_image is None:
236
+ return [], "⚠ Por favor, sube una imagen primero"
237
+
238
  try:
239
+ print("🔄 Procesando imagen de entrada...")
240
+ # Convertir a RGB si no lo es
241
+ if uploaded_image.mode != 'RGB':
242
+ uploaded_image = uploaded_image.convert('RGB')
243
+
244
+ # Mostrar dimensiones de la imagen
245
+ print(f"📐 Dimensiones de la imagen: {uploaded_image.size}")
246
+
247
  img_processed = preprocess_image(uploaded_image)
248
+ print("✅ Imagen preprocesada correctamente")
249
+
250
+ # Intentar primero con enforce_detection=True
251
+ try:
252
+ query_embedding = DeepFace.represent(
253
+ img_path=img_processed,
254
+ model_name="Facenet",
255
+ enforce_detection=True,
256
+ detector_backend='retinaface'
257
+ )[0]["embedding"]
258
+ print("✅ Rostro detectado con enforce_detection=True")
259
+ except Exception as e:
260
+ print(f"⚠ No se pudo detectar rostro con enforce_detection=True, intentando con False: {str(e)}")
261
+ # Si falla, intentar con enforce_detection=False
262
+ query_embedding = DeepFace.represent(
263
+ img_path=img_processed,
264
+ model_name="Facenet",
265
+ enforce_detection=False,
266
+ detector_backend='retinaface'
267
+ )[0]["embedding"]
268
+ print("✅ Embedding generado con enforce_detection=False")
269
+
270
  del img_processed
271
  gc.collect()
272
+
273
  except Exception as e:
274
+ print(f"❌ Error en procesamiento de imagen: {str(e)}")
275
  return [], f"⚠ Error procesando imagen: {str(e)}"
276
 
277
  similarities = []
278
+ print("🔍 Buscando similitudes en la base de datos...")
279
 
280
  try:
281
  embedding_files = [
282
  f for f in list_repo_files(DATASET_ID, repo_type="dataset", token=HF_TOKEN)
283
+ if f.startswith(f"{EMBEDDINGS_SUBFOLDER}/") and f.endswith(".tar.gz")
284
  ]
285
+ print(f"📁 Encontrados {len(embedding_files)} archivos de embeddings")
286
  except Exception as e:
287
+ print(f"❌ Error obteniendo archivos: {str(e)}")
288
  return [], f"⚠ Error obteniendo archivos: {str(e)}"
289
 
290
+ # Procesar en lotes para mejor rendimiento
291
+ batch_size = 10
292
+ for i in range(0, len(embedding_files), batch_size):
293
+ batch_files = embedding_files[i:i + batch_size]
294
+ print(f"📦 Procesando lote {i//batch_size + 1}/{(len(embedding_files) + batch_size - 1)//batch_size}")
295
+
296
+ for file_path in batch_files:
297
+ try:
298
+ file_bytes = requests.get(
299
+ f"https://huggingface.co/datasets/{DATASET_ID}/resolve/main/{file_path}",
300
+ headers=headers,
301
+ timeout=30
302
+ ).content
303
+
304
+ # Crear un archivo temporal para el tar.gz
305
+ temp_archive = Path("temp_archive.tar.gz")
306
+ with open(temp_archive, "wb") as f:
307
+ f.write(file_bytes)
308
+
309
+ # Extraer el contenido
310
+ with tarfile.open(temp_archive, "r:gz") as tar:
311
+ tar.extractall(path="temp_extract")
312
+
313
+ # Procesar cada archivo .pkl en el tar
314
+ for pkl_file in Path("temp_extract").glob("*.pkl"):
315
+ with open(pkl_file, "rb") as f:
316
+ record = pickle.load(f)
317
+
318
+ name = record["name"]
319
+ img = record["img"]
320
+ emb = record["embedding"]
321
+
322
+ dist = np.linalg.norm(np.array(query_embedding) - np.array(emb))
323
+ sim_score = 1 / (1 + dist)
324
+ similarities.append((sim_score, name, np.array(img)))
325
+
326
+ # Limpiar archivos temporales
327
+ shutil.rmtree("temp_extract")
328
+ temp_archive.unlink()
329
+
330
+ except Exception as e:
331
+ print(f"⚠ Error procesando {file_path}: {e}")
332
+ continue
333
 
334
+ if not similarities:
335
+ return [], "⚠ No se encontraron similitudes en la base de datos"
 
336
 
337
+ print(f"✅ Encontradas {len(similarities)} similitudes")
338
  similarities.sort(reverse=True)
339
  top = similarities[:5]
340
  gallery = [(img, f"{name} - Similitud: {sim:.2f}") for sim, name, img in top]
 
355
  build_btn = gr.Button("⚙️ Construir base de embeddings (usa GPU)")
356
  build_btn.click(fn=build_database, inputs=[], outputs=[])
357
 
358
+ demo.launch(share=True)
359
 
requirements.txt CHANGED
@@ -1,4 +1,4 @@
1
- gradio==4.14.0
2
  numpy
3
  Pillow
4
  opencv-python-headless
@@ -6,7 +6,9 @@ opencv-python-headless
6
  # DeepFace desde GitHub
7
  git+https://github.com/serengil/deepface.git
8
 
9
- # Fixes para RetinaFace
10
- tensorflow==2.12.0
11
  tf-keras
12
- spaces
 
 
 
1
+ gradio==3.50.2
2
  numpy
3
  Pillow
4
  opencv-python-headless
 
6
  # DeepFace desde GitHub
7
  git+https://github.com/serengil/deepface.git
8
 
9
+ # TensorFlow con soporte GPU
10
+ tensorflow-gpu==2.15.0
11
  tf-keras
12
+ spaces
13
+ datasets
14
+ pydantic>=2.0.0,<3.0.0