forked from richzeng/asterisk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fingertracker_peaks.py
116 lines (93 loc) · 3.56 KB
/
fingertracker_peaks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
from fingertracker import FingerTracker
from SimpleCV import Camera, Display, Color, cv
import numpy as np
import scipy
import scipy.signal
from tracking import TrackerIn, util
from math import sqrt
import sys
import time
class FingerTrackerPeaks(FingerTracker):
"""Finger tracking using peak-findings
"""
def __init__(self, camera=None):
"""Initialize the finger tracker
:param TrackerIn ti: Tracker input
:param camera: Camera index, filename, or None
"""
FingerTracker.__init__(self, camera)
self.display = None
def crop_img(self, img):
return img.crop(50, 150, img.width-100, img.height-150)
return img.crop(490,95,img.width-1000, img.height-290).rotate(90, fixed=False)
def find_fingers3(self, img, prev_img):
if img is None or prev_img is None:
return []
crop_spec = [0, 0, img.width, img.height]
scale_factor = 2
r1 = img.grayscale().crop(*crop_spec)
r2 = prev_img.grayscale().crop(*crop_spec)
# modified
diff = (r2 - r1).binarize(40)
edge_mask = diff.erode(5).dilate(5) - diff.erode(5)
edge_mask = edge_mask.dilate(5)
scaled = (diff.edges() & edge_mask).resize(r1.width / scale_factor)
points = []
for x in range(scaled.width):
points.append(scaled.edgeIntersections((x,0), (x, scaled.height))[0])
points = [xy for xy in points if xy is not None]
if not points:
return []
xs = range(scaled.width)
ys = scipy.interp(range(scaled.width), [a[0] for a in points], [a[1] for a in points])
peaks = scipy.signal.find_peaks_cwt(-ys, np.arange(7, 11))
if len(peaks) == 0:
return []
positions = np.array(zip(peaks, np.array(ys)[peaks]))*scale_factor + np.array(crop_spec[:2])
return positions
def run_frame(self, ti, img):
"""Run the algorithm for one frame
:param TrackerIn ti: TrackerIn object to send events to
:return: True if I should be called with the next frame
"""
img = self.crop_img(img)
if self.display is None:
# Consume one frame for the initialization
self.display = Display(img.size())
self.prev_img = img
self.bg_img = None
self.count = 20
self.last_time = time.time()
return True
elif self.display.isDone():
return False
if self.bg_img is None and img:
self.bg_img = img
positions = self.find_fingers3(img, self.bg_img)
if self.count > 0:
self.bg_img = img
self.count -= 1
print "SETTING BG IMAGE"
di = img#(bg_img.grayscale() - img.grayscale()).binarize(40)
for x, y in positions:
di.dl().circle((int(x), int(y)), 15, color=Color.RED, width=3)
self.add_positions(ti, positions)
fps = 1.0 / (time.time() - self.last_time)
di.dl().ezViewText("{0:.3f} fps".format(fps), (0, 0))
di.save(self.display)
self.last_time = time.time()
self.last_img = True
if self.display.mouseLeft or self.display.mouseRight:
self.display.done = True
return False
else:
return True
def finish(self):
if self.display is not None:
self.display.done = True
self.display.quit()
if __name__=="__main__":
color_tracker = FingerTrackerPeaks()
def run(ti):
color_tracker.run(ti)
util.run_async_consumer(run, util.print_consumer)