Skip to content

Commit 51043b5

Browse files
authored
Merge pull request #5 from asterics/change-shortcuts
Change shortcuts
2 parents d3b8f15 + 622b015 commit 51043b5

File tree

6 files changed

+132
-57
lines changed

6 files changed

+132
-57
lines changed

Demo.py

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ def __init__(self):
6262
super().__init__()
6363
self.is_running = False
6464
self.is_tracking = False
65-
self.mouse_enabled = False
6665
self.mouse_absolute = True
6766
self.mouse: Mouse.Mouse = Mouse.Mouse()
6867

@@ -115,7 +114,13 @@ def __init__(self):
115114
# add hotkey
116115
# TODO: how to handle activate mouse / toggle mouse etc. by global hotkey
117116
# keyboard.add_hotkey("esc", lambda: self.stop())
117+
# alt + 1: toggle gestures + mouse movement
118+
# alt + g: toggle gestures (keyboard and mouse)
119+
# alt + m: toggle mouse movement
118120
keyboard.add_hotkey("alt + 1", lambda: self.toggle_gesture_mouse()) # TODO: Linux alternative
121+
keyboard.add_hotkey("alt + g", lambda: self.toggle_gestures())
122+
keyboard.add_hotkey("alt + m", lambda: self.toggle_mouse_movement())
123+
keyboard.add_hotkey("alt + t", lambda: self.toggle_tracking())
119124
keyboard.add_hotkey("m", lambda: self.toggle_mouse_mode())
120125
keyboard.add_hotkey("c", lambda: self.mouse.centre_mouse())
121126
keyboard.add_hotkey(".", lambda: self.mouse.switch_monitor())
@@ -219,7 +224,7 @@ def __run_livelinkface(self):
219224

220225
if self.write_csv:
221226
self.csv_writer.writerow(row)
222-
if self.mouse_enabled:
227+
if self.mouse.mouse_movement_enabled:
223228
self.mouse.process_signal(self.signals)
224229

225230
def __start_camera(self):
@@ -306,6 +311,12 @@ def __csv_recording(self):
306311
self.mediapipe_csv_writer.writerow(mp_row)
307312
self.iphone_csv_writer.writerow(ip_row)
308313

314+
def toggle_tracking(self):
315+
print("toggle tracking..")
316+
if self.is_tracking:
317+
self.stop_tracking()
318+
else:
319+
self.start_tracking()
309320
def stop_tracking(self):
310321
print("Stopping tracking..")
311322
self.is_tracking = False
@@ -332,24 +343,59 @@ def update_webcam_video_file_selection(self, vid_source_file):
332343
print(f"Setting camera with video file {vid_source_file}")
333344
self.vid_source_file = vid_source_file
334345

335-
def disable_gesture_mouse(self):
346+
def toggle_gestures(self):
347+
if self.mouse.mouse_gesture_enabled:
348+
self.disable_gestures()
349+
else:
350+
self.enable_gestures()
351+
352+
"""
353+
Disables alls configured gestures (mouse and keyboard).
354+
"""
355+
def disable_gestures(self):
356+
print("disabling gestures")
336357
# Disables gesture mouse and enables normal mouse input
337358
for signal in self.signals.values():
338359
signal.set_actions_active(False)
339-
self.mouse_enabled = False
340-
self.mouse.disable_gesture()
360+
self.mouse.disable_gestures()
361+
362+
"""
363+
Disables all gestures and mouse movement.
364+
"""
365+
def disable_gesture_mouse(self):
366+
self.disable_mouse_movement()
367+
self.disable_gestures()
368+
369+
"""
370+
Enables all gestures (mouse and keyboard)
371+
"""
372+
def enable_gestures(self):
373+
print("enabling gestures")
374+
for signal in self.signals.values():
375+
signal.set_actions_active(True)
376+
377+
self.mouse.enable_gestures()
341378

379+
"""
380+
Enables all gestures and the mouse.
381+
"""
342382
def enable_gesture_mouse(self):
343383
# Enables gesture mouse and enables normal mouse input
384+
self.enable_mouse_movement()
385+
self.enable_gestures()
344386

345-
for signal in self.signals.values():
346-
signal.set_actions_active(True)
347-
self.mouse_enabled = True
348-
self.mouse.enable_gesture()
387+
def enable_mouse_movement(self):
388+
self.mouse.enable_mouse_movement()
389+
def disable_mouse_movement(self):
390+
self.mouse.disable_mouse_movement()
391+
392+
def toggle_mouse_movement(self):
393+
self.mouse.toggle_mouse_movement()
349394

350395
def toggle_gesture_mouse(self):
396+
print("toggling mouse and gestures")
351397
# Toggles between gesture and normal mouse
352-
if self.mouse_enabled:
398+
if self.mouse.mouse_movement_enabled:
353399
self.disable_gesture_mouse()
354400
else:
355401
self.enable_gesture_mouse()

Mouse.py

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ def __init__(self):
8080

8181
# Tracking Mode
8282
self.tracking_mode = TrackingMode.MEDIAPIPE
83-
# To disable mouse
84-
self.mouse_enabled = True
83+
# To toggle mouse movement
84+
self.mouse_movement_enabled = True
8585
self.is_dragging = False
8686
self.precision_mode = False
8787

@@ -90,6 +90,10 @@ def __init__(self):
9090
self.kalman_filter = Kalman1D(sz=100, R=self.filter_value ** 2)
9191
self.filter_mouse_position = True
9292

93+
# Gestures
94+
# To toggle mouse gestures
95+
self.mouse_gesture_enabled = True
96+
9397
def move(self, pitch: float, yaw: float):
9498
if self.mode == MouseMode.ABSOLUTE:
9599
# x_new = self.w_pixels * 2 * (yaw - 0.25) + self.monitor_x_offset
@@ -207,51 +211,67 @@ def process_signal(self, signals):
207211

208212
pitch = signals[upDown].scaled_value
209213
yaw = signals[leftRight].scaled_value
210-
if self.mouse_enabled:
214+
if self.mouse_movement_enabled:
211215
self.move(pitch, yaw)
212216
else:
213217
self.dx = 0
214218
self.dy = 0
215219
self.pitch = pitch
216220
self.yaw = yaw
217221

218-
def enable_gesture(self):
219-
self.mouse_enabled = True
222+
def enable_gestures(self):
223+
self.mouse_gesture_enabled = True
224+
225+
def disable_gestures(self):
226+
self.mouse_gesture_enabled = False
227+
228+
def toggle_gestures(self):
229+
self.mouse_gesture_enabled = not self.mouse_gesture_enabled
220230

221231
def click(self, button):
222232
"""
223233
Clicks the mouse button specified with button.
224234
:param button: str, one of the buttons to click
225235
:return:
226236
"""
227-
self.mouse_controller.click(button)
237+
if self.mouse_gesture_enabled:
238+
self.mouse_controller.click(button)
228239

229240
def double_click(self, button):
230241
"""
231242
Double-clicks the mouse button specified with button.
232243
:param button: str, one of the buttons to click
233244
:return:
234245
"""
235-
self.mouse_controller.click(button, 2)
246+
if self.mouse_gesture_enabled:
247+
self.mouse_controller.click(button, 2)
236248

237249
def drag_drop(self):
238-
if self.is_dragging:
239-
self.mouse_controller.release(mouse.Button.left)
240-
self.is_dragging = False
250+
if self.mouse_gesture_enabled:
251+
if self.is_dragging:
252+
self.mouse_controller.release(mouse.Button.left)
253+
self.is_dragging = False
254+
else:
255+
self.mouse_controller.press(mouse.Button.left)
256+
self.is_dragging = True
257+
print(self.is_dragging)
258+
259+
def toggle_mouse_movement(self):
260+
if self.mouse_movement_enabled:
261+
self.disable_mouse_movement()
241262
else:
242-
self.mouse_controller.press(mouse.Button.left)
243-
self.is_dragging = True
244-
print(self.is_dragging)
245-
246-
def disable_gesture(self):
247-
self.mouse_enabled = False
263+
self.enable_mouse_movement()
264+
def enable_mouse_movement(self):
265+
print("enable mouse movement")
266+
self.mouse_movement_enabled = True
248267

249-
def toggle_active(self):
250-
self.mouse_enabled = not self.mouse_enabled
268+
def disable_mouse_movement(self):
269+
print("disable mouse movement")
270+
self.mouse_movement_enabled = False
251271

252272
def toggle_mode(self):
253273
self.mode = self.mode.next()
254-
print(f"Mouse mode is {self.tracking_mode.name}")
274+
print(f"Mouse mode is {self.mode.name}")
255275

256276
def set_mouse_mode(self, mode: str):
257277
try:
@@ -272,12 +292,14 @@ def centre_mouse(self):
272292
self.in_finezone = False
273293

274294
def switch_monitor(self):
295+
print("switch monitor")
275296
self.monitor_index = (self.monitor_index + 1) % len(self.monitors_list)
276297
screen = self.monitors_list[self.monitor_index]
277298
self.h_pixels = screen.height
278299
self.w_pixels = screen.width
279300
self.monitor_x_offset = screen.x
280301
self.monitor_y_offset = screen.y
302+
print(f"screen {screen}, h_pixels{self.h_pixels}, x_offset {self.monitor_x_offset}")
281303

282304

283305
def set_x_sensitivity(self, value: float):
@@ -371,7 +393,7 @@ def toggle_tracking_mode(self):
371393
mouse.set_filter_enabled(False)
372394
mouse.set_mouse_mode(MouseMode.ABSOLUTE.name)
373395
mouse.set_tracking_mode(TrackingMode.NOSE.name)
374-
mouse.enable_gesture()
396+
mouse.enable_gestures()
375397

376398
for i in range(1000):
377399
time.sleep(0.01)

README.md

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,50 @@
11
# Gesture Mouse
22

33
A library that allows to control the mouse and keyboard with head movement and face gestures. This project is based on the
4-
google mediapipe library (https://google.github.io/mediapipe/).
4+
google mediapipe library (https://ai.google.dev/edge/mediapipe/solutions/guide).
55

66
## Installation instructions
77
Tested with Python 3.10 and PySide6.4.3.
88
1. Clone repository
99
2. Create a sufolder `mkdir venv`
1010
3. Create virtual environment `python -m venv venv`
11-
4. Activate virtual environment `venv\Scripts\activate.bat` (Linux: `. venv/bin/activate`)
11+
4. Activate virtual environment `venv\Scripts\activate.bat` (Linux: `. ./venv/bin/activate`)
1212
5. Install packages `pip install -r requirements.txt`
1313

1414
## Running Gesture Mouse
15-
### Starting the application
16-
- `python gui.py` to start gui (Linux: `sudo ./venv/bin/python3.10 gui.py`)
17-
- `Alt+1` to toggle mouse controlled by python or system.
18-
- `Esc` to turn off program. (Used if you lose control over mouse)
1915

20-
Alternatively you can create an executable distribution and run `dist\gui.exe` (Windows) or `dist/gui` (Linux)
16+
### Release
17+
18+
1. Extract zip file
19+
2. Run `gesture_mouse.exe` (Windows) or `sudo ./gesture_mouse` (Linux)
20+
21+
### Development
22+
23+
- `python gui.py` to start gui (Linux: `sudo ./venv/bin/python3.10 gui.py`)
24+
25+
## Hotkeys
26+
27+
- <kbd>Alt</kbd>+<kbd>1</kbd> to toggle mouse movement and gestures.
28+
- <kbd>Alt</kbd>+<kbd>m</kbd> to toggle mouse movement.
29+
- <kbd>Alt</kbd>+<kbd>g</kbd> to toggle gestures.
30+
- <kbd>Alt</kbd>+<kbd>t</kbd> to toggle tracking (start or stop camera).
31+
32+
### Hotkeys Mouse Movement
33+
34+
- <kbd>m</kbd> iterate through mouse (ABSOLUTE, RELATIVE, JOYSTICK, HYBRID) modes
35+
- <kbd>t</kbd> iterate through tracking mode (PNP, MEDIAPIPE, NOSE)
36+
- <kbd>c</kbd> Center mouse position
37+
- <kbd>.</kbd> Switch monitor in case there are several monitors applied. Ignored for RELATIVE mouse mode.
2138

2239
## Creating an exe distribution
23-
To create a distribution folder wich includes all necessery .dll and an executable one can use PyInstaller([https://pyinstaller.org](https://pyinstaller.org)).
40+
To create a distribution folder which includes all necessery .dll and an executable one can use PyInstaller([https://pyinstaller.org](https://pyinstaller.org)).
2441
Instructions:
2542
1. Follow the installation instructions
26-
2. Activate virtual environment `venv/Scripts/activate` on windows and `source venv/bin/activate` on linux
43+
2. Activate virtual environment
2744
3. Install PyInstaller `pip install pyinstaller`
2845
4. Execute build process with
29-
`pyinstaller gui.py -D --add-data config;config --add-data data;data --collect-all mediapipe` on windows
30-
`pyinstaller gui.py -D --add-data config:config --add-data data:data --collect-all mediapipe` on linux
46+
`pyinstaller gui.py -D --add-data config;config --add-data data;data --collect-all mediapipe -n gesture-mouse --contents-directory .` on linux
47+
`pyinstaller gui.py -D --add-data config:config --add-data data:data --collect-all mediapipe -n gesture-mouse --contents-directory .` on windows
3148

3249
## Algorithms
3350

config/profiles/keyboard_latest.json

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1 @@
1-
[
2-
{
3-
"action": "keyboard_key",
4-
"signal": "jawOpen",
5-
"threshold": 0.318,
6-
"delay": 0.1,
7-
"trigger": "up",
8-
"action_type": "press and release",
9-
"key": "Backspace"
10-
}
11-
]
1+
[]

config/profiles/mouse_latest.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"mouse_setting": {
33
"left_click": {
4-
"threshold": 0.176,
4+
"threshold": 0.121,
55
"signal": "-",
66
"delay": 0.0
77
},
@@ -36,7 +36,7 @@
3636
"delay": 0.5
3737
},
3838
"switch_monitor": {
39-
"threshold": 0.651,
39+
"threshold": 0.641,
4040
"signal": "-",
4141
"delay": 0.1
4242
},
@@ -54,6 +54,6 @@
5454
"filter_enabled": false,
5555
"filter_value": 0.0018371727707755903,
5656
"tracking_mode": "NOSE",
57-
"mouse_mode": "JOYSTICK"
57+
"mouse_mode": "RELATIVE"
5858
}
5959
}

gui.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ def __init__(self, demo):
880880
self.mouse_settings["right_click"] = MouseClickSettings("Right",self.demo,lambda : self.demo.mouse.click(mouse.Button.right))
881881
self.mouse_settings["double_click"] = MouseClickSettings("Double Click", self.demo,lambda : self.demo.mouse.double_click(mouse.Button.left))
882882
self.mouse_settings["drag_drop"] = MouseClickSettings("Drag and Drop",self.demo,lambda : self.demo.mouse.drag_drop())
883-
self.mouse_settings["pause"] = MouseClickSettings("Pause", self.demo, lambda : self.demo.mouse.toggle_active())
883+
self.mouse_settings["pause"] = MouseClickSettings("Pause", self.demo, lambda : self.demo.mouse.toggle_mouse_movement())
884884
self.mouse_settings["center"] = MouseClickSettings("Center", self.demo, lambda : self.demo.mouse.centre_mouse())
885885
self.mouse_settings["switch_mode"] = MouseClickSettings("Switch Mode", self.demo, lambda : self.demo.mouse.toggle_mode())
886886
self.mouse_settings["switch_monitor"] = MouseClickSettings("Switch Monitor", self.demo, lambda : self.demo.mouse.switch_monitor())
@@ -1321,7 +1321,7 @@ def update_action(self):
13211321
print("Parsed hotkey ", parsed_hotkeys)
13221322

13231323
# create new action
1324-
new_action = Signal.GestureAction()
1324+
new_action = Gesture.GestureAction()
13251325
new_action.threshold = threshold
13261326
action_function = None
13271327
if action_type == "press":

0 commit comments

Comments
 (0)