Skip to content

Commit 543aa5e

Browse files
committed
v2
0 parents  commit 543aa5e

File tree

4 files changed

+201
-0
lines changed

4 files changed

+201
-0
lines changed

HandTrackingModule.py

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import cv2
2+
import mediapipe as mp
3+
import time
4+
import math
5+
6+
class handDetector():
7+
def __init__(self, mode=False, maxHands=2, modelComplexity=1, detectionCon=0.5, trackCon=0.5):
8+
self.mode = mode
9+
self.maxHands = maxHands
10+
self.modelComplexity = modelComplexity
11+
self.detectionCon = detectionCon
12+
self.trackCon = trackCon
13+
14+
self.mpHands = mp.solutions.hands
15+
self.hands = self.mpHands.Hands(self.mode, self.maxHands, self.modelComplexity, self.detectionCon, self.trackCon)
16+
self.mpDraw = mp.solutions.drawing_utils
17+
self.tipIds = [4, 8, 12, 16, 20]
18+
19+
def findHands(self, img, draw=True):
20+
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
21+
self.results = self.hands.process(imgRGB)
22+
#print(results.multi_hand_landmarks)
23+
24+
if self.results.multi_hand_landmarks:
25+
for handLms in self.results.multi_hand_landmarks:
26+
if draw:
27+
self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS)
28+
return img
29+
30+
def findPosition(self, img, handNo=0, draw=True):
31+
xList = []
32+
yList = []
33+
bbox = []
34+
self.lmList = []
35+
if self.results.multi_hand_landmarks:
36+
myHand = self.results.multi_hand_landmarks[handNo]
37+
for id, lm in enumerate(myHand.landmark):
38+
#print(id, lm)
39+
h, w, c = img.shape
40+
cx, cy = int(lm.x*w), int(lm.y*h)
41+
xList.append(cx)
42+
yList.append(cy)
43+
#print(id, cx, cy)
44+
self.lmList.append([id, cx, cy])
45+
if draw:
46+
cv2.circle(img, (cx, cy), 5, (255,0,255), cv2.FILLED)
47+
xmin, xmax = min(xList), max(xList)
48+
ymin, ymax = min(yList), max(yList)
49+
bbox = xmin, ymin, xmax, ymax
50+
51+
if draw:
52+
cv2.rectangle(img, (bbox[0]-20, bbox[1]-20), (bbox[2]+20, bbox[3]+20), (0, 255, 0), 2)
53+
return self.lmList, bbox
54+
55+
def findDistance(self, p1, p2, img, draw=True):
56+
x1, y1 = self.lmList[p1][1], self.lmList[p1][2]
57+
x2, y2 = self.lmList[p2][1], self.lmList[p2][2]
58+
cx, cy = (x1+x2)//2, (y1+y2)//2
59+
60+
if draw:
61+
cv2.circle(img, (x1,y1), 15, (255,0,255), cv2.FILLED)
62+
cv2.circle(img, (x2,y2), 15, (255,0,255), cv2.FILLED)
63+
cv2.line(img, (x1,y1), (x2,y2), (255,0,255), 3)
64+
cv2.circle(img, (cx,cy), 15, (255,0,255), cv2.FILLED)
65+
66+
length = math.hypot(x2-x1, y2-y1)
67+
return length, img, [x1, y1, x2, y2, cx, cy]
68+
69+
def fingersUp(self):
70+
fingers = []
71+
72+
# Thumb
73+
if self.lmList[self.tipIds[0]][1] < self.lmList[self.tipIds[0]-1][1]:
74+
fingers.append(1)
75+
else:
76+
fingers.append(0)
77+
78+
# 4 Fingers
79+
for id in range(1,5):
80+
if self.lmList[self.tipIds[id]][2] < self.lmList[self.tipIds[id]-2][2]:
81+
fingers.append(1)
82+
else:
83+
fingers.append(0)
84+
return fingers
85+
86+
def main():
87+
pTime = 0
88+
cTime = 0
89+
cap = cv2.VideoCapture(0)
90+
detector = handDetector()
91+
while True:
92+
success, img = cap.read()
93+
img = detector.findHands(img)
94+
lmList = detector.findPosition(img)
95+
if len(lmList) != 0:
96+
print(lmList[1])
97+
98+
cTime = time.time()
99+
fps = 1. / (cTime - pTime)
100+
pTime = cTime
101+
102+
cv2.putText(img, str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,255), 3)
103+
104+
cv2.imshow("Image", img)
105+
cv2.waitKey(1)
106+
107+
108+
if __name__ == "__main__":
109+
main()

img/HandLandmarks.png

252 KB
Loading

libraries.bat

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pip install mediapipe
2+
pip install opencv-python
3+
pip install numpy
4+
pip install pycaw

main.py

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import cv2
2+
import time
3+
import numpy as np
4+
import HandTrackingModule as htm
5+
import math
6+
from ctypes import cast, POINTER
7+
from comtypes import CLSCTX_ALL
8+
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
9+
10+
wCam, hCam = 1280, 720
11+
12+
cap = cv2.VideoCapture(0)
13+
cap.set(3, wCam)
14+
cap.set(4, hCam)
15+
pTime = 0
16+
17+
detector = htm.handDetector(detectionCon=0.7, maxHands=1)
18+
19+
devices = AudioUtilities.GetSpeakers()
20+
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
21+
volume = cast(interface, POINTER(IAudioEndpointVolume))
22+
volRange = volume.GetVolumeRange()
23+
volume.SetMasterVolumeLevel(0, None)
24+
minVol = volRange[0]
25+
maxVol = volRange[1]
26+
vol = 0
27+
volBar = 400
28+
volPer = 0
29+
area = 0
30+
colorVol = (255, 0, 0)
31+
32+
33+
while True:
34+
success, img = cap.read()
35+
36+
# Find Hand
37+
img = detector.findHands(img)
38+
lmList, bbox = detector.findPosition(img, draw=True)
39+
if len(lmList) != 0:
40+
41+
# Filter based on size
42+
area = (bbox[2]-bbox[0]) * (bbox[3]-bbox[1])//100
43+
#print(area)
44+
if 250 < area < 1000:
45+
#print("yes")
46+
47+
# Find distance between index and Thumb
48+
length, img, lineInfo = detector.findDistance(4, 8, img)
49+
50+
# Convert Volume
51+
volBar = np.interp(length, [50,200], [400, 150])
52+
volPer = np.interp(length, [50,200], [0, 100])
53+
54+
# Reduce Resolution to make it smoother
55+
smoothness = 5
56+
volPer = smoothness * round(volPer/smoothness)
57+
58+
# Check fingers up
59+
fingers = detector.fingersUp()
60+
61+
# If pinky is down set volume
62+
if not fingers[4]:
63+
volume.SetMasterVolumeLevelScalar(volPer/100, None)
64+
cv2.circle(img, (lineInfo[4], lineInfo[5]), 15, (0,255,0), cv2.FILLED)
65+
colorVol = (255, 255, 0)
66+
time.sleep(0.05)
67+
else:
68+
colorVol = (255, 0, 0)
69+
70+
71+
# Drawings
72+
cv2.rectangle(img, (50, 150), (85, 400), (0,255,0), 3)
73+
cv2.rectangle(img, (50, int(volBar)), (85, 400), (0,255,0), cv2.FILLED)
74+
cv2.putText(img, f'{int(volPer)} %', (40,450), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,0), 3)
75+
76+
cVol = int(volume.GetMasterVolumeLevelScalar()*100)
77+
cv2.putText(img, f'Volume set: {int(cVol)}', (600,50), cv2.FONT_HERSHEY_COMPLEX, 1, colorVol, 3)
78+
79+
80+
# Frame rate
81+
cTime = time.time()
82+
fps = 1 / (cTime - pTime)
83+
pTime = cTime
84+
85+
cv2.putText(img, f'FPS: {int(fps)}', (40,70), cv2.FONT_HERSHEY_COMPLEX, 1, (255,0,100), 3)
86+
87+
cv2.imshow("Img", img)
88+
cv2.waitKey(1)

0 commit comments

Comments
 (0)