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()