forked from SouravJohar/handy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Hand.py
72 lines (63 loc) · 2.28 KB
/
Hand.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
import cv2
import math
class Hand:
def __init__(self, binary, masked, raw, frame):
self.masked = masked
self.binary = binary
self._raw = raw
self.frame = frame
self.contours = []
self.outline = self.draw_outline()
self.fingertips = self.extract_fingertips()
def draw_outline(self, min_area=10000, color=(0, 255, 0), thickness=2):
contours, _ = cv2.findContours(
self.binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
palm_area = 0
flag = None
cnt = None
for (i, c) in enumerate(contours):
area = cv2.contourArea(c)
if area > palm_area:
palm_area = area
flag = i
if flag is not None and palm_area > min_area:
cnt = contours[flag]
self.contours = cnt
cpy = self.frame.copy()
cv2.drawContours(cpy, [cnt], 0, color, thickness)
return cpy
else:
return self.frame
def extract_fingertips(self, filter_value=50):
cnt = self.contours
if len(cnt) == 0:
return cnt
points = []
hull = cv2.convexHull(cnt, returnPoints=False)
defects = cv2.convexityDefects(cnt, hull)
for i in range(defects.shape[0]):
s, e, f, d = defects[i, 0]
end = tuple(cnt[e][0])
points.append(end)
filtered = self.filter_points(points, filter_value)
filtered.sort(key=lambda point: point[1])
return [pt for idx, pt in zip(range(5), filtered)]
def filter_points(self, points, filter_value):
for i in range(len(points)):
for j in range(i + 1, len(points)):
if points[i] and points[j] and self.dist(points[i], points[j]) < filter_value:
points[j] = None
filtered = []
for point in points:
if point is not None:
filtered.append(point)
return filtered
def get_center_of_mass(self):
if len(self.contours) == 0:
return None
M = cv2.moments(self.contours)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
return (cX, cY)
def dist(self, a, b):
return math.sqrt((a[0] - b[0])**2 + (b[1] - a[1])**2)