jarondon82 commited on
Commit
39e4dcc
·
1 Parent(s): 4fbede6

Añadir modo de captura continua para reconocimiento facial en Hugging Face Spaces

Browse files
Files changed (1) hide show
  1. streamlit_app.py +159 -0
streamlit_app.py CHANGED
@@ -2353,6 +2353,165 @@ def main():
2353
  3. If it still doesn't work, use the alternative options shown below
2354
  """)
2355
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2356
  # Añadir opción de cámara alternativa para entornos donde WebRTC no funciona bien
2357
  st.markdown("---")
2358
  st.markdown("### Alternative Camera Mode")
 
2353
  3. If it still doesn't work, use the alternative options shown below
2354
  """)
2355
 
2356
+ # Añadir modo de captura continua (funciona mejor en Hugging Face)
2357
+ st.markdown("---")
2358
+ st.markdown("### Continuous Capture Mode")
2359
+ st.info("⚠️ Recommended mode for Hugging Face: Captures frames continuously with reliable camera access.")
2360
+
2361
+ col1, col2 = st.columns(2)
2362
+ start_continuous = col1.button("Start Continuous Capture", key="start_continuous_button", use_container_width=True)
2363
+ stop_continuous = col2.button("Stop Continuous Capture", key="stop_continuous_button", use_container_width=True)
2364
+
2365
+ if start_continuous:
2366
+ st.session_state.continuous_capture = True
2367
+ st.session_state.frame_count = 0
2368
+ st.session_state.frames_processed = 0
2369
+ st.session_state.start_time = time.time()
2370
+ st.session_state.last_fps_update = time.time()
2371
+ # Desactivar otros modos
2372
+ st.session_state.demo_running = False
2373
+ st.session_state.upload_mode = False
2374
+ st.session_state.simple_camera = False
2375
+
2376
+ if stop_continuous:
2377
+ st.session_state.continuous_capture = False
2378
+
2379
+ if st.session_state.get('continuous_capture', False):
2380
+ # Área para mostrar resultados
2381
+ result_container = st.container()
2382
+ camera_container = st.container()
2383
+
2384
+ # Configurar métricas
2385
+ faces_metric.metric("Faces detected", 0)
2386
+ fps_metric.metric("FPS", "Processing...")
2387
+ time_metric.metric("Status", "Running")
2388
+
2389
+ # Capturar imagen y procesarla
2390
+ with camera_container:
2391
+ st.info("Continuous capture mode active. Processing frames automatically.")
2392
+
2393
+ # Incrementar contador de frames para forzar una nueva captura en cada ciclo
2394
+ frame_key = f"continuous_frame_{st.session_state.get('frame_count', 0)}"
2395
+ captured_image = st.camera_input("Camera feed", key=frame_key)
2396
+
2397
+ if captured_image is not None:
2398
+ try:
2399
+ # Procesar la imagen
2400
+ image_bytes = captured_image.getvalue()
2401
+ image = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), cv2.IMREAD_COLOR)
2402
+
2403
+ if image is not None and image.size > 0:
2404
+ # Detectar rostros
2405
+ bboxes = detect_face_dnn(face_net, image, confidence_threshold)
2406
+
2407
+ # Actualizar métricas
2408
+ faces_metric.metric("Faces detected", len(bboxes))
2409
+
2410
+ # Incrementar contador de frames procesados
2411
+ st.session_state.frames_processed += 1
2412
+
2413
+ # Calcular FPS real (actualizar cada segundo)
2414
+ current_time = time.time()
2415
+ elapsed = current_time - st.session_state.start_time
2416
+
2417
+ if current_time - st.session_state.last_fps_update >= 1.0:
2418
+ fps = st.session_state.frames_processed / elapsed
2419
+ fps_metric.metric("FPS", f"{fps:.1f}")
2420
+ st.session_state.last_fps_update = current_time
2421
+
2422
+ # Dibujar resultados
2423
+ result_img = image.copy()
2424
+ for i, bbox in enumerate(bboxes):
2425
+ x1, y1, x2, y2, conf = bbox
2426
+ cv2.rectangle(result_img, (x1, y1), (x2, y2), (0, 255, 0), 2)
2427
+ cv2.putText(result_img, f"Face {i+1}: {conf:.2f}", (x1, y1-10),
2428
+ cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
2429
+
2430
+ # Mostrar resultado
2431
+ with result_container:
2432
+ st.image(result_img, channels="BGR", caption=f"Frame {st.session_state.frames_processed}", use_container_width=True)
2433
+
2434
+ # Si hay rostros y hay una base de datos, intentar reconocerlos
2435
+ if len(bboxes) > 0 and st.session_state.face_database and len(st.session_state.face_database) > 0:
2436
+ recognition_results = []
2437
+
2438
+ for i, bbox in enumerate(bboxes):
2439
+ x1, y1, x2, y2, _ = bbox
2440
+ face_img = image[y1:y2, x1:x2]
2441
+
2442
+ # Extraer el embedding del rostro con el modelo seleccionado
2443
+ if model_choice == "VGG-Face":
2444
+ embedding = vggface_model(face_img)
2445
+ elif model_choice == "Facenet":
2446
+ embedding = facenet_model(face_img)
2447
+ elif model_choice == "OpenFace":
2448
+ embedding = openface_model(face_img)
2449
+ elif model_choice == "ArcFace":
2450
+ embedding = arcface_model(face_img)
2451
+ else:
2452
+ embedding = vggface_model(face_img)
2453
+
2454
+ # Comparar con rostros registrados
2455
+ best_match = None
2456
+ best_similarity = -1
2457
+
2458
+ for name, info in st.session_state.face_database.items():
2459
+ if 'embeddings' in info and info['embeddings']:
2460
+ # Buscar embedding del mismo modelo
2461
+ for emb in info['embeddings']:
2462
+ if isinstance(emb, dict) and 'model' in emb and emb['model'] == model_choice:
2463
+ stored_emb = emb['embedding']
2464
+ similarity = cosine_similarity(embedding, stored_emb)
2465
+
2466
+ if similarity > similarity_threshold/100 and similarity > best_similarity:
2467
+ best_similarity = similarity
2468
+ best_match = name
2469
+
2470
+ if best_match is not None:
2471
+ recognition_results.append({
2472
+ 'bbox': bbox,
2473
+ 'name': best_match,
2474
+ 'similarity': best_similarity
2475
+ })
2476
+
2477
+ # Mostrar resultados de reconocimiento
2478
+ if recognition_results:
2479
+ result_with_names = result_img.copy()
2480
+
2481
+ for result in recognition_results:
2482
+ x1, y1, x2, y2, _ = result['bbox']
2483
+ name = result['name']
2484
+ similarity = result['similarity']
2485
+
2486
+ # Dibujar nombre y similitud
2487
+ cv2.rectangle(result_with_names, (x1, y1), (x2, y2), (0, 255, 0), 2)
2488
+ label = f"{name}: {similarity:.2f}"
2489
+ cv2.putText(result_with_names, label, (x1, y1-10),
2490
+ cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
2491
+
2492
+ with result_container:
2493
+ st.image(result_with_names, channels="BGR", caption="Recognized faces", use_container_width=True)
2494
+
2495
+ # Mostrar tabla de resultados
2496
+ results_df = pd.DataFrame([
2497
+ {"Name": r['name'], "Confidence": f"{r['similarity']:.2f}"}
2498
+ for r in recognition_results
2499
+ ])
2500
+ st.table(results_df)
2501
+
2502
+ # Incrementar contador para siguiente frame
2503
+ st.session_state.frame_count += 1
2504
+
2505
+ # Recargar para capturar siguiente frame (si todavía está activo)
2506
+ if st.session_state.get('continuous_capture', False):
2507
+ time.sleep(0.1) # Pequeña pausa para evitar sobrecarga
2508
+ st.experimental_rerun()
2509
+ else:
2510
+ st.error("Could not process the image. Try taking another photo.")
2511
+ except Exception as e:
2512
+ st.error(f"Error processing image: {str(e)}")
2513
+ st.info("Try again or use another camera mode.")
2514
+
2515
  # Añadir opción de cámara alternativa para entornos donde WebRTC no funciona bien
2516
  st.markdown("---")
2517
  st.markdown("### Alternative Camera Mode")