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. Los campos obligatorios están marcados con *

Click the images in this order: Libreta, Cartera, Ratón

Reloj Taza Tijeras Libreta Cartera Ratón