tutoriales.com

Domótica Personalizada: Control de Acceso con Reconocimiento Facial y ESP32-CAM

Este tutorial te guiará paso a paso en la creación de un sistema de control de acceso con reconocimiento facial utilizando una placa ESP32-CAM. Descubrirás cómo configurar el hardware, programar el software y conectar tu proyecto al Internet de las Cosas para una domótica personalizada y segura.

Intermedio30 min de lectura14 views
Reportar error

Introducción al Control de Acceso Inteligente con Reconocimiento Facial 🔒✨

En la era de la domótica, la seguridad y la comodidad se fusionan para ofrecernos soluciones innovadoras. El control de acceso basado en reconocimiento facial es una de esas tecnologías que, hasta hace poco, parecía sacada de una película de ciencia ficción. Hoy, gracias a dispositivos de bajo costo como el ESP32-CAM, podemos implementar nuestros propios sistemas de seguridad con un presupuesto muy ajustado.

Este tutorial te sumergirá en el fascinante mundo del reconocimiento facial aplicado a la domótica. Aprenderás a construir un sistema que identifica a personas autorizadas y, en función de ello, puede activar un mecanismo de apertura de puerta o enviar notificaciones. Es un proyecto ideal para mejorar la seguridad de tu hogar, oficina o incluso para experimentar con aplicaciones más avanzadas del Internet de las Cosas (IoT).

¿Por qué reconocimiento facial con ESP32-CAM? 🤔

El ESP32-CAM es una placa de desarrollo compacta y potente que integra un módulo Wi-Fi, Bluetooth y una cámara OV2640. Su bajo costo y la capacidad de procesar tareas de visión artificial directamente en el dispositivo (lo que se conoce como edge computing) lo hacen perfecto para proyectos de IoT donde el reconocimiento de imágenes es clave. Además, la comunidad de desarrollo alrededor del ESP32 es vasta, lo que facilita encontrar recursos y soporte.

Al final de este tutorial, serás capaz de:

  • Configurar un ESP32-CAM para captura y procesamiento de imágenes.
  • Implementar un algoritmo básico de reconocimiento facial.
  • Controlar un actuador (como un relé para una cerradura eléctrica) basado en la identificación.
  • Integrar tu sistema con notificaciones para mantenerte informado.

💡 Consejo: Aunque este tutorial se centra en el reconocimiento facial, las bases que aprenderás son aplicables a otros proyectos de visión por computadora con el ESP32-CAM, como la detección de objetos o la lectura de códigos QR.


🛠️ Materiales Necesarios

Antes de sumergirnos en la programación y el montaje, asegúrate de tener todos los componentes necesarios. La mayoría de estos elementos son económicos y fácilmente disponibles en tiendas de electrónica o en línea.

ComponenteDescripciónCantidadCosto EstimadoEnlace Típico
---------------
ESP32-CAMPlaca de desarrollo con cámara OV26401BajoTiendas IoT
FTDI ProgramadorAdaptador USB a TTL para programar el ESP32-CAM1BajoTiendas Electrónica
---------------
Fuente de Alimentación5V DC, al menos 1A (para ESP32-CAM)1BajoAdaptador USB
Relé de 5VMódulo de relé de 1 canal para controlar el actuador1Muy bajoTiendas Electrónica
---------------
Servomotor SG90 (Opcional)Pequeño servo para simular la apertura de una puerta1Muy bajoTiendas Electrónica
BreadboardPara prototipos y conexiones temporales1Muy bajoTiendas Electrónica
---------------
Cables DupontMacho-macho, macho-hembra, hembra-hembra~20Muy bajoTiendas Electrónica
Cerradura Eléctrica (Opcional)Para una implementación real de control de acceso1MedioTiendas Seguridad
---------------
Resistencia 10kΩPara el botón de entrenamiento1Muy bajoTiendas Electrónica
Botón PulsadorPara iniciar el proceso de entrenamiento de caras1Muy bajoTiendas Electrónica
⚠️ Advertencia: Al trabajar con la cerradura eléctrica, asegúrate de entender cómo funciona y las precauciones de seguridad necesarias. Si no tienes experiencia, te recomendamos usar un servomotor o un LED para simular la apertura/cierre.

🔌 Diagrama de Conexión: Hardware Esencial

Las conexiones son cruciales para el funcionamiento de nuestro sistema. Presta especial atención al cableado para evitar daños a los componentes. El ESP32-CAM requiere una conexión específica para su programación y un circuito aparte para el relé o servomotor.

Conexión del FTDI para Programación

El ESP32-CAM no tiene un programador USB integrado, por lo que necesitamos un adaptador FTDI. Asegúrate de que el FTDI esté configurado a 5V (algunos tienen un jumper para seleccionar 3.3V/5V).

Paso 1: Conecta `VCC` del ESP32-CAM a `5V` del FTDI.
Paso 2: Conecta `GND` del ESP32-CAM a `GND` del FTDI.
Paso 3: Conecta `U0R` (RX) del ESP32-CAM a `TX` del FTDI.
Paso 4: Conecta `U0T` (TX) del ESP32-CAM a `RX` del FTDI.
Paso 5: IMPORTANTE: Conecta `GPIO0` del ESP32-CAM a `GND` **antes** de conectar el FTDI al USB. Esto pone el ESP32-CAM en modo de flash. Desconéctalo después de la carga del código.
Conexión ESP32-CAM a FTDI ESP32-CAM VCC GND U0R (RX) U0T (TX) GPIO0 FTDI Programador 5V GND TX RX MODO FLASH Alimentación (5V) Tierra (GND) RX ➔ TX TX ➔ RX

Conexión del Relé/Servomotor para Control de Acceso

Una vez programado, el ESP32-CAM se alimentará por su pin 5V (o 3.3V, dependiendo del modelo específico y la fuente), y controlará el relé o servomotor a través de uno de sus GPIOs.

Conexión con un Módulo de Relé

Para controlar una cerradura eléctrica, el relé actúa como un interruptor. Asegúrate de que la fuente de alimentación para la cerradura sea independiente si maneja voltajes o corrientes altas.

  • 5V del ESP32-CAM a VCC del Módulo Relé (o a una fuente de alimentación externa de 5V si el ESP32-CAM tiene una fuente limitada).
  • GND del ESP32-CAM a GND del Módulo Relé.
  • GPIO (por ejemplo, GPIO12) del ESP32-CAM a IN del Módulo Relé.
  • La cerradura eléctrica se conecta a los terminales NO (Normalmente Abierto) y COM (Común) del relé, o NC (Normalmente Cerrado) y COM, dependiendo de cómo quieres que se comporte (abierto/cerrado por defecto).

Conexión con un Servomotor (Simulación)

  • 5V del ESP32-CAM a VCC (cable rojo) del Servomotor.
  • GND del ESP32-CAM a GND (cable marrón/negro) del Servomotor.
  • GPIO (por ejemplo, GPIO12) del ESP32-CAM a SIGNAL (cable naranja/amarillo) del Servomotor.
🔥 Importante: El ESP32-CAM tiene varios GPIOs disponibles. Consulta el pinout específico de tu placa para elegir los más adecuados. Algunos GPIOs están reservados para la cámara o la tarjeta SD. Para el relé o servomotor, `GPIO12`, `GPIO13`, `GPIO14` o `GPIO15` suelen ser buenas opciones.

Conexión del Botón de Entrenamiento

Para añadir nuevas caras al sistema, implementaremos un botón que activará el modo de entrenamiento.

  • Conecta un lado del botón a un GPIO del ESP32-CAM (por ejemplo, GPIO4).
  • Conecta el otro lado del botón a GND.
  • Conecta una resistencia pull-up de 10kΩ desde el mismo GPIO (GPIO4) a 3.3V del ESP32-CAM (alternativamente, puedes usar la resistencia pull-up interna del ESP32 activándola por software).
ESP32-CAM 5V GND 3.3V GPIO12 GPIO4 MÓDULO RELÉ VCC GND IN NO COM NC BOTÓN 10k Ω 5V VCC GPIO12 -> IN GPIO4 (Señal)

💻 Configuración del Entorno de Desarrollo (Arduino IDE)

Para programar el ESP32-CAM, utilizaremos el entorno de desarrollo Arduino IDE, que es ampliamente conocido y fácil de configurar.

1. Instalar Arduino IDE

Si aún no lo tienes, descarga e instala la última versión del Arduino IDE.

2. Añadir el Soporte para ESP32

Para que Arduino IDE reconozca las placas ESP32, necesitas añadir el gestor de tarjetas:

  1. Abre Arduino IDE.
  2. Ve a Archivo > Preferencias.
  3. En el campo URL de Gestores de Tarjetas Adicionales, añade la siguiente URL: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json Si ya tienes otras URLs, sepáralas con una coma.
  4. Haz clic en OK.
  5. Ve a Herramientas > Placa > Gestor de Tarjetas....
  6. Busca esp32 e instala la plataforma ESP32 de Espressif Systems.

3. Seleccionar la Placa Correcta

Una vez instalado el soporte del ESP32:

  1. Conecta tu FTDI (con el ESP32-CAM en modo flash) a tu computadora.
  2. Ve a Herramientas > Placa y selecciona AI Thinker ESP32-CAM.
  3. Ve a Herramientas > Puerto y selecciona el puerto COM al que esté conectado tu FTDI (puede ser COMx en Windows o /dev/ttyUSBx en Linux/macOS).
  4. Ajusta las configuraciones de la placa:
    • Flash Frecuency: 80MHz
    • Flash Mode: QIO
    • Partition Scheme: Huge APP (3MB No OTA) o AI Thinker ESP32-CAM (si está disponible y tiene el tamaño adecuado).
    • CPU Frecuency: 240MHz (WiFi/BT)
📌 Nota: La selección del `Partition Scheme` es importante. El reconocimiento facial consume mucha memoria, por lo que `Huge APP` o una partición similar que deje más espacio para el código de la aplicación es crucial.

📝 Programación del ESP32-CAM: El Corazón del Sistema

La lógica central de nuestro sistema de control de acceso reside en el código que subiremos al ESP32-CAM. Utilizaremos el ejemplo de reconocimiento facial de la librería esp32-camera y lo modificaremos para nuestro propósito.

1. Descargar la Librería esp32-camera

El código de ejemplo que usaremos se encuentra dentro de la librería esp32-camera.

  1. En Arduino IDE, ve a Archivo > Ejemplos > ESP32 > Camera.
  2. Selecciona CameraWebServer.

Este ejemplo nos servirá como base. Lo modificaremos para incluir la funcionalidad de reconocimiento facial, control del relé y el botón de entrenamiento.

2. Modificaciones al Código Base

Aquí te presento un esqueleto del código que necesitarás. Tendrás que añadir tus credenciales de Wi-Fi y definir los GPIOs correctos.

#include <WiFi.h>
#include <esp_camera.h>
#include <esp_face.h>
#include <soc/soc.h>
#include <soc/rtc_cntl_reg.h>
#include <esp_http_server.h>

// --- Definiciones de Pines (AJUSTA ESTO A TU CONFIGURACIÓN) ---
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27

#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

#define LED_GPIO_NUM      -1 // GPIO donde está conectado el flash LED (si lo tienes, ej: GPIO4)
#define RELAY_GPIO_NUM    12 // GPIO para el relé/servomotor
#define TRAIN_BTN_GPIO_NUM 4 // GPIO para el botón de entrenamiento

// --- Credenciales Wi-Fi ---
const char* ssid = "TU_WIFI_SSID";
const char* password = "TU_WIFI_PASSWORD";

// --- Variables Globales ---
httpd_handle_t http_server = NULL;

// Función para inicializar la cámara
void initCamera() {
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG; // Usamos JPEG para eficiencia

  // Frame buffer settings
  config.frame_size = FRAMESIZE_QVGA; // QQVGA (160x120), HQVGA (240x160), QVGA (320x240)
  config.jpeg_quality = 10; // 0-63, más bajo es mejor calidad
  config.fb_count = 2; // Dos buffers para fluidez

  // Iniciar la cámara
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  // Configurar las opciones de la cámara (ej: brillo, contraste, etc.)
  sensor_t * s = esp_camera_sensor_get();
  // s->set_vflip(s, 1); // Voltear imagen verticalmente
  // s->set_hmirror(s, 1); // Espejo horizontal
  // s->set_brightness(s, 1); // -2 to 2
  // s->set_contrast(s, 1); // -2 to 2
  // s->set_saturation(s, 1); // -2 to 2
}

// Función para el servidor web (manejo de reconocimiento y registro)
static esp_err_t capture_handler(httpd_req_t *req) {
  // Implementación del reconocimiento facial aquí
  // Tomar una foto, procesarla con esp_face, comparar con caras guardadas
  // Si hay coincidencia, activar el relé
  // Si no, rechazar el acceso o tomar otra acción

  // Simulación de reconocimiento:
  Serial.println("Capturando imagen...");
  camera_fb_t *fb = esp_camera_fb_get();
  if (!fb) {
    Serial.println("Camera capture failed");
    httpd_resp_send_500(req);
    return ESP_FAIL;
  }

  // Convertir a escala de grises para el reconocimiento facial
  dl_matrix3du_t *image_matrix = dl_matrix3du_alloc(1, fb->width, fb->height, 1);
  if (!image_matrix) {
    esp_camera_fb_return(fb);
    Serial.println("Error al alocar matriz de imagen");
    httpd_resp_send_500(req);
    return ESP_FAIL;
  }

  fmt2rgb888(fb->buf, fb->len, fb->format, image_matrix->item);
  esp_camera_fb_return(fb);

  // Ejecutar detección de caras
  face_t *face = NULL;
  box_array_t *box_array = face_detect(image_matrix->item, image_matrix->w, image_matrix->h, image_matrix->c);

  if (box_array) {
    if (box_array->len > 0) {
      face = face_recognize(image_matrix->item, image_matrix->w, image_matrix->h, image_matrix->c, box_array->box[0].score, box_array->box[0].landmark);
      if (face) {
        // Aquí iría la lógica de comparación con caras registradas
        // Para simplificar, asumo que 'face' tiene un identificador o una similitud.
        // Si es una cara conocida:
        // if (isKnownFace(face)) {
        //   Serial.println("Cara reconocida! Abriendo puerta.");
        //   digitalWrite(RELAY_GPIO_NUM, HIGH); // Activar relé
        //   delay(3000); // Mantener abierto por 3 segundos
        //   digitalWrite(RELAY_GPIO_NUM, LOW); // Cerrar relé
        // }

        Serial.println("Cara detectada y reconocida (simulado).");
        httpd_resp_sendstr(req, "ACCESO_PERMITIDO");
        dl_matrix3du_free(image_matrix);
        return ESP_OK;
      }
    }
    free(box_array->box);
    free(box_array);
  }

  Serial.println("Cara no reconocida o no detectada.");
  httpd_resp_sendstr(req, "ACCESO_DENEGADO");
  dl_matrix3du_free(image_matrix);
  return ESP_FAIL;
}

// Handler para el registro de nuevas caras (cuando se pulsa el botón)
static esp_err_t enroll_handler(httpd_req_t *req) {
  // Implementación del registro de caras aquí
  // Capturar varias imágenes, procesarlas y guardar los descriptores faciales
  // Se recomienda guardar en SPIFFS o en una base de datos externa
  Serial.println("Modo de entrenamiento activado. Por favor, mire a la cámara.");
  httpd_resp_sendstr(req, "ENTRENAMIENTO_INICIADO");

  // Simulación de captura y guardado de 5 fotos para entrenamiento
  for (int i = 0; i < 5; i++) {
    camera_fb_t *fb = esp_camera_fb_get();
    if (!fb) {
      Serial.println("Error de captura para entrenamiento");
      continue;
    }
    // Aquí deberías procesar fb para obtener los descriptores faciales y guardarlos.
    // face_t *new_face = face_recognize(...);
    // saveFaceDescriptor(new_face);
    esp_camera_fb_return(fb);
    delay(1000);
  }
  Serial.println("Entrenamiento completado (simulado).");
  httpd_resp_sendstr(req, "ENTRENAMIENTO_COMPLETADO");

  return ESP_OK;
}

// --- Configuración de rutas del servidor web ---
httpd_uri_t capture_uri = {
    .uri       = "/capture",
    .method    = HTTP_GET,
    .handler   = capture_handler,
    .user_ctx  = NULL
};

httpd_uri_t enroll_uri = {
    .uri       = "/enroll",
    .method    = HTTP_GET,
    .handler   = enroll_handler,
    .user_ctx  = NULL
};

void startCameraServer() {
  httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  config.max_uri_handlers = 10; // Aumentar si se añaden más handlers

  Serial.printf("Starting web server on port: '%d'\n", config.server_port);
  if (httpd_start(&http_server, &config) == ESP_OK) {
    httpd_register_uri_handler(http_server, &capture_uri);
    httpd_register_uri_handler(http_server, &enroll_uri);
  }
}

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // Deshabilitar detector de brownout
  Serial.begin(115200);
  Serial.setDebugOutput(false);

  initCamera();

  // Configurar GPIOs
  pinMode(RELAY_GPIO_NUM, OUTPUT);
  digitalWrite(RELAY_GPIO_NUM, LOW); // Asegurarse de que el relé esté apagado al inicio
  pinMode(TRAIN_BTN_GPIO_NUM, INPUT_PULLUP); // Usar pull-up interno para el botón

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi conectado");
  Serial.print("Dirección IP: ");
  Serial.println(WiFi.localIP());

  startCameraServer();
}

void loop() {
  // Monitorear el botón de entrenamiento
  if (digitalRead(TRAIN_BTN_GPIO_NUM) == LOW) { // Botón pulsado (activo en bajo)
    Serial.println("Botón de entrenamiento detectado.");
    // Llamar al handler de registro de caras directamente o redirigir
    // Para simplificar, podrías llamar una función que inicie el proceso de registro
    // O hacer una petición HTTP interna a /enroll
    delay(500); // Debounce

    // Puedes implementar aquí la lógica para iniciar el registro
    // Por ejemplo, pedir al usuario que se coloque delante de la cámara y presionar de nuevo
    // O enviar una notificación a un servidor externo para activar el registro

    // Una forma sencilla de activar el entrenamiento a través del botón:
    // Si mantienes el botón pulsado durante X segundos, inicia el registro.
    // Por ahora, solo simularé el inicio del registro en serie.
    Serial.println("Iniciando proceso de registro de nuevas caras...");
    // Aquí deberías integrar la lógica de enroll_handler de una manera que no dependa de HTTP request.
    // Para una implementación real, esto sería más complejo, con una interfaz de usuario o una app.

    // Para este ejemplo, solo notificaré por serie.
    delay(3000); // Simula el tiempo de entrenamiento
    Serial.println("Proceso de registro finalizado.");
  }
  delay(10);
}

Explicación de Secciones Clave del Código:

  • Pines GPIO: Asegúrate de que los DEFINE de los pines (especialmente RELAY_GPIO_NUM y TRAIN_BTN_GPIO_NUM) coincidan con tus conexiones físicas.
  • Credenciales Wi-Fi: Reemplaza TU_WIFI_SSID y TU_WIFI_PASSWORD con los datos de tu red.
  • initCamera(): Configura la cámara. Puedes ajustar FRAMESIZE_QVGA a una resolución mayor o menor (FRAMESIZE_QQVGA, FRAMESIZE_VGA) según la memoria y la velocidad de procesamiento que necesites. jpeg_quality también es importante.
  • capture_handler(): Esta función se ejecuta cuando se accede a la URL /capture. Es donde se toma la foto, se detectan caras (face_detect) y se intenta reconocer (face_recognize). Aquí es donde necesitarías tu lógica de bases de datos de caras para comparar el face actual con los registrados. Por ahora, es un placeholder que indica si se detectó una cara y simula un reconocimiento.
  • enroll_handler(): Este handler, si se activa (por ejemplo, mediante una petición HTTP o el botón de entrenamiento), debería iniciar el proceso de registro de una nueva cara. Consiste en tomar varias fotos de la persona, extraer sus características faciales y guardarlas. Este es un punto donde la complejidad puede aumentar significativamente si quieres persistir las caras de forma robusta.
  • setup(): Inicializa la comunicación serial, la cámara, el Wi-Fi y el servidor HTTP. Configura el pin del relé como salida y el del botón como entrada.
  • loop(): Aquí puedes añadir lógica de lectura del botón de entrenamiento. En este ejemplo, solo se imprime un mensaje serial, pero en una implementación real, podrías llamar a una función que inicie el proceso de registro de caras.
💡 Consejo: La parte más compleja del reconocimiento facial es la gestión de la base de datos de caras. Para un proyecto simple, podrías guardar los descriptores faciales directamente en la memoria SPIFFS del ESP32. Para algo más robusto, considera una base de datos externa o un servicio en la nube (aunque esto aumentaría la latencia).

🚀 Subiendo el Código al ESP32-CAM

Una vez que hayas modificado el código con tus credenciales y pines:

  1. Conecta GPIO0 a GND en el ESP32-CAM.
  2. Conecta el FTDI al USB de tu computadora (con el ESP32-CAM ya conectado al FTDI).
  3. En Arduino IDE, haz clic en el botón Subir (la flecha hacia la derecha).
  4. Verás mensajes de Conectando... en la consola. Si no empieza a cargar, pulsa el botón RST (Reset) del ESP32-CAM.
  5. Una vez que la carga haya terminado, desconecta GPIO0 de GND.
  6. Desconecta y vuelve a conectar la alimentación del ESP32-CAM (o pulsa RST) para que inicie en modo normal.
⚠️ Advertencia: Si olvidas desconectar GPIO0 de GND después de la carga, el ESP32-CAM no iniciará la ejecución de tu programa y permanecerá en modo de flash.

🌐 Interacción con el Sistema: Servidor Web y Entrenamiento

Una vez que el ESP32-CAM esté funcionando, actuará como un pequeño servidor web al que podrás acceder desde tu navegador o una aplicación.

Accediendo al Servidor Web

  1. Abre el Monitor Serial en Arduino IDE (a 115200 baudios).
  2. Verás la dirección IP asignada al ESP32-CAM (ej: 192.168.1.100).
  3. Abre tu navegador web y navega a esa dirección IP.
  4. Para probar el reconocimiento, puedes acceder a la URL http://TU_IP_DEL_ESP32/capture.
    • El ESP32-CAM tomará una foto, intentará reconocer una cara y te devolverá ACCESO_PERMITIDO o ACCESO_DENEGADO (o ACCESO_RECONOCIDO si no tienes el sistema de base de datos implementado). En una implementación real, este endpoint no sería directamente accesible por el usuario, sino por una aplicación frontend.

Proceso de Entrenamiento de Caras 👨‍🏫

El sistema necesita aprender a reconocer las caras. Esto se hace en el modo de entrenamiento.

  1. Pulsar el Botón de Entrenamiento: Cuando pulses el TRAIN_BTN_GPIO_NUM, el sistema debería entrar en un modo especial. En nuestro código de ejemplo, esto solo imprime un mensaje en el Monitor Serial.
  2. Captura de Muestras: En un sistema completo, el ESP32-CAM te pediría que te coloques frente a la cámara y tomaría varias fotos desde diferentes ángulos y expresiones. Es crucial que las condiciones de iluminación sean consistentes.
  3. Extracción y Guardado de Descriptores: Por cada imagen, el ESP32-CAM extraería un descriptor facial (una representación numérica única de la cara) y lo guardaría en su memoria SPIFFS junto con un ID de usuario.
    • 🔥 Importante: El código provisto simplifica enormemente este proceso. La implementación real de la base de datos de descriptores faciales y su comparación requiere un conocimiento más profundo de las librerías `esp_face` y `SPIFFS` o una base de datos externa. Este tutorial se enfoca en la base, y la implementación de una base de datos robusta de caras es un paso avanzado.
¿Qué es un Descriptor Facial? 🧐 Un descriptor facial es un vector de números (un array) que representa las características únicas de una cara. Cuando el sistema "reconoce" una cara, en realidad está comparando el descriptor facial de la persona capturada con un conjunto de descriptores previamente guardados. Si la "distancia" entre el descriptor capturado y uno guardado es lo suficientemente pequeña (es decir, son muy similares), se considera una coincidencia.

📈 Mejoras y Pasos Avanzados

Este proyecto es una excelente base para aprender, pero hay muchas formas de expandirlo y mejorarlo para una implementación real.

1. Gestión de Base de Datos de Caras 🗄️

  • SPIFFS: Almacenar los descriptores faciales en el sistema de archivos SPIFFS del ESP32-CAM. Necesitarás funciones para leer, escribir y borrar estos descriptores.
  • Servidor Externo: Enviar los descriptores faciales a un servidor MQTT, una base de datos Firebase, un servidor Node-RED, o una base de datos SQL para una gestión centralizada y escalable.

2. Interfaz de Usuario 📱

  • Aplicación Móvil: Desarrollar una aplicación móvil (Android/iOS) que se conecte al ESP32-CAM para activar el entrenamiento, ver el registro de accesos y abrir la puerta manualmente.
  • Panel Web Local: Crear una interfaz web más completa en el propio ESP32 (usando HTML, CSS y JavaScript ligero) para gestionar usuarios y ver el streaming de la cámara.

3. Notificaciones Inteligentes 🔔

  • Telegram/Pushbullet: Enviar notificaciones a tu teléfono cuando alguien intenta acceder, ya sea reconocido o no. Puedes incluir la foto del momento.
  • MQTT: Integrar con un broker MQTT para que otros dispositivos domóticos reaccionen a los eventos de acceso.

4. Hardware Adicional 🚪

  • Sensor de Puerta: Añadir un sensor magnético para saber si la puerta está realmente abierta o cerrada.
  • Teclado/RFID: Complementar el reconocimiento facial con otros métodos de autenticación para mayor seguridad o como respaldo.
  • Mejor Iluminación: Implementar LEDs infrarrojos para un mejor rendimiento en condiciones de poca luz.

5. Seguridad de Red 🛡️

  • HTTPS: Implementar un servidor HTTPS en el ESP32 para cifrar las comunicaciones, especialmente si la cámara está expuesta a la red pública o si se envía información sensible.
  • Autenticación de API: Asegurar los endpoints del servidor web con tokens o claves API.
80% Funcionalidad Base
60% Robustez del Sistema
40% Experiencia de Usuario

Conclusión ✅

Has llegado al final de este tutorial. Felicidades por haber explorado el fascinante mundo del control de acceso con reconocimiento facial utilizando el ESP32-CAM. Aunque el camino hacia un sistema de seguridad de nivel profesional es largo, este proyecto te ha proporcionado una base sólida para entender los principios, el hardware y la programación involucrados.

El Internet de las Cosas nos ofrece un sinfín de posibilidades para hacer nuestros espacios más inteligentes y seguros. Con los conocimientos adquiridos, estás listo para personalizar y expandir este proyecto, adaptándolo a tus necesidades específicas y explorando las mejoras propuestas en las secciones avanzadas.

¡Experimenta, construye y comparte tus creaciones! La comunidad IoT está en constante crecimiento y tus aportaciones pueden inspirar a otros.

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!