jarondon82 commited on
Commit
ffc87b0
·
1 Parent(s): 9077361

Corregir visualización de rectángulos de detección facial en tiempo real

Browse files
Files changed (1) hide show
  1. streamlit_app.py +52 -127
streamlit_app.py CHANGED
@@ -2431,7 +2431,7 @@ def main():
2431
  # Componente HTML/JavaScript para acceder a la cámara automáticamente
2432
  camera_html = """
2433
  <div style="margin-bottom: 20px;">
2434
- <video id="webcam" autoplay playsinline width="640" height="480" style="border-radius: 5px;"></video>
2435
  <canvas id="canvas" width="640" height="480" style="display: none;"></canvas>
2436
  <canvas id="display" width="640" height="480" style="border-radius: 5px; display: block; margin: 0 auto;"></canvas>
2437
  </div>
@@ -2474,10 +2474,8 @@ def main():
2474
  // Capturar frame y enviar a Streamlit
2475
  function captureFrame() {
2476
  if (video.readyState === video.HAVE_ENOUGH_DATA) {
2477
- // Dibujar el video en el canvas
2478
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
2479
-
2480
- // Mostrar el video en el canvas de visualización
2481
  displayCtx.drawImage(video, 0, 0, display.width, display.height);
2482
 
2483
  // Convertir a base64
@@ -2493,29 +2491,39 @@ def main():
2493
 
2494
  // Recibir datos de detección de rostros y dibujarlos
2495
  window.addEventListener('message', function(event) {
2496
- const message = event.data;
2497
-
2498
- // Verificar si es un mensaje con cajas de rostros
2499
- if (message && message.type === 'faceBoxes') {
2500
- const boxes = message.boxes;
2501
-
2502
- // Limpiar el canvas y dibujar el frame actual
2503
- displayCtx.drawImage(video, 0, 0, display.width, display.height);
2504
 
2505
- // Dibujar cada caja
2506
- boxes.forEach(box => {
2507
- const [x1, y1, x2, y2, confidence] = box;
 
2508
 
2509
- // Dibujar rectángulo
2510
- displayCtx.strokeStyle = '#00FF00';
2511
- displayCtx.lineWidth = 2;
2512
- displayCtx.strokeRect(x1, y1, x2-x1, y2-y1);
2513
 
2514
- // Dibujar etiqueta
2515
- displayCtx.fillStyle = '#00FF00';
2516
- displayCtx.font = '16px Arial';
2517
- displayCtx.fillText(`Rostro: ${confidence.toFixed(2)}`, x1, y1-5);
2518
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2519
  }
2520
  });
2521
 
@@ -2578,109 +2586,25 @@ def main():
2578
  st.session_state.last_fps_update = current_time
2579
 
2580
  # Enviar las cajas detectadas al componente JavaScript para dibujarlas en tiempo real
2581
- face_boxes_js = f"""
2582
- <script>
2583
- window.parent.postMessage({{
2584
- type: 'faceBoxes',
2585
- boxes: {json.dumps(bboxes.tolist() if isinstance(bboxes, np.ndarray) else bboxes)}
2586
- }}, '*');
2587
- </script>
2588
- """
2589
- st.components.v1.html(face_boxes_js, height=0, width=0)
2590
-
2591
- # Dibujar resultados
2592
- result_img = image.copy()
2593
- for i, bbox in enumerate(bboxes):
2594
- x1, y1, x2, y2, conf = bbox
2595
- cv2.rectangle(result_img, (x1, y1), (x2, y2), (0, 255, 0), 2)
2596
- cv2.putText(result_img, f"Face {i+1}: {conf:.2f}", (x1, y1-10),
2597
- cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
2598
-
2599
- # Mostrar resultado
2600
- with result_container:
2601
- st.image(result_img, channels="BGR", caption="Real-time capture", use_container_width=True)
2602
-
2603
- # Si hay rostros y hay una base de datos, intentar reconocerlos
2604
- if len(bboxes) > 0 and st.session_state.face_database and len(st.session_state.face_database) > 0:
2605
- recognition_results = []
2606
-
2607
- # Usar la configuración local
2608
- local_model = st.session_state.get('continuous_model_choice', 'VGG-Face')
2609
- local_threshold = st.session_state.get('continuous_similarity_threshold', 45.0) / 100.0
2610
 
2611
- for i, bbox in enumerate(bboxes):
2612
- x1, y1, x2, y2, _ = bbox
2613
- face_img = image[y1:y2, x1:x2]
2614
-
2615
- # Extraer el embedding del rostro con el modelo seleccionado
2616
- if local_model == "VGG-Face":
2617
- embedding = vggface_model(face_img)
2618
- elif local_model == "Facenet":
2619
- embedding = facenet_model(face_img)
2620
- elif local_model == "OpenFace":
2621
- embedding = openface_model(face_img)
2622
- elif local_model == "ArcFace":
2623
- embedding = arcface_model(face_img)
2624
- else:
2625
- embedding = vggface_model(face_img)
2626
-
2627
- # Comparar con rostros registrados
2628
- best_match = None
2629
- best_similarity = -1
2630
-
2631
- for name, info in st.session_state.face_database.items():
2632
- if 'embeddings' in info and info['embeddings']:
2633
- # Buscar embedding del mismo modelo
2634
- for emb in info['embeddings']:
2635
- if isinstance(emb, dict) and 'model' in emb and emb['model'] == local_model:
2636
- stored_emb = emb['embedding']
2637
- similarity = cosine_similarity(embedding, stored_emb)
2638
-
2639
- if similarity > local_threshold and similarity > best_similarity:
2640
- best_similarity = similarity
2641
- best_match = name
2642
- elif not isinstance(emb, dict) and 'models' in info and local_model in info['models']:
2643
- # Compatibilidad con formato anterior
2644
- model_idx = info['models'].index(local_model)
2645
- if model_idx < len(info['embeddings']):
2646
- stored_emb = info['embeddings'][model_idx]
2647
- similarity = cosine_similarity(embedding, stored_emb)
2648
-
2649
- if similarity > local_threshold and similarity > best_similarity:
2650
- best_similarity = similarity
2651
- best_match = name
2652
-
2653
- if best_match is not None:
2654
- recognition_results.append({
2655
- 'bbox': bbox,
2656
- 'name': best_match,
2657
- 'similarity': best_similarity
2658
- })
2659
-
2660
- # Mostrar resultados de reconocimiento
2661
- if recognition_results:
2662
- result_with_names = result_img.copy()
2663
-
2664
- for result in recognition_results:
2665
- x1, y1, x2, y2, _ = result['bbox']
2666
- name = result['name']
2667
- similarity = result['similarity']
2668
-
2669
- # Dibujar nombre y similitud
2670
- cv2.rectangle(result_with_names, (x1, y1), (x2, y2), (0, 255, 0), 2)
2671
- label = f"{name}: {similarity:.2f}"
2672
- cv2.putText(result_with_names, label, (x1, y1-10),
2673
- cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
2674
-
2675
- with result_container:
2676
- st.image(result_with_names, channels="BGR", caption="Recognized faces", use_container_width=True)
2677
-
2678
- # Mostrar tabla de resultados
2679
- results_df = pd.DataFrame([
2680
- {"Name": r['name'], "Confidence": f"{r['similarity']:.2f}"}
2681
- for r in recognition_results
2682
- ])
2683
- st.table(results_df)
2684
  except Exception as e:
2685
  st.error(f"Error processing camera frame: {str(e)}")
2686
  st.info("Camera continues to run. Processing will be attempted on next frame.")
@@ -2800,7 +2724,8 @@ def main():
2800
  cv2.putText(result_with_names, label, (x1, y1-10),
2801
  cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
2802
 
2803
- st.image(result_with_names, channels="BGR", caption="Recognized faces", use_container_width=True)
 
2804
 
2805
  # Mostrar tabla de resultados
2806
  results_df = pd.DataFrame([
 
2431
  # Componente HTML/JavaScript para acceder a la cámara automáticamente
2432
  camera_html = """
2433
  <div style="margin-bottom: 20px;">
2434
+ <video id="webcam" autoplay playsinline width="640" height="480" style="border-radius: 5px; display: none;"></video>
2435
  <canvas id="canvas" width="640" height="480" style="display: none;"></canvas>
2436
  <canvas id="display" width="640" height="480" style="border-radius: 5px; display: block; margin: 0 auto;"></canvas>
2437
  </div>
 
2474
  // Capturar frame y enviar a Streamlit
2475
  function captureFrame() {
2476
  if (video.readyState === video.HAVE_ENOUGH_DATA) {
2477
+ // Dibujar el video en ambos canvas
2478
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
 
 
2479
  displayCtx.drawImage(video, 0, 0, display.width, display.height);
2480
 
2481
  // Convertir a base64
 
2491
 
2492
  // Recibir datos de detección de rostros y dibujarlos
2493
  window.addEventListener('message', function(event) {
2494
+ try {
2495
+ const message = event.data;
 
 
 
 
 
 
2496
 
2497
+ // Verificar si es un mensaje con cajas de rostros
2498
+ if (message && message.type === 'faceBoxes') {
2499
+ console.log('Recibido datos de cajas:', message.boxes);
2500
+ const boxes = message.boxes;
2501
 
2502
+ // Limpiar el canvas y dibujar el frame actual
2503
+ displayCtx.drawImage(video, 0, 0, display.width, display.height);
 
 
2504
 
2505
+ // Dibujar cada caja
2506
+ if (boxes && boxes.length > 0) {
2507
+ boxes.forEach(box => {
2508
+ if (box && box.length >= 5) {
2509
+ const [x1, y1, x2, y2, confidence] = box;
2510
+ console.log(`Dibujando caja: (${x1}, ${y1}, ${x2}, ${y2}, ${confidence})`);
2511
+
2512
+ // Dibujar rectángulo
2513
+ displayCtx.strokeStyle = '#00FF00';
2514
+ displayCtx.lineWidth = 3;
2515
+ displayCtx.strokeRect(x1, y1, x2-x1, y2-y1);
2516
+
2517
+ // Dibujar etiqueta
2518
+ displayCtx.fillStyle = '#00FF00';
2519
+ displayCtx.font = '16px Arial';
2520
+ displayCtx.fillText(`Rostro: ${confidence.toFixed(2)}`, x1, y1-5);
2521
+ }
2522
+ });
2523
+ }
2524
+ }
2525
+ } catch (error) {
2526
+ console.error('Error al procesar mensaje:', error);
2527
  }
2528
  });
2529
 
 
2586
  st.session_state.last_fps_update = current_time
2587
 
2588
  # Enviar las cajas detectadas al componente JavaScript para dibujarlas en tiempo real
2589
+ if bboxes is not None and len(bboxes) > 0:
2590
+ # Convertir a lista si es un array numpy
2591
+ bbox_list = bboxes.tolist() if isinstance(bboxes, np.ndarray) else bboxes
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2592
 
2593
+ # Crear script para enviar datos al componente JavaScript
2594
+ face_boxes_js = f"""
2595
+ <script>
2596
+ (function() {{
2597
+ console.log('Enviando cajas al componente: {bbox_list}');
2598
+ // Usar postMessage para comunicarse con el componente
2599
+ window.postMessage({{
2600
+ type: 'faceBoxes',
2601
+ boxes: {json.dumps(bbox_list)}
2602
+ }}, '*');
2603
+ }})();
2604
+ </script>
2605
+ """
2606
+ # Renderizar el script
2607
+ st.components.v1.html(face_boxes_js, height=0, width=0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2608
  except Exception as e:
2609
  st.error(f"Error processing camera frame: {str(e)}")
2610
  st.info("Camera continues to run. Processing will be attempted on next frame.")
 
2724
  cv2.putText(result_with_names, label, (x1, y1-10),
2725
  cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
2726
 
2727
+ with result_container:
2728
+ st.image(result_with_names, channels="BGR", caption="Real-time capture", use_container_width=True)
2729
 
2730
  # Mostrar tabla de resultados
2731
  results_df = pd.DataFrame([