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]: if len(img.shape) in [1, 2]:
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
img = cv2.flip(img, 1)
img_height, img_width = img.shape[:2] img_height, img_width = img.shape[:2]
img = img[ img = img[
margin_top:img_height-margin_bottom, margin_top:img_height-margin_bottom,
@ -70,7 +68,7 @@ def add_directional_triangle(
# normalize # normalize
norm = np.linalg.norm(dir_vector) norm = np.linalg.norm(dir_vector)
dir_vector /= norm dir_vector /= (norm or 1)
# TODO: Fix type issue # TODO: Fix type issue
side_len *= norm / 15 side_len *= norm / 15
@ -96,6 +94,8 @@ def show_frame(frame: np.ndarray, to_stdout: bool=False) -> None:
if to_stdout: if to_stdout:
sys.stdout.buffer.write(frame.tobytes()) sys.stdout.buffer.write(frame.tobytes())
else: else:
cv2.namedWindow("Image", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("Image", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
cv2.imshow("Image", frame) cv2.imshow("Image", frame)
cv2.waitKey(1) cv2.waitKey(1)
@ -103,7 +103,7 @@ def main() -> int:
music = start_game_sfx() music = start_game_sfx()
capture: cv2.VideoCapture = cv2.VideoCapture(0) 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 collected_42: bool = True
noise_42img: int = 5 noise_42img: int = 5
img42_x: int = -img42_side_len - 1 - noise_42img img42_x: int = -img42_side_len - 1 - noise_42img
@ -114,7 +114,7 @@ def main() -> int:
finger_y: int = -1 finger_y: int = -1
no_collect_ratio = 0 no_collect_ratio = 0
no_finger_ratio = 0 no_finger_ratio = 0
timer = 100 timer = 1000
i: int = 0 i: int = 0
while True: while True:
@ -124,6 +124,7 @@ def main() -> int:
if not success: if not success:
continue continue
frame = cv2.flip(frame, 1)
ratio = max(no_finger_ratio, no_collect_ratio) ratio = max(no_finger_ratio, no_collect_ratio)
frame = cv2.addWeighted(frame, 1 - ratio, np.ones(frame.shape, dtype=frame.dtype), ratio, 0) frame = cv2.addWeighted(frame, 1 - ratio, np.ones(frame.shape, dtype=frame.dtype), ratio, 0)
if i > 30: 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 opencv-python==4.8.0.76
packaging==23.1 packaging==23.1
Pillow==10.0.0 Pillow==10.0.0
playsound==1.3.0
protobuf==3.20.3 protobuf==3.20.3
pycparser==2.21 pycparser==2.21
pyparsing==3.0.9 pyparsing==3.0.9

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/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" -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" -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 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='SauceCodePro Nerd Font Mono'
TERM_FONT_SIZE='10' TERM_FONT_SIZE='10'
@ -21,7 +21,7 @@ xterm \
-pix_fmt bgr24 \ -pix_fmt bgr24 \
-i - \ -i - \
-map 0:V:0 \ -map 0:V:0 \
-filter:v "format=gray,hflip" \ -filter:v "format=gray" \
-c:v libx265 \ -c:v libx265 \
-preset ultrafast \ -preset ultrafast \
-tune zerolatency \ -tune zerolatency \

View File

@ -4,11 +4,12 @@ from enum import Enum
from subprocess import Popen from subprocess import Popen
from typing import Generator from typing import Generator
from types import ModuleType from types import ModuleType
import threading
import numpy as np import numpy as np
import mediapipe as mp import mediapipe as mp
import cv2 import cv2
from cv2 import VideoCapture from playsound import playsound
mp_hands = mp.solutions.hands mp_hands = mp.solutions.hands
mp_draw: ModuleType = mp.solutions.drawing_utils mp_draw: ModuleType = mp.solutions.drawing_utils
@ -40,22 +41,23 @@ def save_score(score: int) -> None:
with open('./.score', 'w') as score_file: with open('./.score', 'w') as score_file:
score_file.write(str(score)) score_file.write(str(score))
def start_game_sfx() -> Popen: def start_game_sfx() -> None:
Popen(['paplay', './assets/sound/start.mp3']).communicate() playsound('./assets/sound/start.mp3')
time.sleep(.5) 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: 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: def lost_sfx() -> None:
Popen(['paplay', './assets/sound/lost.mp3']).communicate() playsound('./assets/sound/lost.mp3')
def show_matrix() -> None: def show_matrix() -> None:
Popen(['tmatrix']) Popen(['tmatrix'])
def initiate_rick() -> None: 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') cap = cv2.VideoCapture('./assets/video/rick2.mp4')
fps: int = int(cap.get(cv2.CAP_PROP_FPS)) fps: int = int(cap.get(cv2.CAP_PROP_FPS))
desired_delay: float = 1 / fps desired_delay: float = 1 / fps
@ -73,7 +75,7 @@ def initiate_rick() -> None:
def found_hands() -> bool: def found_hands() -> bool:
capture: VideoCapture = cv2.VideoCapture(0) capture: cv2.VideoCapture = cv2.VideoCapture(0)
hands = mp_hands.Hands(max_num_hands=1) hands = mp_hands.Hands(max_num_hands=1)
success, frame = capture.read() success, frame = capture.read()
if not success: if not success: