Spaces:
Build error
Build error
Commit
·
4ec605a
1
Parent(s):
dacb695
Solucionar problemas de detección facial: usar umbral más bajo, añadir detección por Haar como respaldo, mejorar diagnóstico visual
Browse files- streamlit_app.py +44 -24
streamlit_app.py
CHANGED
|
@@ -127,8 +127,11 @@ def main():
|
|
| 127 |
Lista de bounding boxes con formato [x1, y1, x2, y2, confidence]
|
| 128 |
o None si no se detectan rostros
|
| 129 |
"""
|
|
|
|
|
|
|
|
|
|
| 130 |
# Añadir impresión de depuración para el umbral usado
|
| 131 |
-
print(f"Detecting faces with
|
| 132 |
|
| 133 |
# Obtener dimensiones de la imagen
|
| 134 |
h, w = frame.shape[:2]
|
|
@@ -150,7 +153,9 @@ def main():
|
|
| 150 |
print(f"Error al procesar la imagen con el modelo DNN: {str(e)}")
|
| 151 |
# En caso de error, devolver lista vacía
|
| 152 |
print("Error en la detección de rostros. No se pudo procesar la imagen.")
|
| 153 |
-
|
|
|
|
|
|
|
| 154 |
|
| 155 |
# Variable para almacenar las cajas delimitadoras
|
| 156 |
bboxes = []
|
|
@@ -161,8 +166,8 @@ def main():
|
|
| 161 |
# Extraer la confianza (probabilidad) de la detección
|
| 162 |
confidence = detections[0, 0, i, 2]
|
| 163 |
|
| 164 |
-
# Filtrar detecciones débiles por confianza
|
| 165 |
-
if confidence >
|
| 166 |
detection_count += 1
|
| 167 |
# La red da las coordenadas de la caja normalizadas entre 0 y 1
|
| 168 |
# Multiplicamos por ancho y alto para obtener coordenadas en píxeles
|
|
@@ -188,17 +193,21 @@ def main():
|
|
| 188 |
bboxes.append([x1, y1, x2, y2, confidence])
|
| 189 |
|
| 190 |
# Dar feedback sobre el número de detecciones
|
| 191 |
-
print(f"Total de detecciones con confianza > {
|
| 192 |
print(f"Total de cajas válidas: {len(bboxes)}")
|
| 193 |
|
| 194 |
-
# Si no se encontraron rostros,
|
| 195 |
if not bboxes:
|
| 196 |
-
print(f"No se detectaron rostros con confianza > {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
print("Sugerencias para mejorar la detección:")
|
| 198 |
print("1. Ajustar la iluminación - evitar contraluces")
|
| 199 |
-
print("2.
|
| 200 |
-
print("3.
|
| 201 |
-
print("4. Verificar que la cámara esté enfocada")
|
| 202 |
|
| 203 |
# Verificar si hay detecciones con umbral más bajo para depuración
|
| 204 |
for i in range(detections.shape[2]):
|
|
@@ -2608,9 +2617,6 @@ def main():
|
|
| 2608 |
// Dibujar cajas almacenadas (para mantener las cajas entre frames)
|
| 2609 |
drawStoredBoxes();
|
| 2610 |
|
| 2611 |
-
// Dibujar un rectángulo de prueba en cada captura
|
| 2612 |
-
drawTestRect();
|
| 2613 |
-
|
| 2614 |
// Convertir a base64
|
| 2615 |
const imageData = canvas.toDataURL('image/jpeg', 0.8);
|
| 2616 |
|
|
@@ -2689,6 +2695,14 @@ def main():
|
|
| 2689 |
// Dibujar cada caja
|
| 2690 |
if (boxes.length > 0) {
|
| 2691 |
console.log(`Dibujando ${boxes.length} cajas de rostros`);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2692 |
boxes.forEach(box => {
|
| 2693 |
if (box && box.length >= 5) {
|
| 2694 |
const [x1, y1, x2, y2, confidence] = box;
|
|
@@ -2705,30 +2719,36 @@ def main():
|
|
| 2705 |
|
| 2706 |
// Añadir un fondo para el texto
|
| 2707 |
displayCtx.fillStyle = 'rgba(0, 0, 0, 0.7)';
|
| 2708 |
-
displayCtx.fillRect(x1, y1-25,
|
| 2709 |
|
| 2710 |
// Dibujar etiqueta con fuente más grande
|
| 2711 |
displayCtx.fillStyle = '#FFFF00'; // Amarillo brillante
|
| 2712 |
displayCtx.font = 'bold 18px Arial';
|
| 2713 |
-
displayCtx.fillText(`
|
| 2714 |
} else {
|
| 2715 |
console.warn('Formato de caja inválido:', box);
|
| 2716 |
}
|
| 2717 |
});
|
| 2718 |
-
|
| 2719 |
-
// Añadir indicador de cantidad de rostros detectados
|
| 2720 |
-
displayCtx.fillStyle = 'rgba(0, 0, 0, 0.7)';
|
| 2721 |
-
displayCtx.fillRect(10, 10, 200, 30);
|
| 2722 |
-
displayCtx.fillStyle = '#FFFFFF';
|
| 2723 |
-
displayCtx.font = 'bold 18px Arial';
|
| 2724 |
-
displayCtx.fillText(`Rostros: ${boxes.length}`, 20, 30);
|
| 2725 |
} else {
|
| 2726 |
// Mensaje cuando no se detectan rostros
|
| 2727 |
displayCtx.fillStyle = 'rgba(0, 0, 0, 0.7)';
|
| 2728 |
-
displayCtx.fillRect(10, 10,
|
| 2729 |
displayCtx.fillStyle = '#FF9900';
|
| 2730 |
displayCtx.font = 'bold 18px Arial';
|
| 2731 |
-
displayCtx.fillText('No se detectan rostros', 20, 30);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2732 |
console.log('No hay cajas para dibujar o formato inválido');
|
| 2733 |
|
| 2734 |
// Limpiar cajas almacenadas si se recibe explícitamente un array vacío
|
|
|
|
| 127 |
Lista de bounding boxes con formato [x1, y1, x2, y2, confidence]
|
| 128 |
o None si no se detectan rostros
|
| 129 |
"""
|
| 130 |
+
# Forzar un umbral muy bajo para aumentar la sensibilidad
|
| 131 |
+
internal_threshold = 0.1 # Usar este umbral internamente para mayor sensibilidad
|
| 132 |
+
|
| 133 |
# Añadir impresión de depuración para el umbral usado
|
| 134 |
+
print(f"Detecting faces with original threshold: {conf_threshold}, using internal threshold: {internal_threshold}")
|
| 135 |
|
| 136 |
# Obtener dimensiones de la imagen
|
| 137 |
h, w = frame.shape[:2]
|
|
|
|
| 153 |
print(f"Error al procesar la imagen con el modelo DNN: {str(e)}")
|
| 154 |
# En caso de error, devolver lista vacía
|
| 155 |
print("Error en la detección de rostros. No se pudo procesar la imagen.")
|
| 156 |
+
# Intentar con Haar cascade como respaldo
|
| 157 |
+
print("Intentando detección con Haar cascade como respaldo...")
|
| 158 |
+
return detect_face_haar(frame, conf_threshold)
|
| 159 |
|
| 160 |
# Variable para almacenar las cajas delimitadoras
|
| 161 |
bboxes = []
|
|
|
|
| 166 |
# Extraer la confianza (probabilidad) de la detección
|
| 167 |
confidence = detections[0, 0, i, 2]
|
| 168 |
|
| 169 |
+
# Filtrar detecciones débiles por confianza (usando el umbral interno más bajo)
|
| 170 |
+
if confidence > internal_threshold:
|
| 171 |
detection_count += 1
|
| 172 |
# La red da las coordenadas de la caja normalizadas entre 0 y 1
|
| 173 |
# Multiplicamos por ancho y alto para obtener coordenadas en píxeles
|
|
|
|
| 193 |
bboxes.append([x1, y1, x2, y2, confidence])
|
| 194 |
|
| 195 |
# Dar feedback sobre el número de detecciones
|
| 196 |
+
print(f"Total de detecciones con confianza > {internal_threshold}: {detection_count}")
|
| 197 |
print(f"Total de cajas válidas: {len(bboxes)}")
|
| 198 |
|
| 199 |
+
# Si no se encontraron rostros, intentar con Haar cascade
|
| 200 |
if not bboxes:
|
| 201 |
+
print(f"No se detectaron rostros con confianza > {internal_threshold}")
|
| 202 |
+
print("Intentando detección con Haar cascade como respaldo...")
|
| 203 |
+
haar_bboxes = detect_face_haar(frame, conf_threshold)
|
| 204 |
+
if haar_bboxes and len(haar_bboxes) > 0:
|
| 205 |
+
print(f"Haar cascade encontró {len(haar_bboxes)} rostro(s)")
|
| 206 |
+
return haar_bboxes
|
| 207 |
print("Sugerencias para mejorar la detección:")
|
| 208 |
print("1. Ajustar la iluminación - evitar contraluces")
|
| 209 |
+
print("2. Mirar directamente a la cámara")
|
| 210 |
+
print("3. Verificar que la cámara esté enfocada")
|
|
|
|
| 211 |
|
| 212 |
# Verificar si hay detecciones con umbral más bajo para depuración
|
| 213 |
for i in range(detections.shape[2]):
|
|
|
|
| 2617 |
// Dibujar cajas almacenadas (para mantener las cajas entre frames)
|
| 2618 |
drawStoredBoxes();
|
| 2619 |
|
|
|
|
|
|
|
|
|
|
| 2620 |
// Convertir a base64
|
| 2621 |
const imageData = canvas.toDataURL('image/jpeg', 0.8);
|
| 2622 |
|
|
|
|
| 2695 |
// Dibujar cada caja
|
| 2696 |
if (boxes.length > 0) {
|
| 2697 |
console.log(`Dibujando ${boxes.length} cajas de rostros`);
|
| 2698 |
+
|
| 2699 |
+
// Añadir texto grande para diagnóstico
|
| 2700 |
+
displayCtx.fillStyle = 'rgba(0, 0, 0, 0.7)';
|
| 2701 |
+
displayCtx.fillRect(10, 50, 300, 40);
|
| 2702 |
+
displayCtx.fillStyle = '#00FF00';
|
| 2703 |
+
displayCtx.font = 'bold 20px Arial';
|
| 2704 |
+
displayCtx.fillText(`DETECTADAS: ${boxes.length} CAJAS`, 20, 80);
|
| 2705 |
+
|
| 2706 |
boxes.forEach(box => {
|
| 2707 |
if (box && box.length >= 5) {
|
| 2708 |
const [x1, y1, x2, y2, confidence] = box;
|
|
|
|
| 2719 |
|
| 2720 |
// Añadir un fondo para el texto
|
| 2721 |
displayCtx.fillStyle = 'rgba(0, 0, 0, 0.7)';
|
| 2722 |
+
displayCtx.fillRect(x1, y1-25, 160, 25);
|
| 2723 |
|
| 2724 |
// Dibujar etiqueta con fuente más grande
|
| 2725 |
displayCtx.fillStyle = '#FFFF00'; // Amarillo brillante
|
| 2726 |
displayCtx.font = 'bold 18px Arial';
|
| 2727 |
+
displayCtx.fillText(`ROSTRO: ${confidence.toFixed(2)}`, x1+5, y1-5);
|
| 2728 |
} else {
|
| 2729 |
console.warn('Formato de caja inválido:', box);
|
| 2730 |
}
|
| 2731 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2732 |
} else {
|
| 2733 |
// Mensaje cuando no se detectan rostros
|
| 2734 |
displayCtx.fillStyle = 'rgba(0, 0, 0, 0.7)';
|
| 2735 |
+
displayCtx.fillRect(10, 10, 350, 30);
|
| 2736 |
displayCtx.fillStyle = '#FF9900';
|
| 2737 |
displayCtx.font = 'bold 18px Arial';
|
| 2738 |
+
displayCtx.fillText('No se detectan rostros (Usa conf. < 0.2)', 20, 30);
|
| 2739 |
+
|
| 2740 |
+
// Añadir texto de diagnóstico adicional
|
| 2741 |
+
displayCtx.fillStyle = 'rgba(0, 0, 0, 0.7)';
|
| 2742 |
+
displayCtx.fillRect(10, 50, 400, 90);
|
| 2743 |
+
displayCtx.fillStyle = '#FF9900';
|
| 2744 |
+
displayCtx.font = 'bold 16px Arial';
|
| 2745 |
+
displayCtx.fillText('DIAGNÓSTICO:', 20, 70);
|
| 2746 |
+
displayCtx.fillStyle = '#FFFFFF';
|
| 2747 |
+
displayCtx.font = '14px Arial';
|
| 2748 |
+
displayCtx.fillText('1. Reduce el umbral de confianza a 0.1-0.2', 20, 90);
|
| 2749 |
+
displayCtx.fillText('2. Mejora la iluminación (luz frontal)', 20, 110);
|
| 2750 |
+
displayCtx.fillText('3. Mira directo a la cámara', 20, 130);
|
| 2751 |
+
|
| 2752 |
console.log('No hay cajas para dibujar o formato inválido');
|
| 2753 |
|
| 2754 |
// Limpiar cajas almacenadas si se recibe explícitamente un array vacío
|