-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhandDetectionModule.py
126 lines (107 loc) · 4.67 KB
/
handDetectionModule.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
"""
Detect hands using cv2 & mediapipe library
Draw lines to connect the landmarks of the detected hands
"""
import cv2
import mediapipe as mp
import math
class handDetector():
def __init__(self, mode=False, maxHands=2, detectConfidence=0.75, trackConfidence=0.75):
self.mode = mode
self.maxHands = maxHands
self.detectConfidence = detectConfidence
self.trackConfidence = trackConfidence
self.mpHands = mp.solutions.hands
self.hands = self.mpHands.Hands()
self.mpDraw = mp.solutions.drawing_utils
self.tipIds = [4, 8, 12, 16, 20]
# self.LmarkList = []
def findHands(self, frame, draw=True):
# convert img from BGR to RGB for hands object to process
rgbImg = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.result = self.hands.process(rgbImg)
if self.result.multi_hand_landmarks:
for handLmarks in self.result.multi_hand_landmarks:
if draw:
# draw landmarks & connections for them
self.mpDraw.draw_landmarks(
frame, handLmarks, self.mpHands.HAND_CONNECTIONS)
return frame
def findPosition(self, frame, handNo=0, draw=True):
self.LmarkList = []
# xList = []
# yList = []
# bBox = []
# LmarkList = []
# rgbImg = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# self.result = self.hands.process(rgbImg)
if self.result.multi_hand_landmarks:
# processed landmarks from Hands() method for 1 hand
myHand = self.result.multi_hand_landmarks[handNo]
# get land mark ids
for LmarkId, lmk in enumerate(myHand.landmark):
h, w, c = frame.shape # get o/p window dimension
# coordinates for landmarks of detected hands
cx, cy = int(lmk.x * w), int(lmk.y * h)
# xList.append(cx)
# yList.append(cy)
# print(LmarkId, cx, cy) # print id & coord. of landmarks on console
# LmarkList.append([LmarkId, cx, cy])
self.LmarkList.append([LmarkId, cx, cy])
if draw:
if LmarkId in [4, 8, 12, 16, 20]: # id of thumb tip
# draw circle for thumb tip
cv2.circle(frame, (cx, cy), 9,
(84, 245, 66), cv2.FILLED)
# xMin, xMax = min(xList), max(xList)
# yMin, yMax = min(yList), max(yList)
# bBox = xMin, yMax, xMax, yMax
return self.LmarkList
def upFingers(self):
fingers = []
# thumb open or closed
if self.LmarkList[self.tipIds[0]][1] < self.LmarkList[self.tipIds[0] - 1][1]:
fingers.append(1)
else:
fingers.append(0)
# other fingers
for id in range(1, 5):
if self.LmarkList[self.tipIds[id]][2] < self.LmarkList[self.tipIds[id] - 2][2]:
fingers.append(1)
else:
fingers.append(0)
return fingers
def findDistance(self, f1, f2, frame, draw=True):
x1, y1 = self.LmarkList[f1][1:]
x2, y2 = self.LmarkList[f1][1:]
cx, cy = (x1 + x2) // 2, (y1 + y2) // 2
# if draw:
# cv2.line(frame, (x1, y1), (x2, y2), (255, 0, 255), 3)
# cv2.circle(frame, (x1, y1), 15, (255, 0, 255), cv2.FILLED)
# cv2.circle(frame, (x2, y2), 15, (255, 0, 255), cv2.FILLED)
# cv2.circle(frame, (cx, cy), 15, (0, 0, 255), cv2.FILLED)
length = math.hypot(x2 - x1, y2 - y1)
return length, frame, [x1, y1, x2, y2, cx, cy]
def main():
video = cv2.VideoCapture(0) # open camera to capture image frame
detect = handDetector()
# make o/p window of free dimension
cv2.namedWindow('=== Live Cam ===', cv2.WINDOW_NORMAL)
while True:
check, frame = video.read() # check & capture the frame
# flip the frame for a mirror image like o/p
frame = cv2.flip(frame, 1)
frame = detect.findHands(frame)
# get hand landmarks and store in a list
LmarkList = detect.findPosition(frame)
cv2.putText(frame, "Press 'Q' to exit", (25, 450), cv2.FONT_HERSHEY_SIMPLEX,
1, (255, 255, 0), 2) # display quit key on o/p window
# open window for showing the o/p
cv2.imshow('=== Live Cam ===', frame)
# escape key (q)
if cv2.waitKey(1) == ord('q'):
break
video.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()