ComputerVisionProject / detect_face_test.py
jarondon82's picture
Agregar scripts de prueba para diagnóstico de detección facial
7b0cfb4
import cv2
import numpy as np
import time
def main():
"""
Script para probar la detección de rostros con diferentes configuraciones
y visualizar claramente los resultados.
"""
print("Iniciando prueba de detección facial...")
# Cargar el modelo DNN preentrenado para detección de rostros
print("Cargando modelo DNN para detección facial...")
# Usar el modelo Caffe
modelFile = "models/deploy.prototxt"
weightsFile = "models/res10_300x300_ssd_iter_140000_fp16.caffemodel"
try:
face_net = cv2.dnn.readNetFromCaffe(modelFile, weightsFile)
print("Modelo DNN cargado correctamente.")
except Exception as e:
print(f"Error al cargar el modelo DNN: {str(e)}")
print("Intentando usar detección Haar en su lugar...")
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
if face_cascade.empty():
print("Error: No se pudo cargar el clasificador Haar.")
return
use_dnn = False
else:
use_dnn = True
# Iniciar la cámara
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("Error: No se pudo abrir la cámara.")
return
print("Cámara iniciada correctamente. Presione 'q' para salir, 's' para guardar una captura.")
# Contador de frames
frame_count = 0
start_time = time.time()
# Umbrales de confianza para probar
confidence_thresholds = [0.5, 0.3, 0.1]
current_threshold_index = 0
current_threshold = confidence_thresholds[current_threshold_index]
def detect_face_dnn(net, frame, conf_threshold=0.5):
# Preparar la imagen para la red (redimensionar a 300x300 y normalizar)
h, w = frame.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0,
(300, 300), (104.0, 177.0, 123.0))
# Pasar la imagen a través de la red
net.setInput(blob)
detections = net.forward()
# Procesar las detecciones
bboxes = []
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > conf_threshold:
# Obtener coordenadas de la caja delimitadora
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
x1, y1, x2, y2 = box.astype("int")
# Asegurarse de que las coordenadas estén dentro de la imagen
x1, y1 = max(0, x1), max(0, y1)
x2, y2 = min(w, x2), min(h, y2)
# Añadir caja y confianza
bboxes.append([x1, y1, x2, y2, confidence])
return bboxes if bboxes else None
def detect_face_haar(face_cascade, frame, scale_factor=1.1):
# Convertir a escala de grises para la detección Haar
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Detectar rostros
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=scale_factor,
minNeighbors=5,
minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE
)
if len(faces) == 0:
return None
# Convertir al mismo formato que el DNN
bboxes = []
for (x, y, w, h) in faces:
bboxes.append([x, y, x+w, y+h, 1.0]) # Confianza simulada de 1.0
return bboxes
while True:
# Leer un frame de la cámara
ret, frame = cap.read()
if not ret:
print("Error al capturar el frame.")
break
# Incrementar contador
frame_count += 1
elapsed = time.time() - start_time
fps = frame_count / elapsed if elapsed > 0 else 0
# Crear copia del frame para dibujar
display_frame = frame.copy()
# Detectar rostros según el método seleccionado
if use_dnn:
bboxes = detect_face_dnn(face_net, frame, current_threshold)
method_text = f"DNN (Conf: {current_threshold})"
else:
bboxes = detect_face_haar(face_cascade, frame)
method_text = "Haar Cascade"
# Dibujar los rostros detectados
if bboxes is not None:
for box in bboxes:
x1, y1, x2, y2 = int(box[0]), int(box[1]), int(box[2]), int(box[3])
# Dibujar rectángulo verde grueso
cv2.rectangle(display_frame, (x1, y1), (x2, y2), (0, 255, 0), 3)
# Mostrar confianza
if len(box) > 4:
conf = box[4]
cv2.putText(display_frame, f"Conf: {conf:.2f}", (x1, y1 - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
face_count = len(bboxes)
status = f"Detectados: {face_count}"
else:
status = "No se detectaron rostros"
# Dibujar información en pantalla
h, w = display_frame.shape[:2]
# Método de detección
cv2.putText(display_frame, f"Método: {method_text}", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
# Estado de detección
cv2.putText(display_frame, status, (10, 70),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
# FPS
cv2.putText(display_frame, f"FPS: {fps:.1f}", (10, h - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
# Rectángulo de prueba en la esquina superior derecha
cv2.rectangle(display_frame, (w-150, 50), (w-50, 150), (0, 0, 255), 3)
cv2.putText(display_frame, "TEST", (w-130, 40),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
# Mostrar resultado
cv2.imshow("Prueba de Detección Facial", display_frame)
# Manejo de teclas
key = cv2.waitKey(1) & 0xFF
# Salir si se presiona 'q'
if key == ord('q'):
break
# Cambiar umbral si se presiona 't'
elif key == ord('t'):
current_threshold_index = (current_threshold_index + 1) % len(confidence_thresholds)
current_threshold = confidence_thresholds[current_threshold_index]
print(f"Umbral cambiado a: {current_threshold}")
# Guardar imagen si se presiona 's'
elif key == ord('s'):
timestamp = time.strftime("%Y%m%d-%H%M%S")
filename = f"face_detection_{timestamp}.jpg"
cv2.imwrite(filename, display_frame)
print(f"Imagen guardada como {filename}")
# Imprime estadísticas
print(f"Frames totales: {frame_count}")
print(f"Tiempo total: {elapsed:.2f} segundos")
print(f"FPS promedio: {fps:.1f}")
# Liberar recursos
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()