Skip to content
Snippets Groups Projects
Commit 4fdba920 authored by Taddeüs Kroes's avatar Taddeüs Kroes
Browse files

Improved hand tracking.

parent 1cf29d18
No related branches found
No related tags found
No related merge requests found
......@@ -2,8 +2,5 @@ Code:
- Rotation has a 'bump' at angle = 0.
- Polygon tracker verplaatsen naar framework.
Tests:
- Improve hand tracker.
Report/appendix reference gesture detection:
- Point_leave(+point_enter) kan niet -> flaw v/h systeem/driver?
from src.tracker import GestureTracker, Gesture
from src.geometry import Positionable
class HandGesture(Gesture):
def __init__(self, hand, finger):
def __init__(self, hand, finger=None):
self.hand = hand
self.finger = finger
......@@ -12,11 +13,13 @@ class HandGesture(Gesture):
def get_finger(self):
return self.finger
def is_first(self):
return len(self.hand) == 1
def is_last(self):
return not len(self.hand)
class HandDownGesture(HandGesture):
_type = 'hand_down'
class HandUpGesture(HandGesture):
_type = 'hand_up'
class FingerDownGesture(HandGesture):
......@@ -31,9 +34,10 @@ class FingerUpGesture(HandGesture):
_type = 'finger_up'
class Hand(object):
class Hand(Positionable):
def __init__(self):
self.fingers = []
self.centroid = None
def __len__(self):
return len(self.fingers)
......@@ -48,29 +52,32 @@ class Hand(object):
def __repr__(self):
return str(self)
def contains(self, finger, max_distance):
for other_finger in self.fingers:
if other_finger.distance_to(finger) <= max_distance:
return True
return False
def add_finger(self, finger):
self.fingers.append(finger)
self.update_centroid()
def remove_finger(self, finger):
self.fingers.remove(finger)
self.update_centroid()
def get_centroid(self):
def update_centroid(self):
l = len(self.fingers)
if not l:
self.centroid = None
return
coords = [f.get_position() for f in self.fingers]
all_x, all_y = zip(*coords)
return sum(all_x) / l, sum(all_y) / l
self.centroid = sum(all_x) / l, sum(all_y) / l
def get_centroid(self):
return self.centroid
class HandTracker(GestureTracker):
supported_gestures = [FingerDownGesture, FingerMoveGesture,
FingerUpGesture]
supported_gestures = [HandDownGesture, HandUpGesture, FingerDownGesture,
FingerMoveGesture, FingerUpGesture]
configurable = ['max_finger_distance']
......@@ -87,18 +94,30 @@ class HandTracker(GestureTracker):
self.max_finger_distance = 300
def find_hand(self, finger):
for hand in self.hands:
if hand.contains(finger, self.max_finger_distance):
return hand
min_dist = hand = None
for h in self.hands:
dist = finger.distance_to(h.get_centroid())
if min_dist is None or dist < min_dist:
min_dist = dist
hand = h
if not hand or min_dist > self.max_finger_distance:
hand = Hand()
self.hands.append(hand)
self.hands.append(Hand())
return self.hands[-1]
self.finger_hands[finger.get_id()] = hand
hand.add_finger(finger)
if len(hand) == 1:
self.trigger(HandDownGesture(hand))
return hand
def on_point_down(self, event):
finger = event.get_touch_object()
hand = self.find_hand(finger)
hand.add_finger(finger)
self.finger_hands[finger.get_id()] = hand
self.trigger(FingerDownGesture(hand, finger))
def on_point_move(self, event):
......@@ -108,6 +127,17 @@ class HandTracker(GestureTracker):
return
hand = self.finger_hands[finger.get_id()]
hand.update_centroid()
if finger.distance_to(hand.get_centroid()) > self.max_finger_distance:
hand.remove_finger(finger)
if not len(hand):
self.hands.remove(hand)
self.trigger(HandUpGesture(hand))
hand = self.find_hand(finger)
self.trigger(FingerMoveGesture(hand, finger))
def on_point_up(self, event):
......@@ -120,8 +150,8 @@ class HandTracker(GestureTracker):
hand = self.finger_hands[finger_id]
del self.finger_hands[finger_id]
hand.remove_finger(finger)
self.trigger(FingerUpGesture(hand, finger))
if not len(hand):
self.hands.remove(hand)
self.trigger(FingerUpGesture(hand, finger))
self.trigger(HandUpGesture(hand))
......@@ -269,15 +269,13 @@ def on_show(window):
# Overlay catches finger events to be able to draw touch points
def handle_down(gesture):
if gesture.is_first():
touch_hands.append(gesture.get_hand())
touch_hands.append(gesture.get_hand())
if draw_touch_objects:
refresh()
def handle_up(gesture):
if gesture.is_last():
touch_hands.remove(gesture.get_hand())
touch_hands.remove(gesture.get_hand())
if draw_touch_objects:
refresh()
......@@ -288,9 +286,9 @@ def on_show(window):
screen.add_area(root)
screen.add_area(overlay)
overlay.on_finger_down(handle_down)
overlay.on_hand_down(handle_down)
overlay.on_finger_move(lambda g: draw_touch_objects and refresh())
overlay.on_finger_up(handle_up)
overlay.on_hand_up(handle_up)
# Root area rotation leads to rotation of all polygons around the centroid
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment