import sys import time from enum import Enum from subprocess import Popen from typing import Generator from types import ModuleType import threading import numpy as np import mediapipe as mp import cv2 from playsound import playsound mp_hands = mp.solutions.hands mp_draw: ModuleType = mp.solutions.drawing_utils class FingerType(Enum): BASE = 0 BASE_RIGHT = 1 THUMB_BASE = 2 THUMB_KNUCKLE_1 = 3 THUMB_TIP = 4 INDEX_BASE = 5 INDEX_KNUCKLE_1 = 6 INDEX_KNUCKLE_2 = 7 INDEX_TIP = 8 MIDDLE_BASE = 9 MIDDLE_KNUCKLE_1 = 10 MIDDLE_KNUCKLE_2 = 11 MIDDLE_TIP = 12 RING_BASE = 13 RING_KNUCKLE_1 = 14 RING_KNUCKLE_2 = 15 RING_TIP = 16 PINKY_BASE = 17 PINKY_KNUCKLE_1 = 18 PINKY_KNUCKLE_2 = 19 PINKY_TIP = 20 def save_score(score: int) -> None: with open('./.score', 'w') as score_file: score_file.write(str(score)) def start_game_sfx() -> None: playsound('./assets/sound/start.mp3') time.sleep(.5) threading.Thread(target=playsound, args=('./assets/sound/background_music.mp3',), daemon=True).start() def collect_sfx() -> None: pass threading.Thread(target=playsound, args=('./assets/sound/collect.mp3',), daemon=True).start() def lost_sfx() -> None: playsound('./assets/sound/lost.mp3') def show_matrix() -> None: Popen(['tmatrix']) def initiate_rick() -> None: threading.Thread(target=playsound, args=('./assets/sound/rick.mp3',), daemon=True).start() cap = cv2.VideoCapture('./assets/video/rick2.mp4') fps: int = int(cap.get(cv2.CAP_PROP_FPS)) desired_delay: float = 1 / fps while True: start_time = time.time() ret, frame = cap.read() if not ret: break sys.stdout.buffer.write(frame.tobytes()) elapsed_time = time.time() - start_time remaining_delay = max(desired_delay - elapsed_time, 0) time.sleep(remaining_delay) cap.release() def found_hands() -> bool: capture: cv2.VideoCapture = cv2.VideoCapture(0) hands = mp_hands.Hands(max_num_hands=1) success, frame = capture.read() if not success: return False return list(get_finger_positions(frame, hands)) != [] def get_finger_positions( frame: np.ndarray, hands: mp.solutions.hands.Hands, add_landmarks: bool=False, ) -> Generator[list[tuple[int, int, int]], None, None]: height, width = frame.shape[:2] img_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results = hands.process(img_rgb) if results.multi_hand_landmarks: for hand_landmarks in results.multi_hand_landmarks: positions = [] for id, lm in enumerate(hand_landmarks.landmark): x = int(lm.x * width) y = int(lm.y * height) positions.append((FingerType(id), x, y)) yield positions if add_landmarks: mp_draw.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)