Skip to content

Commit

Permalink
Version 1.1.0
Browse files Browse the repository at this point in the history
* WindowService and Some improvements

* Hand Tracking Example and Some improvements

* Delete .DS_Store
  • Loading branch information
xavi-burgos99 authored Sep 29, 2024
1 parent 7e397a4 commit caeda2a
Show file tree
Hide file tree
Showing 14 changed files with 803 additions and 74 deletions.
Binary file removed .DS_Store
Binary file not shown.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,6 @@ cython_debug/

# PyCharm
.idea/

# MacOS
.DS_Store
281 changes: 224 additions & 57 deletions README.md

Large diffs are not rendered by default.

4 changes: 1 addition & 3 deletions examples/camera_timer/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import time

from eymos.services import CameraService
from eymos.service_manager import ServiceManager
from eymos.services.camera import CameraService
from services.camera_timer import CameraTimerService


Expand Down
3 changes: 0 additions & 3 deletions examples/camera_timer/services/camera_timer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import cv2
from PIL import Image

from eymos import Service, log
from eymos.services import FrameType

Expand Down
10 changes: 10 additions & 0 deletions examples/hand_tracking/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"timer": {
"max_time": 300
},
"hand_tracking": {
"model_complexity": 0,
"min_detection_confidence": 0.5,
"min_tracking_confidence": 0.5
}
}
19 changes: 19 additions & 0 deletions examples/hand_tracking/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from eymos import ServiceManager, log
from eymos.services import CameraService, WindowService
from services.hand_tracking import HandTrackingService


# Initialize the service manager
manager = ServiceManager()

# Add the services to the manager
camera = manager.add("camera", CameraService)
window = manager.add("window", WindowService)
hand_tracking = manager.add("hand_tracking", HandTrackingService)

# Start the services
manager.start()

# Start the window main loop
log("Starting tkinter main loop...")
window.mainloop()
61 changes: 61 additions & 0 deletions examples/hand_tracking/services/hand_tracking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import cv2
import mediapipe as mp
from eymos import Service


class HandTrackingService(Service):
def init(self):
"""Initialize the service."""
# Setting up initial attributes
self._loop_delay = 0.04 # Delay between each loop
self.__hand_detector = None # Placeholder for the hand detection model
self.__model_complexity = self._config.get('model_complexity', 0) # Simplified hand model for real-time
self.__min_detection_confidence = self._config.get('min_detection_confidence', 0.5) # Minimum confidence to detect hands
self.__min_tracking_confidence = self._config.get('min_tracking_confidence', 0.5) # Minimum confidence to track hands

def destroy(self):
"""Clean up resources before stopping the service."""
if self.__hand_detector:
self.__hand_detector.close() # Clean up MediaPipe hand detector
self._hand_detector = None
self._model_complexity = None
self._min_detection_confidence = None
self._min_tracking_confidence = None

def before(self):
"""Prepare anything that needs to be initialized outside the main thread."""
self.__hand_detector = mp.solutions.hands.Hands(
model_complexity=self.__model_complexity,
min_detection_confidence=self.__min_detection_confidence,
min_tracking_confidence=self.__min_tracking_confidence
)

def loop(self):
"""Main loop where the hand detection logic will run."""
# Get the CameraService from the service manager
camera_service = self._services.get('camera')
if camera_service is None:
return

# Get the latest frame from CameraService
frame = camera_service.get_frame()
if frame is None:
return

# Convert the frame from BGR to RGB as required by MediaPipe
image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

# Process the frame to detect hands
results = self.__hand_detector.process(image_rgb)

# If hands are detected, draw landmarks on the frame
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp.solutions.drawing_utils.draw_landmarks(
frame, hand_landmarks, mp.solutions.hands.HAND_CONNECTIONS
)

# Display the processed frame in WindowService
window_service = self._services.get('window')
if window_service:
window_service.draw(frame)
1 change: 0 additions & 1 deletion examples/timer/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import time

from eymos.service_manager import ServiceManager
from services.timer import TimerService

Expand Down
58 changes: 53 additions & 5 deletions eymos/service_manager.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import os
import sys
import json
import logging
import warnings
import platform
from pynput import keyboard

from .logger import LoggerManager, log
from .service import Service
Expand All @@ -21,12 +24,31 @@ def __init__(self, config=None, services=None):
if services is None:
services = {}

# Service manager information
self._config = None
# Set the services
self._services = services

# Set the configuration
self.set_config(config)
self._config = self.set_config(config)

# Initialize stop queue
self.stop_queue = []

# Listen if the escape key is pressed
if self._config['escape']:
listener = keyboard.Listener(on_press=self.__on_press)
listener.start()

# Hide logs
logging.getLogger('tensorflow').setLevel(logging.ERROR)
logging.getLogger('absl').setLevel(logging.ERROR)
logging.getLogger('cv2').setLevel(logging.ERROR)
logging.getLogger('PIL').setLevel(logging.ERROR)
logging.getLogger('matplotlib').setLevel(logging.ERROR)
logging.getLogger('urllib3').setLevel(logging.ERROR)
logging.getLogger('requests').setLevel(logging.ERROR)

# Hide warnings
warnings.filterwarnings("ignore", category=UserWarning)

def add(self, name: str, service: type[Service]):
"""Add a service to the manager.
Expand Down Expand Up @@ -95,6 +117,22 @@ def stop(self):
for name in self._services:
self._services[name].stop()

# Call the stop queue
for callback in self.stop_queue:

# Call the callback
callback()

# Clear the stop queue
self.stop_queue.clear()

def on_stop(self, callback: callable):
"""Add a callback to call when the services are stopped.
Args:
callback (callable): The callback to call.
"""
self.stop_queue.append(callback)

def restart(self):
"""Restart all services (in order)."""
# Stop all services
Expand Down Expand Up @@ -126,7 +164,7 @@ def exit(self):

# Exit the system
log('Exiting the system...')
exit()
sys.exit()

def set_config(self, config: dict):
"""Load the configuration.
Expand All @@ -148,6 +186,8 @@ def set_config(self, config: dict):
config['logging']['format'] = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
if ('enable' not in config['logging']) or (type(config['logging']['enable']) is not bool):
config['logging']['enable'] = True
if ('escape' not in config) or (type(config['escape']) is not bool):
config['escape'] = True

# Set the configuration
self._config = config
Expand All @@ -174,6 +214,14 @@ def set_config_file(self, file: str):
# Set the configuration
return self.set_config(config)

def __on_press(self, key):
"""Listen if the escape key is pressed.
Args:
key (keyboard.Key): The key pressed.
"""
if key == keyboard.Key.esc:
self.exit()

def __update_logging(self):
"""Update the logging configuration."""
# Disable logging in LoggingManager
Expand All @@ -182,4 +230,4 @@ def __update_logging(self):
return

# Enable logging in LoggingManager
LoggerManager.enable(self._config['logging']['level'], self._config['logging']['format'])
LoggerManager.enable(self._config['logging']['level'], self._config['logging']['format'])
3 changes: 2 additions & 1 deletion eymos/services/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# eymos/services/__init__.py

from .camera import CameraService, FrameType
from .window import WindowService, ImageSize

__all__ = ['CameraService', 'FrameType']
__all__ = ['CameraService', 'FrameType', 'WindowService', 'ImageSize']
6 changes: 3 additions & 3 deletions eymos/services/camera.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import base64
import cv2
import base64
from PIL import Image
from eymos.service import Service

Expand All @@ -13,8 +13,8 @@ class FrameType:


class CameraService(Service):
DEFAULT_FPS = 10
DEFAULT_RESOLUTION = [512, 288]
DEFAULT_FPS = 25
DEFAULT_RESOLUTION = [640, 480]

def __init__(self, name: str, config: dict, services: dict):
"""Initialize the service.
Expand Down
Loading

0 comments on commit caeda2a

Please sign in to comment.