Spaces:
Build error
Build error
| 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() |