jarondon82's picture
Mejorado diagnóstico con pruebas adicionales y cara realista
ca08464
raw
history blame
14.4 kB
# Simple app.py for Face Detection
import os
import streamlit as st
import cv2
import numpy as np
from PIL import Image
import io
import base64
import logging
# Configurar logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Comprobar y descargar modelos necesarios
try:
# Verificar si los archivos de modelo existen
model_files = [
"deploy.prototxt.txt",
"res10_300x300_ssd_iter_140000.caffemodel"
]
missing_files = [f for f in model_files if not os.path.exists(f)]
if missing_files:
st.warning("Faltan archivos de modelo. Descargando...")
import download_models
download_models.main()
st.success("¡Archivos de modelo descargados correctamente!")
except Exception as e:
st.error(f"Error al comprobar/descargar modelos: {e}")
# Modo diagnóstico
if 'modo_diagnostico' not in st.session_state:
st.session_state.modo_diagnostico = False
# Función para el modo de diagnóstico
def modo_diagnostico():
st.title("Diagnóstico de Detección Facial")
st.write("Esta herramienta ayuda a identificar problemas con la detección de rostros.")
# Verificar modelos
st.subheader("1. Verificación de archivos de modelo")
for archivo in model_files:
if os.path.exists(archivo):
st.success(f"✅ Modelo encontrado: {archivo}")
st.write(f"Tamaño: {os.path.getsize(archivo)} bytes")
else:
st.error(f"❌ Modelo NO encontrado: {archivo}")
# Probar carga del modelo
st.subheader("2. Prueba de carga del modelo")
try:
modelFile = "res10_300x300_ssd_iter_140000.caffemodel"
configFile = "deploy.prototxt.txt"
# Cargar modelos
st.write("Intentando cargar el modelo DNN...")
try:
net = cv2.dnn.readNetFromCaffe(configFile, modelFile)
st.success(f"✅ Modelo DNN cargado correctamente: {type(net)}")
st.write(f"Información del modelo: {str(net)}")
except Exception as e:
st.error(f"❌ Error al cargar el modelo DNN: {e}")
st.warning("Intentando cargar cascadas Haar como alternativa...")
# Cargar cascadas Haar como alternativa
st.write("Cargando modelos de cascada Haar...")
try:
# Obtener la ruta a los archivos de cascada
haar_face_path = cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
st.write(f"Ruta a Haar Cascade: {haar_face_path}")
haar_face = cv2.CascadeClassifier(haar_face_path)
if haar_face.empty():
st.error("❌ El clasificador de Haar no se cargó correctamente")
else:
st.success("✅ Cascada Haar para rostros cargada correctamente")
except Exception as e:
st.error(f"❌ Error al cargar cascadas Haar: {e}")
# Crear imagen de prueba
st.subheader("3. Probar detección con imagen sintética")
# Crear una imagen de prueba con un óvalo como rostro
example_image = np.zeros((400, 400, 3), dtype=np.uint8)
# Dibujar un óvalo que simule un rostro
cv2.ellipse(example_image, (200, 200), (100, 140), 0, 0, 360, (200, 200, 200), -1)
# Dibujar ojos
cv2.circle(example_image, (150, 150), 15, (255, 255, 255), -1)
cv2.circle(example_image, (250, 150), 15, (255, 255, 255), -1)
# Dibujar boca
cv2.ellipse(example_image, (200, 250), (50, 20), 0, 0, 360, (150, 150, 150), -1)
# Mostrar imagen de prueba
st.image(example_image, caption="Imagen de prueba", channels="BGR")
# Detectar rostros con DNN
st.subheader("4. Prueba de detección con DNN")
umbral = st.slider("Umbral de confianza DNN", 0.1, 0.9, 0.3, 0.1)
try:
# Detectar rostros en la imagen de prueba con DNN
h, w = example_image.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(example_image, (300, 300)), 1.0,
(300, 300), (104.0, 177.0, 123.0))
net.setInput(blob)
detections = net.forward()
# Procesar detecciones
bboxes = []
frame_h, frame_w = example_image.shape[:2]
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > umbral:
box = detections[0, 0, i, 3:7] * np.array([frame_w, frame_h, frame_w, frame_h])
x1, y1, x2, y2 = box.astype("int")
# Asegurar coordenadas válidas
x1 = max(0, min(x1, frame_w - 1))
y1 = max(0, min(y1, frame_h - 1))
x2 = max(0, min(x2, frame_w - 1))
y2 = max(0, min(y2, frame_h - 1))
# Verificar validez de la caja
width, height = x2 - x1, y2 - y1
if width <= 0 or height <= 0:
continue
bboxes.append([x1, y1, x2, y2, confidence])
# Dibujar resultados
result_image = example_image.copy()
for bbox in bboxes:
x1, y1, x2, y2, confidence = bbox
# Dibujar rectángulo verde grueso
cv2.rectangle(result_image, (x1, y1), (x2, y2), (0, 255, 0), 3)
# Añadir texto con confianza
cv2.putText(result_image, f"{confidence:.2f}", (x1, y1-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
st.image(result_image, caption=f"Resultado con DNN (umbral {umbral})", channels="BGR")
# Mostrar estadísticas
st.write(f"Detecciones encontradas con DNN: {len(bboxes)}")
if len(bboxes) > 0:
st.success("✅ La detección DNN funciona correctamente")
else:
st.error("❌ No se detectaron rostros con DNN")
# Mostrar valores de confianza
st.write("Valores de confianza detectados:")
confianzas = []
for i in range(min(10, detections.shape[2])):
confianza = detections[0, 0, i, 2]
confianzas.append(confianza)
st.write(confianzas)
except Exception as e:
st.error(f"Error en detección DNN: {e}")
# Prueba con Haar Cascade
st.subheader("5. Prueba de detección con Haar (alternativa)")
try:
# Convertir a escala de grises
gray = cv2.cvtColor(example_image, cv2.COLOR_BGR2GRAY)
# Detectar rostros
faces = haar_face.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE
)
# Dibujar resultados
haar_result = example_image.copy()
for (x, y, w, h) in faces:
cv2.rectangle(haar_result, (x, y), (x+w, y+h), (0, 255, 0), 3)
st.image(haar_result, caption="Resultado con Haar Cascade", channels="BGR")
st.write(f"Rostros detectados con Haar: {len(faces)}")
if len(faces) > 0:
st.success("✅ La detección con Haar funciona correctamente")
else:
st.error("❌ No se detectaron rostros con Haar")
except Exception as e:
st.error(f"Error en detección Haar: {e}")
# Probar con imagen real
st.subheader("6. Prueba con imagen de rostro real")
# Crear una imagen realista de prueba
real_face = np.ones((400, 400, 3), dtype=np.uint8) * 200 # Fondo gris claro
# Dibujar un rostro más realista (óvalo de color piel)
cv2.ellipse(real_face, (200, 200), (120, 170), 0, 0, 360, (50, 140, 220), -1) # BGR
# Dibujar ojos (elipses con iris y pupilas)
# Ojo izquierdo
cv2.ellipse(real_face, (150, 150), (25, 15), 0, 0, 360, (255, 255, 255), -1) # Blanco del ojo
cv2.circle(real_face, (150, 150), 10, (80, 120, 180), -1) # Iris
cv2.circle(real_face, (150, 150), 5, (20, 20, 20), -1) # Pupila
# Ojo derecho
cv2.ellipse(real_face, (250, 150), (25, 15), 0, 0, 360, (255, 255, 255), -1) # Blanco del ojo
cv2.circle(real_face, (250, 150), 10, (80, 120, 180), -1) # Iris
cv2.circle(real_face, (250, 150), 5, (20, 20, 20), -1) # Pupila
# Dibujar nariz
nose_points = np.array([[200, 180], [180, 220], [220, 220]], np.int32)
nose_points = nose_points.reshape((-1, 1, 2))
cv2.fillPoly(real_face, [nose_points], (40, 120, 200))
# Dibujar boca (sonrisa)
cv2.ellipse(real_face, (200, 260), (60, 25), 0, 0, 180, (40, 80, 200), -1)
# Mostrar imagen
st.image(real_face, caption="Imagen realista de prueba", channels="BGR")
# Detectar rostros con DNN en la imagen realista
try:
h, w = real_face.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(real_face, (300, 300)), 1.0,
(300, 300), (104.0, 177.0, 123.0))
net.setInput(blob)
detections = net.forward()
bboxes = []
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > umbral:
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
x1, y1, x2, y2 = box.astype("int")
# Asegurar coordenadas válidas
x1 = max(0, min(x1, w - 1))
y1 = max(0, min(y1, h - 1))
x2 = max(0, min(x2, w - 1))
y2 = max(0, min(y2, h - 1))
# Verificar validez de la caja
width, height = x2 - x1, y2 - y1
if width <= 0 or height <= 0:
continue
bboxes.append([x1, y1, x2, y2, confidence])
# Dibujar resultados
real_result = real_face.copy()
for bbox in bboxes:
x1, y1, x2, y2, confidence = bbox
# Dibujar rectángulo verde grueso
cv2.rectangle(real_result, (x1, y1), (x2, y2), (0, 255, 0), 3)
# Añadir texto con confianza
cv2.putText(real_result, f"{confidence:.2f}", (x1, y1-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)
st.image(real_result, caption=f"Imagen realista con DNN (umbral {umbral})", channels="BGR")
st.write(f"Detecciones en imagen realista: {len(bboxes)}")
if len(bboxes) > 0:
st.success("✅ La detección en imagen realista funciona correctamente")
else:
st.error("❌ No se detectaron rostros en la imagen realista")
except Exception as e:
st.error(f"Error en detección de imagen realista: {e}")
# Diagnóstico final
st.subheader("Diagnóstico y recomendaciones")
if len(bboxes) == 0:
st.write("""
### Posibles problemas:
1. **El modelo no se está cargando correctamente.**
- Verifique que los archivos existan y tengan el tamaño correcto.
- Intente descargar los modelos manualmente en la misma carpeta.
2. **El procesamiento de la imagen es incorrecto.**
- La transformación blob podría estar mal configurada.
- Intente usar diferentes preprocesamiento de la imagen.
3. **El umbral de confianza es demasiado alto.**
- Pruebe umbrales más bajos como 0.1 o 0.2.
- Ajuste la sensibilidad de detección.
4. **Hay un problema con la visualización de los resultados.**
- Verifique el código que dibuja los rectángulos.
- Asegúrese de que las coordenadas sean válidas.
### Soluciones para la aplicación principal:
1. Intente usar Haar Cascades en lugar del modelo DNN.
2. Ajuste el umbral de confianza a un valor más bajo.
3. Verifique la conversión de color BGR a RGB en la visualización.
4. Intente usar otro modelo de detección facial como MediaPipe.
""")
else:
st.write("""
### La detección facial funciona en el diagnóstico, pero no en la aplicación principal
Esto sugiere que hay algún problema en la aplicación principal, no en el modelo. Revise:
1. Cómo se procesan las imágenes en la aplicación principal
2. El código que dibuja los rectángulos verdes
3. La conversión de color BGR a RGB para visualización
4. Los umbrales de confianza utilizados
""")
except Exception as e:
st.error(f"Error general en el diagnóstico: {e}")
# Crear un sidebar con opciones
st.sidebar.title("Opciones")
modo = st.sidebar.radio("Seleccionar modo:", ["Aplicación principal", "Diagnóstico"])
if modo == "Diagnóstico":
# Ejecutar diagnóstico
modo_diagnostico()
else:
# Ejecutar aplicación principal
try:
# Importar la aplicación principal
print("Starting Face Detection Application...")
from streamlit_app import main
# Main entry point
if __name__ == "__main__":
main()
except Exception as e:
st.error(f"Error al iniciar la aplicación: {e}")
st.error("Por favor, revise los logs para más información.")