Skip to content

Instantly share code, notes, and snippets.

@SULAIMAN-5-AHMED
Last active December 12, 2022 17:18
Show Gist options
  • Save SULAIMAN-5-AHMED/ec3ad5b66861318e23f257ae111c3bea to your computer and use it in GitHub Desktop.
Save SULAIMAN-5-AHMED/ec3ad5b66861318e23f257ae111c3bea to your computer and use it in GitHub Desktop.
import cv2
import mediapipe as mp
import numpy as np
import math
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
cap = cv2.VideoCapture(0)
mphands = mp.solutions.hands
hands = mphands.Hands()
mpdraw = mp.solutions.drawing_utils
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
volRange = volume.GetVolumeRange() # We can print this out to get the range of the volume we will be just using the first 2-values.
# The above one would be of list format.
minVol = volRange[0]
maxVol = volRange[1]
volp = 0 # Setting a default value of vol in %
while True:
success, img = cap.read()
imgRgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
result = hands.process(imgRgb)
if result.multi_hand_landmarks:
for handlms in result.multi_hand_landmarks:
for id, lm in enumerate(handlms.landmark):
# print(id,lm) Getting the landmarks and id.
h, w, c = img.shape
cx, cy = int(lm.x * w), int(lm.y * h)
# print(id,cx,cy)
if id == 4 or id == 8: # Getting the values co-ordinates of 4 and 8 id.
lmlist = [cx,
cy] # Converting them to list so that we can get seperate values of x and y coordinates to substitute them.
cv2.circle(img, (lmlist[0], lmlist[1]), 15, (0, 0, 0),
cv2.FILLED) # Creating circle around the tips of the finger we are working with.
if id == 4: # Getting seperate values of coordinates od 4th and 8th id.
x1 = lmlist[0]
y1 = lmlist[1]
if id == 8:
x2 = lmlist[0]
y2 = lmlist[1]
length = math.hypot(x2 - x1,
y2 - y1) # We are using the hypotaneous funciton to get the length of the line
p1, p2 = (x1 + x2) // 2, (y1 + y2) // 2 # We are finding out the mid-point of the line.
cv2.circle(img, (p1, p2), 15, (225, 255, 255),
cv2.FILLED) # Creating a circle around our mid-point
cv2.line(img, (x1, y1), (x2, y2), (0, 225, 0),
4) # Creating a line having points as our tips of our finger.
# print(length) getting the idea of max and min length
# Hand Range 50 - 300
# vol Range 65 -0
vol = np.interp(length, [50, 290], [minVol,
maxVol]) # Using the numpy library to convert the values of our range equal to that of vol
# print(int(length) , vol)
volume.SetMasterVolumeLevel(vol,
None) # Substitutung the range of values obtained from above in this function
if length < 30: # Creating a colour changer to act as button when our tips gets close to each other.
cv2.circle(img, (p1, p2), 15, (225, 0, 0), cv2.FILLED)
volp = np.interp(length, [50, 290], [0,
100]) # Creating range similar to that of we did above to put over the image.
cv2.putText(img, f'{int(volp)}%', (40, 400), cv2.FONT_HERSHEY_COMPLEX, 1,
(0, 225, 225, 3)) # We are using int() to get whole values.
mpdraw.draw_landmarks(img, handlms, mphands.HAND_CONNECTIONS)
cv2.imshow('VID', img)
cv2.waitKey(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment