Controlando el Juego del T-Rex de Chrome con parpadeos

El proyecto consiste en integrar la detección de parpadeos utilizando Mediapipe en Python para controlar el salto del juego del T-Rex de Chrome (el juego que aparece cuando no hay conexión a Internet) en una página web. El objetivo principal es comprender cómo utilizar la visión artificial para interactuar con aplicaciones web en tiempo real.

Paso 1: Configurar el entorno:

1. Instalaremos Python3 y pip:

sudo apt update
sudo apt install python3 python3-pip

2. Crea el Directorio del Proyecto y Entorno Virtual:

mkdir parpadeo-trex
cd parpadeo-trex
sudo apt install python3-venv # Si no tienes python3-venv
python3 -m venv mediapipe_env
source mediapipe_env/bin/activate # Activamos el entorno virtual

3.Instala Mediapipe y Pynput:

# Mediapipe para detección facial y Pynput para simular pulsaciones de teclado.
pip3 install mediapipe 
pip3 install pynput

Paso 2: Crear la aplicación:

1. Creamos un archivo en Python que abriremos con nuestro editor de texto favorito.

nano parpadeo.py

2. Escribiremos el codigo para crear el programa que nos detecte cuando parpadeemos y pulsará la tecla espacio en nuestro sistema.

import cv2
import mediapipe
from math import sqrt
import numpy
from pynput.keyboard import Controller

# Inicializar controlador de teclado
keyboard = Controller()

COUNTER = 0
TOTAL_BLINKS = 0

FONT = cv2.FONT_HERSHEY_SIMPLEX

# Puntos de referencia de los ojos en la malla facial
LEFT_EYE = [362, 382, 381, 380, 374, 373, 390, 249, 263, 466, 388, 387, 386, 385, 384, 398]
RIGHT_EYE = [33, 7, 163, 144, 145, 153, 154, 155, 133, 173, 157, 158, 159, 160, 161, 246]

mediapipe_face_mesh = mediapipe.solutions.face_mesh
face_mesh = mediapipe_face_mesh.FaceMesh(max_num_faces=1, min_detection_confidence=0.6, min_tracking_confidence=0.7)

video_capture = cv2.VideoCapture(0)

def landmarksDetection(image, results):
    """Obtiene las coordenadas de los puntos de la cara sin dibujarlos."""
    image_height, image_width = image.shape[:2]
    return [(int(point.x * image_width), int(point.y * image_height)) for point in results.multi_face_landmarks[0].landmark]

# Distancia Euclidiana
def euclideanDistance(point, point1):
    x, y = point
    x1, y1 = point1
    return sqrt((x1 - x) ** 2 + (y1 - y) ** 2)

# Calcular el ratio de parpadeo
def blinkRatio(landmarks, right_indices, left_indices):
    right_eye_landmark1 = landmarks[right_indices[0]]
    right_eye_landmark2 = landmarks[right_indices[8]]

    right_eye_landmark3 = landmarks[right_indices[12]]
    right_eye_landmark4 = landmarks[right_indices[4]]

    left_eye_landmark1 = landmarks[left_indices[0]]
    left_eye_landmark2 = landmarks[left_indices[8]]

    left_eye_landmark3 = landmarks[left_indices[12]]
    left_eye_landmark4 = landmarks[left_indices[4]]

    right_eye_horizontal_distance = euclideanDistance(right_eye_landmark1, right_eye_landmark2)
    right_eye_vertical_distance = euclideanDistance(right_eye_landmark3, right_eye_landmark4)

    left_eye_vertical_distance = euclideanDistance(left_eye_landmark3, left_eye_landmark4)
    left_eye_horizontal_distance = euclideanDistance(left_eye_landmark1, left_eye_landmark2)

    return ((right_eye_horizontal_distance / right_eye_vertical_distance) +
            (left_eye_horizontal_distance / left_eye_vertical_distance)) / 2

while True:
    ret, frame = video_capture.read()
    frame = cv2.resize(frame, None, fx=1.5, fy=1.5, interpolation=cv2.INTER_CUBIC)
    frame_height, frame_width = frame.shape[:2]
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
    results = face_mesh.process(rgb_frame)

    if results.multi_face_landmarks:
        mesh_coordinates = landmarksDetection(frame, results)
        eyes_ratio = blinkRatio(mesh_coordinates, RIGHT_EYE, LEFT_EYE)

        cv2.putText(frame, "Por favor, pestaniea", (int(frame_height / 2), 100), FONT, 1, (0, 255, 0), 2)

        if eyes_ratio > 4:
            COUNTER += 1
        else:
            if COUNTER > 3:
                TOTAL_BLINKS += 1
                print(f"Pestanieo detectado: {TOTAL_BLINKS}")

                # Simular pulsación de tecla (Espacio)
                keyboard.press(" ")
                keyboard.release(" ")

                COUNTER = 0

        cv2.rectangle(frame, (20, 120), (290, 160), (0, 0, 0), -1)
        cv2.putText(frame, f'Pestanieos Totales: {TOTAL_BLINKS}', (30, 150), FONT, 1, (0, 255, 0), 2)

    cv2.imshow('Liveness Detection', frame)
    if cv2.waitKey(2) == 27:  # Tecla "ESC" para salir
        break

cv2.destroyAllWindows()
video_capture.release()

Paso 3: Obtener el juego:

Descarga desde GitHub:

Ahora obtendremos el juego desde GitHub el juego elegido es:

https://github.com/kubowania/chrome-trex-game.git

Pongo el enlace aquí del archivo comprimido para descargarlo desde github con este comando:

wget https://github.com/kubowania/chrome-trex-game/archive/refs/heads/master.zip
unzip master.zip

Se nos habrá creado una carpeta llamada chrome-trex-game-master ahí estará el documento index.html que contendrá el juego. Ábrelo con un navegador.

También puedes acceder al juego directamente alojado en github https://chrome-dino-game.github.io/

Paso 4: Ejecutar la aplicación

1. Ejecuta el script de python:

python3 parpadeo.py

Se abrirá una ventana mostrando la imagen de tu cámara y un contador que registrará los parpadeos al detectar un rostro.

Abre el juego del dinosaurio en tu navegador.

¡Empieza a jugar! Verás que, como por arte de magia, podrás controlar el juego sin tocar el teclado.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

3 + 2 =