-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathVol_Hand_Control.py
97 lines (75 loc) · 2.95 KB
/
Vol_Hand_Control.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
import cv2
import numpy as np
import time
import VH_HandTrackingModule as htm
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
wCam, hCam = 640, 480
pTime = 0
min_dist = 25
max_dist = 190
vol = 0
vol_bar = 340
vol_perc = 0
area = 0
vol_color = (250, 0, 0)
cap = cv2.VideoCapture(0)
cap.set(3, wCam)
cap.set(4, hCam)
detector = htm.HandDetector(detection_conf=1, max_hands=1)
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
# Volume Range -65 - 0
vol_range = volume.GetVolumeRange()
min_vol = vol_range[0]
max_vol = vol_range[1]
while True:
success, img = cap.read()
# Find Hand
img = detector.findHands(img, draw=True)
lmList, b_box = detector.findPosition(img, draw=True)
if len(lmList) != 0:
# Filter based on Size
area = (b_box[2] - b_box[0]) * (b_box[3] - b_box[1]) // 100
# print(area)
if 200 < area < 1000:
# Find Dist btw index & thumb
## Fings Distance Range 25 - 205
len_line, img, line_info = detector.findDistance(4, 8, img)
# Convert Vol
vol_bar = np.interp(len_line, [min_dist, max_dist], [340, 140])
vol_perc = np.interp(len_line, [min_dist, max_dist], [0, 100])
# Reduce Resolution to make it smoother
smoothness = 10
vol_perc = smoothness * round(vol_perc / smoothness)
# Check fingers up
fingers = detector.fingersUp()
# print(fingers)
# If pinky is down set volume
if not fingers[4]:
volume.SetMasterVolumeLevelScalar(vol_perc / 100, None)
cv2.circle(img, (line_info[4], line_info[5]), 5, (255, 255, 0), cv2.FILLED)
vol_color = (135, 0, 255)
else:
vol_color = (135, 0, 255)
# Min - Max Vol Button Color
if len_line < min_dist:
cv2.circle(img, (line_info[4], line_info[5]), 5, (0, 0, 255), cv2.FILLED)
elif len_line > max_dist:
cv2.circle(img, (line_info[4], line_info[5]), 5, (0, 255, 0), cv2.FILLED)
# Drawings
cv2.rectangle(img, (55, 140), (85, 340), (255, 255, 0), 3)
cv2.rectangle(img, (55, int(vol_bar)), (85, 340), (255, 255, 0), cv2.FILLED)
cv2.putText(img, f'Vol = {int(vol_perc)} %', (18, 380), cv2.FONT_HERSHEY_COMPLEX, 0.6, (51, 255, 255), 2)
curr_vol = int(volume.GetMasterVolumeLevelScalar() * 100)
cv2.putText(img, f'Vol set to: {int(curr_vol)} %', (410, 50), cv2.FONT_HERSHEY_COMPLEX, 0.7, vol_color, 2)
# Frame Rate
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
cv2.putText(img, f'FPS:{int(fps)}', (30, 50), cv2.FONT_HERSHEY_COMPLEX, 0.7, (255, 0, 0), 2)
cv2.imshow("Frame", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break