El proyecto consiste en implementar un sistema de control de encendido y apagado de pantalla de ordenador basado en el reconocimiento de gestos de la mano mediante MediaPipe. El sistema se activará al detectar la extensión de los cinco dedos de la mano derecha (apagado de pantalla) y se desactivará al detectar la extensión de los cinco dedos de la mano izquierda (restablecimiento de pantalla).
Con un poco de teatro previo podrás lograr un efecto de apagado dejando boquiabiertos a los que te estén mirando. Desarrollaremos una aplicación en Python para Linux Mint que controlará el encendido y apagado de la pantalla mediante gestos de mano, utilizando MediaPipe y una webcam.
Paso 1: Configurar el entorno
-
Instalar Python y pip: Asegúrate de tener Python 3.7 o superior instalado. Puedes verificarlo con:
python3 --version
Si no lo tienes instalado, puedes instalarlo con:
sudo apt update sudo apt install python3 python3-pip
-
Crear un entorno virtual: Puede que el paquete python3-venv necesario para crear entornos virtuales, no lo tengas instalado. Para hacerlo ejecuta lo siguiente:
sudo apt install python3-venv
Es recomendable usar un entorno virtual para aislar las dependencias del proyecto.
python3 -m venv mediapipe_env
- Activar el entorno virtual:
source mediapipe_env/bin/activate
Paso 2: Instalar MediaPipe
-
Instalar MediaPipe:
pip install mediapipe
-
Instalar OpenCV: MediaPipe a menudo se usa junto con OpenCV para manejar la captura de video y la visualización.
pip install opencv-python
Paso 3: Crear la aplicación básica
- Instalar xdotool: xdotool es una herramienta de línea de comandos para automatizar interacciones con ventanas y entornos gráficos en Linux, permitiendo mover el ratón, simular clics, teclear, y más. Nos servirá para mover el cursor del ratón cuando detectemos los 5 dedos de la mano izquierda con MediaPipe Hands.
sudo apt install xdotool
- Crear un archivo Python: Crea un archivo llamado
mediapipe_hands.py
y abre tu editor de texto favorito para editarlo.nano mediapipe_hands.py
- Escribir el código: A continuación, Procederemos a crear el programa en python que realiza la detección.
import cv2
import mediapipe as mp
import numpy as np
import subprocess
import random # Importar random para generar números aleatorios
# Inicializar soluciones de Mediapipe Hands
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands
# Inicializar la captura de video (1 es usualmente la segunda cámara web, si tienes)
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("No se puede abrir la cámara.")
exit()
# Inicializar el modelo de Hands
with mp_hands.Hands(
min_detection_confidence=0.5,
min_tracking_confidence=0.5) as hands:
while cap.isOpened():
success, image = cap.read()
if not success:
print("Ignorando fotograma de cámara vacío.")
continue
# Para mejorar el rendimiento, marcar la imagen como no escribible para pasarla por referencia.
image.flags.writeable = False
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = hands.process(image)
# Volver a dibujar la imagen en BGR para mostrarla
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# Dibujar las anotaciones de las manos en la imagen y detectar 5 dedos
if results.multi_hand_landmarks:
for hand_landmarks, handedness in zip(results.multi_hand_landmarks, results.multi_handedness):
hand_label = handedness.classification[0].label # Obtener la etiqueta de la mano ('Left' o 'Right')
mp_drawing.draw_landmarks(
image, hand_landmarks, mp_hands.HAND_CONNECTIONS)
# Detección de 5 dedos
dedos_arriba = 0
puntos_dedos = [8, 12, 16, 20] # Puntos índice de los dedos (sin pulgar para simplificar)
tip_ids = [mp_hands.HandLandmark.INDEX_FINGER_TIP,
mp_hands.HandLandmark.MIDDLE_FINGER_TIP,
mp_hands.HandLandmark.RING_FINGER_TIP,
mp_hands.HandLandmark.PINKY_TIP]
mcp_ids = [mp_hands.HandLandmark.INDEX_FINGER_MCP,
mp_hands.HandLandmark.MIDDLE_FINGER_MCP,
mp_hands.HandLandmark.RING_FINGER_MCP,
mp_hands.HandLandmark.PINKY_MCP]
thumb_tip_id = mp_hands.HandLandmark.THUMB_TIP
thumb_ip_id = mp_hands.HandLandmark.THUMB_IP
# Contar dedos levantados (pulgar separado)
if hand_label == 'Left':
if hand_landmarks.landmark[thumb_tip_id].x > hand_landmarks.landmark[thumb_ip_id].x:
dedos_arriba += 1
elif hand_label == 'Right':
if hand_landmarks.landmark[thumb_tip_id].x < hand_landmarks.landmark[thumb_ip_id].x:
dedos_arriba += 1
for tip_id, mcp_id in zip(tip_ids, mcp_ids):
if hand_landmarks.landmark[tip_id].y < hand_landmarks.landmark[mcp_id].y:
dedos_arriba += 1
# Acciones según la mano y la detección de 5 dedos
if dedos_arriba == 5:
if hand_label == 'Left':
# Mano IZQUIERDA: Apagar monitor
cv2.putText(image, "IZQUIERDA: APAGAR MONITOR!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX,
1, (0, 255, 0), 2, cv2.LINE_AA)
subprocess.run(["xset", "dpms", "force", "off"])
print("Monitor apagado por comando 'xset dpms force off' (mano izquierda)")
elif hand_label == 'Right':
# Mano DERECHA: Mover ratón aleatoriamente
cv2.putText(image, "DERECHA: MOVER RATON!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX,
1, (255, 0, 0), 2, cv2.LINE_AA)
# Obtener la posición actual del ratón
mouse_position = subprocess.run(["xdotool", "getmouselocation"], capture_output=True, text=True)
mouse_x = int(mouse_position.stdout.split()[0].split(':')[1])
mouse_y = int(mouse_position.stdout.split()[1].split(':')[1])
# Calcular un desplazamiento aleatorio entre -10 y 10 píxeles
offset_x = random.randint(-10, 10)
offset_y = random.randint(-10, 10)
# Calcular la nueva posición del ratón
new_x = mouse_x + offset_x
new_y = mouse_y + offset_y
# Mover el ratón a la nueva posición
subprocess.run(["xdotool", "mousemove", str(new_x), str(new_y)], env={"DISPLAY": ":0"})
print(f"Ratón movido a ({new_x}, {new_y}) (mano derecha)")
# Imagen en espejo horizontal (opcional, pero útil para la vista de cámara frontal)
image = cv2.flip(image, 1)
# Mostrar la imagen resultante Comenta la siguiente línea si quieres no mostrar la detección de manos.
cv2.imshow('Mediapipe Hands', image)
if cv2.waitKey(5) & 0xFF == 27: # ESC para salir
break
cap.release()
cv2.destroyAllWindows()
Paso 4: Ejecutar la aplicación
-
Ejecutar el script:
python mediapipe_hands.py
-
Ver la salida: Deberías ver una ventana que muestra la transmisión de video de tu cámara con las manos detectadas y las conexiones entre los puntos de referencia dibujadas. Se apagará el monitor al detectar los 5 dedos de la mano derecha y se encenderá al detectar los de la mano izquierda.
Paso 5: Desactivar el entorno virtual
Cuando termines de trabajar en tu proyecto, puedes desactivar el entorno virtual con:
deactivate