Python con Arduino + Open CV

 Encender y Apagar el LED con Expresiones Faciales usando OpenCV y Arduino



Objetivo:

  • Usar la cámara para detectar si estás sonriendo o enojado.
  • Si sonríes, se encenderá el LED en el Arduino.
  • Si te enojas, se apagará el LED.

1️⃣ Instalación de Librerías Necesarias

Antes de empezar, asegúrate de tener instaladas las siguientes librerías en Python.

Ejecuta estos comandos en CMD o PowerShell:

pip install opencv-python mediapipe numpy pyserial

📌 Explicación:
opencv-python → Para usar la cámara y procesar imágenes.
mediapipe → Para detectar el rostro y analizar expresiones faciales.
numpy → Para manejar cálculos en matrices de imagen.
pyserial → Para comunicarse con Arduino por puerto serial.


2️⃣ Código en Arduino (IDE de Arduino)

Antes de programar Python, necesitamos un código en el Arduino que reciba comandos Seriales (1 para encender y 0 para apagar el LED).

📌 Código en Arduino (cargarlo en la placa usando Arduino IDE):

void setup() {
    Serial.begin(9600);  // Iniciar comunicación serial
    pinMode(13, OUTPUT); // Configurar LED en el pin 13 como salida
}

void loop() {
    if (Serial.available()) {  // Si hay datos en el puerto serie
        char comando = Serial.read();  // Leer el comando recibido
        if (comando == '1') {
            digitalWrite(13, HIGH);  // Encender LED
        }
        else if (comando == '0') {
            digitalWrite(13, LOW);   // Apagar LED
        }
    }
}

Sube este código a tu Arduino antes de continuar.


3️⃣ Código en Python con OpenCV y MediaPipe

Ahora vamos a crear el código en Python para detectar la expresión facial y controlar el LED.

1️⃣ Crear un archivo Python y nombrarlo control_led_cara.py.
2️⃣ Copiar este código en el archivo:

import cv2
import mediapipe as mp
import serial
import time

# Conectar con el Arduino (cambia 'COM3' por el puerto correcto)
try:
    arduino = serial.Serial('COM3', 9600)
    time.sleep(2)  # Esperar que la conexión se establezca
except:
    print("⚠️ No se pudo conectar con Arduino. Verifica el puerto COM.")
    exit()

# Inicializar MediaPipe Face Mesh
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh()

# Iniciar la cámara
cap = cv2.VideoCapture(0)

def detectar_sonrisa(landmarks):
    """Determina si la boca está en posición de sonrisa o enojo."""
    labio_superior = landmarks[13].y  # Punto del labio superior
    labio_inferior = landmarks[14].y  # Punto del labio inferior
    boca_abierta = labio_inferior - labio_superior  # Distancia entre labios

    if boca_abierta > 0.05:  # Ajusta este umbral según tu rostro
        return "sonrisa"
    elif boca_abierta < 0.02:  # Boca apretada (indica enojo)
        return "enojo"
    else:
        return "neutral"

estado_actual = ""

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    # Convertir la imagen a RGB (MediaPipe usa RGB)
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    resultado = face_mesh.process(rgb_frame)

    if resultado.multi_face_landmarks:
        for landmarks in resultado.multi_face_landmarks:
            expresion = detectar_sonrisa(landmarks.landmark)

            if expresion == "sonrisa" and estado_actual != "sonrisa":
                print("😊 Sonrisa detectada → Encendiendo LED")
                arduino.write(b'1')  # Enviar '1' al Arduino
                estado_actual = "sonrisa"

            elif expresion == "enojo" and estado_actual != "enojo":
                print("😠 Enojo detectado → Apagando LED")
                arduino.write(b'0')  # Enviar '0' al Arduino
                estado_actual = "enojo"

            # Dibujar puntos en el rostro
            for punto in landmarks.landmark:
                x, y = int(punto.x * frame.shape[1]), int(punto.y * frame.shape[0])
                cv2.circle(frame, (x, y), 1, (0, 255, 0), -1)

    # Mostrar imagen con puntos de referencia
    cv2.imshow("Detección de Expresión Facial", frame)

    # Presiona 'q' para salir
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

4️⃣ Explicación del Código

🔹 1. Configuración Inicial

import cv2
import mediapipe as mp
import serial
import time

✔️ Importamos OpenCV, MediaPipe y PySerial para trabajar con la cámara y la conexión con Arduino.

arduino = serial.Serial('COM3', 9600)
time.sleep(2)

✔️ Abrimos la conexión con Arduino en el puerto COM3.


🔹 2. Detección de Expresiones Faciales

mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh()

✔️ Inicializamos MediaPipe Face Mesh, que detectará los puntos del rostro.

def detectar_sonrisa(landmarks):
    labio_superior = landmarks[13].y  
    labio_inferior = landmarks[14].y  
    boca_abierta = labio_inferior - labio_superior  

    if boca_abierta > 0.05:
        return "sonrisa"
    elif boca_abierta < 0.02:
        return "enojo"
    else:
        return "neutral"

✔️ Analizamos la apertura de la boca para determinar si sonríes o si estás enojado.


🔹 3. Control del LED según la expresión

if expresion == "sonrisa" and estado_actual != "sonrisa":
    print("😊 Sonrisa detectada → Encendiendo LED")
    arduino.write(b'1')  
    estado_actual = "sonrisa"

elif expresion == "enojo" and estado_actual != "enojo":
    print("😠 Enojo detectado → Apagando LED")
    arduino.write(b'0')  
    estado_actual = "enojo"

✔️ Si sonríes, enviamos "1" a Arduino para encender el LED.
✔️ Si te enojas, enviamos "0" para apagarlo.
✔️ Usamos estado_actual para evitar enviar el mismo comando varias veces.


5️⃣ Ejecutar el Programa

Para ejecutar el código, abre CMD y ejecuta:

python control_led_cara.py

🔹 Se abrirá la cámara y detectará tu rostro.
🔹 Si sonríes, el LED se encenderá.
🔹 Si te enojas, el LED se apagará.
🔹 Presiona q para cerrar la cámara.


6️⃣ Mejoras Opcionales 🚀

📌 Hacer que también detecte una expresión "neutral" para apagar el LED.
📌 Agregar más LEDs para diferentes expresiones.
📌 Hacer que muestre un emoji en pantalla según la expresión detectada.

¡Dime si necesitas más mejoras! 🚀🔥😃

Comments

Popular posts from this blog

Te cuento mi aventura como mestra IB de Design y STEM

Cómo enseñar a mover motores con Arduino (RECOMENDABLE PARA COLLEGIOS, GOOGLE REFERENCE SCHOOL QUE USEN CHROMEBOOKS!)

Python con Arduino + Interfaz