Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
multitouch
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Taddeüs Kroes
multitouch
Commits
cc772060
Commit
cc772060
authored
12 years ago
by
Taddeüs Kroes
Browse files
Options
Downloads
Patches
Plain Diff
Added hand tracker and implemented it in the test application.
parent
adeaa561
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/trackers/__init__.py
+2
-0
2 additions, 0 deletions
src/trackers/__init__.py
src/trackers/hand.py
+127
-0
127 additions, 0 deletions
src/trackers/hand.py
tests/testapp.py
+52
-34
52 additions, 34 deletions
tests/testapp.py
with
181 additions
and
34 deletions
src/trackers/__init__.py
+
2
−
0
View file @
cc772060
from
basic
import
BasicEventTracker
from
tap
import
TapTracker
from
transform
import
TransformationTracker
from
hand
import
HandTracker
# Map of gesture type to tracker type
...
...
@@ -31,3 +32,4 @@ def create_tracker(gesture_type, widget):
_register_tracker
(
BasicEventTracker
)
_register_tracker
(
TapTracker
)
_register_tracker
(
TransformationTracker
)
_register_tracker
(
HandTracker
)
This diff is collapsed.
Click to expand it.
src/trackers/hand.py
0 → 100644
+
127
−
0
View file @
cc772060
from
..tracker
import
GestureTracker
,
Gesture
class
HandGesture
(
Gesture
):
def
__init__
(
self
,
hand
,
finger
):
self
.
hand
=
hand
self
.
finger
=
finger
def
get_hand
(
self
):
return
self
.
hand
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
FingerDownGesture
(
HandGesture
):
_type
=
'
finger_down
'
class
FingerMoveGesture
(
HandGesture
):
_type
=
'
finger_move
'
class
FingerUpGesture
(
HandGesture
):
_type
=
'
finger_up
'
class
Hand
(
object
):
def
__init__
(
self
):
self
.
fingers
=
[]
def
__len__
(
self
):
return
len
(
self
.
fingers
)
def
__iter__
(
self
):
return
iter
(
self
.
fingers
)
def
__str__
(
self
):
return
'
<Hand fingers=%s centroid=%s>
'
\
%
(
self
.
fingers
,
self
.
get_centroid
())
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
)
def
remove_finger
(
self
,
finger
):
self
.
fingers
.
remove
(
finger
)
def
get_centroid
(
self
):
l
=
len
(
self
.
fingers
)
coords
=
[
f
.
get_position
()
for
f
in
self
.
fingers
]
all_x
,
all_y
=
zip
(
*
coords
)
return
sum
(
all_x
)
/
l
,
sum
(
all_y
)
/
l
class
HandTracker
(
GestureTracker
):
supported_gestures
=
[
FingerDownGesture
,
FingerMoveGesture
,
FingerUpGesture
]
configurable
=
[
'
max_finger_distance
'
]
def
__init__
(
self
,
area
):
super
(
HandTracker
,
self
).
__init__
(
area
)
# Map of finger id's to corresponding hand objects
self
.
finger_hands
=
{}
# All hands being tracked
self
.
hands
=
[]
# Maximum distance between two fingers to be assigned to the same hand
self
.
max_finger_distance
=
400
def
find_hand
(
self
,
finger
):
for
hand
in
self
.
hands
:
if
hand
.
contains
(
finger
,
self
.
max_finger_distance
):
return
hand
self
.
hands
.
append
(
Hand
())
return
self
.
hands
[
-
1
]
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
):
finger
=
event
.
get_touch_object
()
if
finger
.
get_id
()
not
in
self
.
finger_hands
:
return
hand
=
self
.
finger_hands
[
finger
.
get_id
()]
self
.
trigger
(
FingerMoveGesture
(
hand
,
finger
))
def
on_point_up
(
self
,
event
):
finger
=
event
.
get_touch_object
()
finger_id
=
finger
.
get_id
()
if
finger_id
not
in
self
.
finger_hands
:
return
hand
=
self
.
finger_hands
[
finger_id
]
del
self
.
finger_hands
[
finger_id
]
hand
.
remove_finger
(
finger
)
if
not
len
(
hand
):
self
.
hands
.
remove
(
hand
)
self
.
trigger
(
FingerUpGesture
(
hand
,
finger
))
This diff is collapsed.
Click to expand it.
tests/testapp.py
+
52
−
34
View file @
cc772060
...
...
@@ -88,7 +88,7 @@ class Polygon(BoundingBoxArea):
fullscreen
=
False
draw_bounding_boxes
=
draw_touch_
poin
ts
=
True
draw_bounding_boxes
=
draw_touch_
objec
ts
=
True
W
,
H
=
mt
.
screen
.
screen_size
...
...
@@ -107,8 +107,8 @@ def create_context_window(w, h, callback):
refresh
()
def
handle_key
(
win
,
event
):
"""
Handle key event.
'
f
'
toggles fullscreen,
'
q
'
exits the program,
'
b
'
toggles bounding
boxes,
'
p
'
toggles
touch
points.
"""
"""
Handle key event.
'
f
'
toggles fullscreen,
'
b
'
toggles bounding
boxes,
'
i
'
toggles
input
points
,
'
q
'
exits the program
.
"""
if
event
.
keyval
>=
256
:
return
...
...
@@ -118,16 +118,16 @@ def create_context_window(w, h, callback):
global
fullscreen
(
win
.
unfullscreen
if
fullscreen
else
win
.
fullscreen
)()
fullscreen
=
not
fullscreen
elif
key
==
'
q
'
:
quit
()
elif
key
==
'
b
'
:
global
draw_bounding_boxes
draw_bounding_boxes
=
not
draw_bounding_boxes
refresh
()
elif
key
==
'
p
'
:
global
draw_touch_
poin
ts
draw_touch_
poin
ts
=
not
draw_touch_
poin
ts
elif
key
==
'
i
'
:
global
draw_touch_
objec
ts
draw_touch_
objec
ts
=
not
draw_touch_
objec
ts
refresh
()
elif
key
==
'
q
'
:
quit
()
# Root area (will be synchronized with GTK window)
global
root
,
overlay
...
...
@@ -156,7 +156,7 @@ def create_context_window(w, h, callback):
window
.
show
()
def
draw
(
*
args
):
def
draw
():
if
not
cr
:
return
...
...
@@ -171,26 +171,44 @@ def draw(*args):
obj
.
draw
(
cr
)
cr
.
restore
()
if
draw_touch_
poin
ts
:
if
draw_touch_
objec
ts
:
ox
,
oy
=
root
.
get_position
()
cr
.
set_source_rgb
(
*
WHITE
)
for
x
,
y
in
touch_points
.
itervalues
():
x
-=
ox
y
-=
oy
for
hand
in
touch_hands
:
cx
,
cy
=
hand
.
get_centroid
()
cr
.
set_line_width
(
3
)
cr
.
arc
(
x
,
y
,
20
,
0
,
2
*
pi
)
cr
.
stroke
()
# Filled centroid circle
if
len
(
hand
)
>
1
:
cr
.
arc
(
cx
-
ox
,
cy
-
oy
,
20
,
0
,
2
*
pi
)
cr
.
fill
()
for
x
,
y
in
hand
:
x
-=
ox
y
-=
oy
# Circle outline
cr
.
set_line_width
(
3
)
cr
.
arc
(
x
,
y
,
20
,
0
,
2
*
pi
)
cr
.
stroke
()
# Line to centroid
if
len
(
hand
)
>
1
:
cr
.
move_to
(
x
,
y
)
cr
.
line_to
(
cx
-
ox
,
cy
-
oy
)
cr
.
set_line_width
(
2
)
cr
.
stroke
()
# Cross
cr
.
set_line_width
(
1
)
cr
.
move_to
(
x
-
8
,
y
)
cr
.
line_to
(
x
+
8
,
y
)
cr
.
move_to
(
x
,
y
-
8
)
cr
.
line_to
(
x
,
y
+
8
)
cr
.
stroke
()
cr
.
set_line_width
(
1
)
cr
.
move_to
(
x
-
8
,
y
)
cr
.
line_to
(
x
+
8
,
y
)
cr
.
move_to
(
x
,
y
-
8
)
cr
.
line_to
(
x
,
y
+
8
)
cr
.
stroke
()
def
refresh
():
def
refresh
(
*
args
):
window
.
queue_draw
()
...
...
@@ -198,10 +216,10 @@ def quit(*args):
gtk
.
main_quit
()
#
Initialization
#
Global variables
window
=
cr
=
root
=
overlay
=
None
draw_objects
=
[]
touch_
point
s
=
{}
touch_
hand
s
=
[]
def
triangle_height
(
width
):
...
...
@@ -231,22 +249,22 @@ def on_show(window):
# Overlay catches basic events
def
handle_down
(
gesture
):
point
=
gesture
.
get_event
().
get_touch_objec
t
()
touch_
points
[
point
.
get_id
()]
=
point
.
get_position
()
if
gesture
.
is_firs
t
()
:
touch_
hands
.
append
(
gesture
.
get_hand
()
)
if
draw_touch_
poin
ts
:
if
draw_touch_
objec
ts
:
refresh
()
def
handle_up
(
gesture
):
point
=
gesture
.
get_event
().
get_touch_object
()
del
touch_
points
[
point
.
get_
i
d
()
]
if
gesture
.
is_last
():
touch_
hands
.
remove
(
gesture
.
get_
han
d
()
)
if
draw_touch_
poin
ts
:
if
draw_touch_
objec
ts
:
refresh
()
overlay
.
on_
point
_down
(
handle_down
)
overlay
.
on_
point_move
(
handle_down
)
overlay
.
on_
point
_up
(
handle_up
)
overlay
.
on_
finger
_down
(
handle_down
)
overlay
.
on_
finger_move
(
lambda
g
:
draw_touch_objects
and
refresh
()
)
overlay
.
on_
finger
_up
(
handle_up
)
root
.
add_area
(
overlay
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment