From 37b3ef728bb10deb300e7f2f2b2e55de7dd6502d Mon Sep 17 00:00:00 2001 From: Arthur Santos Date: Tue, 27 Aug 2024 16:17:31 -0300 Subject: [PATCH] hello alice --- .gitignore | 9 +++ README.md | 0 docs/HELP.md | 11 ++++ docs/INSTALL.md | 3 + requirements.txt | 5 ++ sounds/kick.ogg | Bin 0 -> 11024 bytes sounds/snare.ogg | Bin 0 -> 9958 bytes src/entrypoint/cli.py | 45 ++++++++++++++ src/main.py | 12 ++++ src/modulos/debug.py | 90 ++++++++++++++++++++++++++++ src/modulos/segmentation.py | 30 ++++++++++ src/modulos/stream.py | 71 ++++++++++++++++++++++ src/sistema/fsm.py | 103 ++++++++++++++++++++++++++++++++ src/sistema/io.py | 27 +++++++++ src/sistema/landmark.py | 115 ++++++++++++++++++++++++++++++++++++ src/sistema/settings.py | 33 +++++++++++ src/sistema/sound.py | 37 ++++++++++++ src/sistema/video.py | 42 +++++++++++++ 18 files changed, 633 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docs/HELP.md create mode 100644 docs/INSTALL.md create mode 100644 requirements.txt create mode 100644 sounds/kick.ogg create mode 100644 sounds/snare.ogg create mode 100644 src/entrypoint/cli.py create mode 100644 src/main.py create mode 100644 src/modulos/debug.py create mode 100644 src/modulos/segmentation.py create mode 100644 src/modulos/stream.py create mode 100644 src/sistema/fsm.py create mode 100644 src/sistema/io.py create mode 100644 src/sistema/landmark.py create mode 100644 src/sistema/settings.py create mode 100644 src/sistema/sound.py create mode 100644 src/sistema/video.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e79221f --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +models/ +test/ + +.env/ +.git/ + +**/__pycache__/ + +*.wav diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/HELP.md b/docs/HELP.md new file mode 100644 index 0000000..6042412 --- /dev/null +++ b/docs/HELP.md @@ -0,0 +1,11 @@ +projeto_lab: python[3|3.10] src/main [--FLAG] + + Flags: + --debugging-video Abre o streaming de video. + --debugging-landmark Abre o streaming de video com reconhecimento de gestos. + --debugging-sound Abre o streaming de video e audio com Image2Sound. + --debugging-lab + --server Abre o debugging para server. + --client Abre o debugging para client. + Exemplo: + python3 src/main.py --video diff --git a/docs/INSTALL.md b/docs/INSTALL.md new file mode 100644 index 0000000..1e72bdc --- /dev/null +++ b/docs/INSTALL.md @@ -0,0 +1,3 @@ +* sudo apt install portaudio19-dev python3 python3-pip python3-dev +* pip install opencv-python mediapipe pyaudio synthesizer +* mkdir models/ && curl https://storage.googleapis.com/mediapipe-models/gesture_recognizer/gesture_recognizer/float16/latest/gesture_recognizer.task --output models/gesture_recognizer.task diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..aedac70 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +opencv-python +mediapipe +pyaudio +pygame +synthesizer diff --git a/sounds/kick.ogg b/sounds/kick.ogg new file mode 100644 index 0000000000000000000000000000000000000000..853790e8f4c10359d29ef1af690db3b6c267bb58 GIT binary patch literal 11024 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 XZh3I?9rGQkMe$OzKdl>#Ai@6v>BraY literal 0 HcmV?d00001 diff --git a/sounds/snare.ogg b/sounds/snare.ogg new file mode 100644 index 0000000000000000000000000000000000000000..94e1bda2ec2f109cce4b0cfbbbcb3f1ee3991cef GIT binary patch literal 9958 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 literal 0 HcmV?d00001 diff --git a/src/entrypoint/cli.py b/src/entrypoint/cli.py new file mode 100644 index 0000000..4e60c84 --- /dev/null +++ b/src/entrypoint/cli.py @@ -0,0 +1,45 @@ +import os +import time + +from sistema.io import IO +from sistema.settings import ( DOCS_PATH ) + +from modulos.debug import Debug +from modulos.stream import Stream + +class CLI(object): + + def __init__(self): + pass + + + def handler(self, flag): + + match flag: + case '--debugging-video': + Debug.debug_video() + + case '--debugging-landmark': + Debug.debug_landmark() + + case '--debugging-sound': + Debug.debug_sound() + + case '--debugging-lab': + Debug.debug_lab() + + case '--server': + Stream(is_server=True).server() + + case '--client': + Stream(is_server=False).client() + + case '--help': + self.help() + + case _: + print('Flag não encontrada. Use --help para visualizar todas as opções') + exit(0) + + def help(self): + print(IO.read_as_utf8(DOCS_PATH, 'HELP.md'), end='') diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..08e6eca --- /dev/null +++ b/src/main.py @@ -0,0 +1,12 @@ +import sistema.settings + +from entrypoint.cli import CLI +from sys import argv + +if __name__ == '__main__': + + if len(argv) != 2: + print('Entrada ruim. Utilize python[3|3.10] src/main.py --help') + exit(-1) + + CLI().handler(argv[1]) diff --git a/src/modulos/debug.py b/src/modulos/debug.py new file mode 100644 index 0000000..fcd6fd8 --- /dev/null +++ b/src/modulos/debug.py @@ -0,0 +1,90 @@ +from sistema.landmark import Landmark +from sistema.sound import Sound +from sistema.video import Video +from sistema.fsm import State + +import numpy as np +import cv2 as cv +import threading +import time + +class Debug(object): + + def debug_landmark(): + v = Video(is_client=True) + l = Landmark() + + while True: + frame = v.serialize() + frame = v.deserialize(frame) + + frame, _, _, _ = l.recognize(frame) + + cv.imshow('Debug', frame) + + if cv.waitKey(1) == ord('q'): + break + + v.close() + + + def debug_sound(): + v = Video(is_client=True) + s = Sound() + l = Landmark() + + _start = time.time() + while True: + frame = v.serialize() + frame = v.deserialize(frame) + + frame, x, y, z = l.recognize(frame) + + _end = time.time() + if _end - self._start > 0.4: + x = threading.Thread(target=s.play, args=(x, y, z, )) + x.start() + self._start = _end + cv.imshow('Debug', frame) + + if cv.waitKey(1) == ord('q'): + break + + s.close() + v.close() + + + def debug_video(): + v = Video(is_client=True) + + while True: + frame = v.serialize() + frame = v.deserialize(frame) + + cv.imshow('Debug', frame) + + if cv.waitKey(1) == ord('q'): + break + + v.close() + + + def debug_lab(): + v = Video(is_client=True) + l = Landmark() + s = State() + + while True: + frame = v.serialize() + frame = v.deserialize(frame) + + frame, gesture_name, position_x = l.read_gesture(frame) + + s.check((gesture_name, position_x)) + + cv.imshow('Debug', frame) + + if cv.waitKey(1) == ord('q'): + break + + v.close() diff --git a/src/modulos/segmentation.py b/src/modulos/segmentation.py new file mode 100644 index 0000000..439e0c0 --- /dev/null +++ b/src/modulos/segmentation.py @@ -0,0 +1,30 @@ +# TODO +import numpy as np +import cv2 as cv + +from sistema.video import Video + +class Segmentation(object): + + def __init__(self): + pass + + + def depth_color_map(self, frame): + return frame + + + def debug(self): + v = Video() + + while True: + frame = v.serialize() + + frame = self.depth_color_map(frame) + + cv.imshow('Debug', frame) + + if cv.waitKey(1) == ord('q'): + break + + v.close() diff --git a/src/modulos/stream.py b/src/modulos/stream.py new file mode 100644 index 0000000..dbc637b --- /dev/null +++ b/src/modulos/stream.py @@ -0,0 +1,71 @@ +import struct +import socket +import cv2 as cv + +from sistema.video import Video +from sistema.settings import ( HOST, PORT ) + + +class Stream(object): + + def __init__(self, is_server=False): + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + if is_server: + self.socket.bind((HOST, PORT)) + self.socket.listen() + else: + self.socket.connect((HOST, PORT)) + + + def server(self): + v = Video(is_client=False) + conn, addr = self.socket.accept() + + PAYLOAD_SIZE = struct.calcsize("Q") + + streaming_data = b'' + + while True: + + while len(streaming_data) < PAYLOAD_SIZE: + packet = conn.recv(4 * 1024) + if not packet: break + streaming_data += packet + + packed_msg_size = streaming_data[:PAYLOAD_SIZE] + streaming_data = streaming_data[PAYLOAD_SIZE:] + video_msg_size = struct.unpack("Q", packed_msg_size)[0] + + while len(streaming_data) < video_msg_size: + streaming_data += conn.recv(4 * 1024) + + serialized_frame = streaming_data[:video_msg_size] + streaming_data = streaming_data[video_msg_size:] + + frame = v.deserialize(serialized_frame) + cv.imshow("Stream", frame) + + if cv.waitKey(1) == ord('q'): + break + + v.close() + self.close() + + + def client(self): + v = Video(is_client=True) + + while(True): + serialized_frame = v.serialize() + serialized_frame = struct.pack("Q", len(serialized_frame)) \ + + serialized_frame + + self.socket.sendall(serialized_frame) + + v.close() + self.close() + + + def close(self): + self.socket.close() diff --git a/src/sistema/fsm.py b/src/sistema/fsm.py new file mode 100644 index 0000000..cce3cbe --- /dev/null +++ b/src/sistema/fsm.py @@ -0,0 +1,103 @@ +import os +import pygame +from sistema.settings import ( SOUNDS_PATH ) + +import threading +import time + +class State(object): + + def __init__(self): + self.STATES = [ + 'normal', + 'insert', + 'edit', + 'visual', + 'exit' + ] + self.init_state = 'normal' + self.curr_state = self.init_state + self.end_state = 'exit' + + self.gesture_name = None + self.enter_state = True + self.can_play_audio = True + self._start = time.time() + self.position_x = 0 + + + def check(self, package): + + self.gesture_name = package[0] + self.position_x = package[1] + + print(self.position_x) + + match self.curr_state: + case 'normal': + self.normal_state() + case 'insert': + self.insert_state() + case 'exit': + self.exit_state() + + + def set_state(self, new_state): + if new_state != self.curr_state: + self.enter_state = True + + self.curr_state = new_state + + + def normal_state(self): + if self.enter_state: + self.can_play_audio = True + self.enter_state = False + + self.set_state(self.check_normal()) + + def insert_state(self): + if self.enter_state: + _end = time.time() + if _end - self._start > 0.4: + x = threading.Thread(target=self.play) + x.start() + self.can_play_audio = False + self._start = _end + self.enter_state = False + + self.set_state(self.check_insert()) + + def exit_state(self): + exit(0) + + + def check_normal(self): + new_state = self.curr_state + if self.gesture_name == 'Closed_Fist': + new_state = 'insert' + if self.curr_state in ['normal', 'insert'] and self.gesture_name == 'Victory': + new_state = 'exit' + return new_state + + + def check_insert(self): + new_state = self.curr_state + if self.gesture_name in ['Open_Palm', 'Thumb_Up']: + new_state = 'normal' + + if self.curr_state in ['normal', 'insert'] and self.gesture_name == 'Victory': + new_state = 'exit' + return new_state + + + def play(self): + pygame.mixer.init() + pygame.mixer.music.load(os.path.join(SOUNDS_PATH, 'kick.ogg')) + if self.position_x > 0.5: + pygame.mixer.music.load(os.path.join(SOUNDS_PATH, 'snare.ogg')) + else: + pygame.mixer.music.load(os.path.join(SOUNDS_PATH, 'kick.ogg')) + pygame.mixer.music.play() + pygame.time.delay(1000) + pygame.mixer.music.stop() diff --git a/src/sistema/io.py b/src/sistema/io.py new file mode 100644 index 0000000..33da770 --- /dev/null +++ b/src/sistema/io.py @@ -0,0 +1,27 @@ +import os +import json + + +class IO(object): + + def read_as_json(filepath, filename) -> dict: + with open(os.path.join(filepath, filename), 'r', encoding='utf8') as f: + data = json.load(f) + return data + + + def read_as_utf8(filepath, filename) -> str: + with open(os.path.join(filepath, filename), 'r', encoding='utf8') as f: + data = f.read() + return data + + + def update(filepath, filename, data): + with open(os.path.join(filepath, filename), 'w', encoding='utf8') as f: + json.dump( + obj=data, + fp=f, + ensure_ascii=False, + indent='\t', + separators=(',', ': ') + ) diff --git a/src/sistema/landmark.py b/src/sistema/landmark.py new file mode 100644 index 0000000..5e92518 --- /dev/null +++ b/src/sistema/landmark.py @@ -0,0 +1,115 @@ +import os +import mediapipe as mp + +from mediapipe.tasks import python +from mediapipe.tasks.python import vision +from mediapipe.framework.formats import landmark_pb2 + +from sistema.settings import ( MODELS_PATH ) + +class Landmark(object): + + def __init__(self): + VisionRunningMode = mp.tasks.vision.RunningMode + + self.mp_hands = mp.solutions.hands + self.mp_drawing = mp.solutions.drawing_utils + self.mp_drawing_styles = mp.solutions.drawing_styles + + + self.base_options = python.BaseOptions( + model_asset_path = os.path.join(MODELS_PATH, 'gesture_recognizer.task') + ) + + self.options = vision.GestureRecognizerOptions( + base_options = self.base_options, + num_hands = 2 + # running_mode = VisionRunningMode.VIDEO + ) + + self.recognizer = vision.GestureRecognizer.create_from_options( + self.options + ) + + + def recognize(self, frame): + mp_frame = mp.Image( + image_format=mp.ImageFormat.SRGB, + data=frame + ) + + recognition_result = self.recognizer.recognize( + mp_frame + ) + + if len(recognition_result.gestures) == 0: + return frame, 0, 0, 0 + + gesture = recognition_result.gestures[0][0] + gesture_name = gesture.category_name + hand_landmarks = recognition_result.hand_landmarks + + test_x = 0 + test_y = 0.0 + + for hand_landmark in hand_landmarks: + hand_landmarks_proto = landmark_pb2.NormalizedLandmarkList() + hand_landmarks_proto.landmark.extend([ + landmark_pb2.NormalizedLandmark(x=landmark.x, y=landmark.y, z=landmark.z) for landmark in hand_landmark]) + + self.mp_drawing.draw_landmarks( + frame, + hand_landmarks_proto, + self.mp_hands.HAND_CONNECTIONS, + self.mp_drawing_styles.get_default_hand_landmarks_style(), + self.mp_drawing_styles.get_default_hand_connections_style() + ) + + return frame, hand_landmarks[0][8].x * 100, hand_landmarks[0][8].y * 100, hand_landmarks[0][8].z * 10 + + + def read_gesture(self, frame): + mp_frame = mp.Image( + image_format=mp.ImageFormat.SRGB, + data=frame + ) + + recognition_result = self.recognizer.recognize( + mp_frame + ) + + if len(recognition_result.gestures) == 0: + return frame, None, 0 + + gesture = recognition_result.gestures[0][0] + gesture_name = gesture.category_name + hand_landmarks = recognition_result.hand_landmarks + + print(gesture_name) + + for hand_landmark in hand_landmarks: + hand_landmarks_proto = landmark_pb2.NormalizedLandmarkList() + hand_landmarks_proto.landmark.extend( + [ + landmark_pb2.NormalizedLandmark( + x=landmark.x, + y=landmark.y, + z=landmark.z + ) + for landmark in hand_landmark + ] + ) + + self.mp_drawing.draw_landmarks( + frame, + hand_landmarks_proto, + self.mp_hands.HAND_CONNECTIONS, + self.mp_drawing_styles.get_default_hand_landmarks_style(), + self.mp_drawing_styles.get_default_hand_connections_style() + ) + + return frame, gesture_name, hand_landmarks[0][8].x + + + def serialize(self): + pass diff --git a/src/sistema/settings.py b/src/sistema/settings.py new file mode 100644 index 0000000..306337b --- /dev/null +++ b/src/sistema/settings.py @@ -0,0 +1,33 @@ +import os +from sys import path +from pathlib import Path +from platform import system + +BASE_PATH = Path(__file__).resolve().parent.parent.parent +SRC_PATH = Path(__file__).resolve().parent.parent + +path.append(str(SRC_PATH)) + +# \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +# GET SSH PUBKEY +SSH_PUBKEY = '' +if os.path.exists(f'{Path.home()}/.ssh/id_rsa.pub'): + with open(f'{Path.home()}/.ssh/id_rsa.pub', 'r') as f: + SSH_PUBKEY = f.read().replace('\n', '') +# ///////////////////////////////////////////////////////////////////////////// + +# \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +# ROOT FOLDERS PATH + +DOCS_PATH = os.path.join(BASE_PATH, 'docs') +MODELS_PATH = os.path.join(BASE_PATH, 'models') +SOUNDS_PATH = os.path.join(BASE_PATH, 'sounds') + +# ///////////////////////////////////////////////////////////////////////////// + +# \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ +# SERVER SETTINGS + +HOST = '127.0.0.1' +PORT = 65432 +# ///////////////////////////////////////////////////////////////////////////// diff --git a/src/sistema/sound.py b/src/sistema/sound.py new file mode 100644 index 0000000..e01e2f8 --- /dev/null +++ b/src/sistema/sound.py @@ -0,0 +1,37 @@ +import pyaudio +from synthesizer import Player, Synthesizer, Waveform + +import numpy as np +from types import NoneType + +CHORD_FREQUENCIES = [ + 32.7, + 36.7, + 41.2, + 43.7, + 49.0, + 55.0, + 61.7 +] + + +class Sound(object): + + def __init__(self): + self.player = Player() + self.player.open_stream() + + self.synthesizer = Synthesizer(osc1_waveform=Waveform.sawtooth, osc1_volume=0.1, use_osc2=False) + + def play(self, x, y, z) -> NoneType: + + player = Player() + player.open_stream() + synthesizer = Synthesizer(osc1_waveform=Waveform.square, osc1_volume=0.1, use_osc2=False) + chord_mapped = [CHORD_FREQUENCIES[int(x // (100 / 7))] * 2**int(y // (100 / 7))] + player.play_wave(synthesizer.generate_chord(chord_mapped, abs(z))) + player._pyaudio.terminate() + + + def close(self): + pass diff --git a/src/sistema/video.py b/src/sistema/video.py new file mode 100644 index 0000000..9a7370b --- /dev/null +++ b/src/sistema/video.py @@ -0,0 +1,42 @@ +import pickle +import cv2 as cv +import numpy as np + +from types import NoneType + +class Video(object): + + def __init__(self, is_client): + self.camera = cv.VideoCapture(0) + + self.WIDTH = 640 + self.HEIGHT = 360 + + if is_client: + #TODO: Resizible dimensions + #self.WIDTH = int(self.camera.get(cv.CAP_PROP_FRAME_WIDTH)) + #self.HEIGHT = int(self.camera.get(cv.CAP_PROP_FRAME_HEIGHT)) + + #self.WIDTH = 640 + #self.HEIGHT = 360 + + if not self.camera.isOpened(): + raise('Não foi possível abrir a câmera.') + + + def serialize(self) -> bytes: + ret, frame = self.camera.read() + + if not ret: + raise('Não foi possível receber o frame.') + + return pickle.dumps(frame) + + + def deserialize(self, serialized_ndarray) -> np.ndarray: + return pickle.loads(serialized_ndarray) + + + def close(self) -> NoneType: + self.camera.release() + cv.destroyAllWindows()