Bootstrap for windows

This commit is contained in:
cubernetes 2023-08-11 15:45:27 +02:00
parent f1638afb09
commit e31239f7aa
7 changed files with 131 additions and 324725 deletions

5
bootstrap.cmd Normal file
View File

@ -0,0 +1,5 @@
python3 -m venv env
.\env\bin\activate.bat
python3 -m pip install -r requirements.txt
echo Ready
pause

105
changes/utils.py Executable file
View File

@ -0,0 +1,105 @@
import sys
import time
from enum import Enum
from subprocess import Popen
from typing import Generator
from types import ModuleType
import numpy as np
import mediapipe as mp
import cv2
from cv2 import VideoCapture
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() -> Popen:
return
Popen(['paplay', './assets/sound/start.mp3']).communicate()
time.sleep(.5)
return Popen(['paplay', './assets/sound/background_music.mp3'])
def collect_sfx() -> None:
pass # Popen(['paplay', './assets/sound/collect.mp3'])
def lost_sfx() -> None:
pass # Popen(['paplay', './assets/sound/lost.mp3']).communicate()
def show_matrix() -> None:
pass # Popen(['cmatrix'])
def initiate_rick() -> None:
return
Popen(['paplay', './assets/sound/rick.mp3'])
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: 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)

11
game.py
View File

@ -22,8 +22,6 @@ def get_42_img(
if len(img.shape) in [1, 2]:
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
img = cv2.flip(img, 1)
img_height, img_width = img.shape[:2]
img = img[
margin_top:img_height-margin_bottom,
@ -70,7 +68,7 @@ def add_directional_triangle(
# normalize
norm = np.linalg.norm(dir_vector)
dir_vector /= norm
dir_vector /= (norm or 1)
# TODO: Fix type issue
side_len *= norm / 15
@ -96,6 +94,8 @@ def show_frame(frame: np.ndarray, to_stdout: bool=False) -> None:
if to_stdout:
sys.stdout.buffer.write(frame.tobytes())
else:
cv2.namedWindow("Image", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("Image", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
cv2.imshow("Image", frame)
cv2.waitKey(1)
@ -103,7 +103,7 @@ def main() -> int:
music = start_game_sfx()
capture: cv2.VideoCapture = cv2.VideoCapture(0)
hands: mp.solutions.hands.Hands = mp_hands.Hands(max_num_hands=1)
hands: mp.solutions.hands.Hands = mp_hands.Hands(max_num_hands=2)
collected_42: bool = True
noise_42img: int = 5
img42_x: int = -img42_side_len - 1 - noise_42img
@ -114,7 +114,7 @@ def main() -> int:
finger_y: int = -1
no_collect_ratio = 0
no_finger_ratio = 0
timer = 100
timer = 1000
i: int = 0
while True:
@ -124,6 +124,7 @@ def main() -> int:
if not success:
continue
frame = cv2.flip(frame, 1)
ratio = max(no_finger_ratio, no_collect_ratio)
frame = cv2.addWeighted(frame, 1 - ratio, np.ones(frame.shape, dtype=frame.dtype), ratio, 0)
if i > 30:

324708
libcaca/a

File diff suppressed because one or more lines are too long

View File

@ -13,6 +13,7 @@ opencv-contrib-python==4.8.0.76
opencv-python==4.8.0.76
packaging==23.1
Pillow==10.0.0
playsound==1.3.0
protobuf==3.20.3
pycparser==2.21
pyparsing==3.0.9

View File

@ -1,7 +1,7 @@
#!/bin/sh
# st -f 'SauceCodePro Nerd Font Mono:size=10' -e sh -c '{ ./game.py | 2>/dev/null ffmpeg -y -f rawvideo -s 640x480 -pix_fmt bgr24 -i - -map 0:V:0 -filter:v "format=gray,hflip" -c:v libx265 -preset ultrafast -tune zerolatency -crf 30 -f nut - | TERM=xterm-mono CACA_DRIVER=ncurses DISPLAY= mpv --really-quiet --no-cache --no-config --vo=caca --untimed --profile=low-latency - || { echo Error 1>&2; read X; }; } | ./game.py'
# st -f 'SauceCodePro Nerd Font Mono:size=10' -e sh -c '{ ./game.py | 2>/dev/null ffmpeg -y -f rawvideo -s 640x480 -pix_fmt bgr24 -i - -map 0:V:0 -filter:v "format=gray,hflip" -c:v libx265 -preset ultrafast -tune zerolatency -crf 30 -f nut - | TERM=xterm-mono CACA_DRIVER=ncurses DISPLAY= mpv --really-quiet --no-cache --no-config --vo=caca --untimed --profile=low-latency - || { echo Error 1>&2; read X; }; }'
# st -f 'SauceCodePro Nerd Font Mono:size=10' -e sh -c '{ ./game.py | 2>/dev/null ffmpeg -y -f rawvideo -s 640x480 -pix_fmt bgr24 -i - -map 0:V:0 -filter:v "format=gray,hflip" -c:v libx264 -preset ultrafast -tune zerolatency -crf 30 -f nut - | TERM=xterm-mono CACA_DRIVER=ncurses DISPLAY= mpv --really-quiet --no-cache --no-config --vo=tct --untimed --profile=low-latency - || { echo Error 1>&2; read X; }; }'
# st -f 'SauceCodePro Nerd Font Mono:size=10' -e sh -c '{ ./game.py | 2>/dev/null ffmpeg -y -f rawvideo -s 640x480 -pix_fmt bgr24 -i - -map 0:V:0 -filter:v "format=gray" -c:v libx265 -preset ultrafast -tune zerolatency -crf 30 -f nut - | TERM=xterm-mono CACA_DRIVER=ncurses DISPLAY= mpv --really-quiet --no-cache --no-config --vo=caca --untimed --profile=low-latency - || { echo Error 1>&2; read X; }; } | ./game.py'
# st -f 'SauceCodePro Nerd Font Mono:size=10' -e sh -c '{ ./game.py | 2>/dev/null ffmpeg -y -f rawvideo -s 640x480 -pix_fmt bgr24 -i - -map 0:V:0 -filter:v "format=gray" -c:v libx265 -preset ultrafast -tune zerolatency -crf 30 -f nut - | TERM=xterm-mono CACA_DRIVER=ncurses DISPLAY= mpv --really-quiet --no-cache --no-config --vo=caca --untimed --profile=low-latency - || { echo Error 1>&2; read X; }; }'
# st -f 'SauceCodePro Nerd Font Mono:size=10' -e sh -c '{ ./game.py | 2>/dev/null ffmpeg -y -f rawvideo -s 640x480 -pix_fmt bgr24 -i - -map 0:V:0 -filter:v "format=gray" -c:v libx264 -preset ultrafast -tune zerolatency -crf 30 -f nut - | TERM=xterm-mono CACA_DRIVER=ncurses DISPLAY= mpv --really-quiet --no-cache --no-config --vo=tct --untimed --profile=low-latency - || { echo Error 1>&2; read X; }; }'
TERM_FONT='SauceCodePro Nerd Font Mono'
TERM_FONT_SIZE='10'
@ -21,7 +21,7 @@ xterm \
-pix_fmt bgr24 \
-i - \
-map 0:V:0 \
-filter:v "format=gray,hflip" \
-filter:v "format=gray" \
-c:v libx265 \
-preset ultrafast \
-tune zerolatency \

View File

@ -4,11 +4,12 @@ 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 cv2 import VideoCapture
from playsound import playsound
mp_hands = mp.solutions.hands
mp_draw: ModuleType = mp.solutions.drawing_utils
@ -40,22 +41,23 @@ def save_score(score: int) -> None:
with open('./.score', 'w') as score_file:
score_file.write(str(score))
def start_game_sfx() -> Popen:
Popen(['paplay', './assets/sound/start.mp3']).communicate()
def start_game_sfx() -> None:
playsound('./assets/sound/start.mp3')
time.sleep(.5)
return Popen(['paplay', './assets/sound/background_music.mp3'])
threading.Thread(target=playsound, args=('./assets/sound/background_music.mp3',), daemon=True).start()
def collect_sfx() -> None:
Popen(['paplay', './assets/sound/collect.mp3'])
pass
threading.Thread(target=playsound, args=('./assets/sound/collect.mp3',), daemon=True).start()
def lost_sfx() -> None:
Popen(['paplay', './assets/sound/lost.mp3']).communicate()
playsound('./assets/sound/lost.mp3')
def show_matrix() -> None:
Popen(['tmatrix'])
def initiate_rick() -> None:
Popen(['paplay', './assets/sound/rick.mp3'])
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
@ -73,7 +75,7 @@ def initiate_rick() -> None:
def found_hands() -> bool:
capture: VideoCapture = cv2.VideoCapture(0)
capture: cv2.VideoCapture = cv2.VideoCapture(0)
hands = mp_hands.Hands(max_num_hands=1)
success, frame = capture.read()
if not success: