-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathhand_utils.py
134 lines (109 loc) · 4.16 KB
/
hand_utils.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import cv2
import numpy as np
from utils import *
#detect possible fingers from defects
def eliminate_defects( bounding_box, defects, contour ):
x,y = bounding_box[0]
w,h = bounding_box[1]
tolerance = h / 4
angle_to = 110
new_defects = []
if defects is None or contour is None:
return new_defects
for i in range(len(defects)):
s,e,f,d = defects[i,0]
start = tuple(contour[s][0])
end = tuple(contour[e][0])
far = tuple(contour[f][0])
if distanceP2P(start, far) > tolerance and distanceP2P(end, far) > tolerance:
current_angle = get_angle(start, far, end)
if current_angle < angle_to and current_angle > 30:
condition = y + h / 4
if (end[1] > condition):
continue
elif (start[1] > condition):
continue
else:
new_defects.append([s, e, f])
remove_redundant(new_defects, contour, bounding_box )
return new_defects
def get_far_finger(fingers, contour):
far = None
is_start = False
max_y = 10**5
if fingers is not None and len(fingers) > 0:
for i in range(len(fingers)):
s,e,f = fingers[i]
fr = tuple(contour[f][0])
if (fr[1] < max_y):
max_y = fr[1]
far = fingers[i]
if (e != -1 ):
end = tuple(contour[e][0])
if (end[1] <= max_y):
max_y = end[1]
far = fingers[i]
is_start = True
return far, is_start
#remove redundant fingers for gesture recognition
def get_target_fingers(fingers, contour, bound_rect):
fingers_count = 0
if fingers is None or (len(fingers) <= 0):
return None, None, fingers_count
new_fingers = []
far_finger_pt = None
far, is_start = get_far_finger(fingers,contour )
if far == None or len(far) < 3:
return new_fingers, far_finger_pt, fingers_count
w,h = bound_rect[1]
tolerance=h/5
s,e,f = far
if s == -1:
new_fingers.append(far)
far_finger_pt = tuple(contour[f][0])
fingers_count = 1
else:
start = tuple(contour[s][0])
end = tuple(contour[e][0])
if end[1] < start[1] and abs(start[1] - end[1]) > tolerance:
new_fingers.append(far)
far_finger_pt = end
fingers_count = 2
return new_fingers, far_finger_pt, fingers_count
def remove_redundant(new_defects, contour, bound_rect):
w,h = bound_rect[1]
tolerance=w/4
for i in range(len(new_defects)):
s1,e1,f = new_defects[i]
start1 = tuple(contour[s1][0])
end1 = tuple(contour[e1][0])
for j in range(len(new_defects)):
s2,e2,f = new_defects[j]
start2 = tuple(contour[s2][0])
end2 = tuple(contour[e2][0])
if distanceP2P(start1, end2) < tolerance:
contour[s1][0] = end2
break
if distanceP2P(end1, start2) < tolerance:
contour[s2][0] = end1
def check_one_finger(fingers, contour, bounding_rect, hulls, center):
x,y = bounding_rect[0]
w,h = bounding_rect[1]
max_finger_height = h / 1.65
possible_finger_point = [0, y + w / 2 ]
index = 0
for hl in hulls:
cur_point = contour[hl[0]][0]
if cur_point[1] < possible_finger_point[1]:
possible_finger_point = cur_point
index = hl[0]
tolerance = h / 6
n = 0
for hl in hulls:
cur_point = contour[hl[0]][0]
if cur_point[1] < (possible_finger_point[1] + tolerance) and cur_point[1] != possible_finger_point[1] :
if cur_point[1] < y and cur_point[0] != possible_finger_point[0]:
if distanceP2P(possible_finger_point, cur_point) > tolerance:
n += 1
if n < 2 and len(fingers) == 0:
fingers.append([-1, -1, index])