import cv2import mediapipe as mpimport mathimport numpy as npfrom ctypes import cast, POINTERfrom comtypes import CLSCTX_ALLfrom pycaw.pycaw import AudioUtilities, IAudioEndpointVolume# Initialize webcamcap = cv2.VideoCapture(0)# Set webcam resolutioncap.set(3, 1280)cap.set(4, 720)# Initialize MediaPipe Handsmp_hands = mp.solutions.handshands = mp_hands.Hands( static_image_mode=False, max_num_hands=1, min_detection_confidence=0.7, min_tracking_confidence=0.7)mp_draw = mp.solutions.drawing_utils# Initialize system audiodevices = AudioUtilities.GetSpeakers()interface = devices.Activate( IAudioEndpointVolume._iid_, CLSCTX_ALL, None)volume = cast(interface, POINTER(IAudioEndpointVolume))# Get volume rangevol_min, vol_max = volume.GetVolumeRange()[:2]while True: success, frame = cap.read() if not success: break # Flip image horizontally frame = cv2.flip(frame, 1) # Convert to RGB rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Process hand detection results = hands.process(rgb_frame) if results.multi_hand_landmarks: for hand_landmarks in results.multi_hand_landmarks: landmark_list = [] h, w, c = frame.shape # Extract landmarks for idx, lm in enumerate(hand_landmarks.landmark): cx = int(lm.x * w) cy = int(lm.y * h) landmark_list.append((idx, cx, cy)) # Thumb tip x1, y1 = landmark_list[4][1], landmark_list[4][2] # Index finger tip x2, y2 = landmark_list[8][1], landmark_list[8][2] # Center point cx, cy = (x1 + x2) // 2, (y1 + y2) // 2 # Draw landmarks cv2.circle(frame, (x1, y1), 12, (255, 0, 255), cv2.FILLED) cv2.circle(frame, (x2, y2), 12, (255, 0, 255), cv2.FILLED) cv2.line(frame, (x1, y1), (x2, y2), (255, 0, 255), 3) cv2.circle(frame, (cx, cy), 10, (0, 255, 0), cv2.FILLED) # Calculate distance length = math.hypot(x2 - x1, y2 - y1) # Convert finger distance to volume vol = np.interp(length, [30, 220], [vol_min, vol_max]) # Volume percentage vol_percent = np.interp(length, [30, 220], [0, 100]) # Volume bar vol_bar = np.interp(length, [30, 220], [400, 150]) # Set system volume volume.SetMasterVolumeLevel(vol, None) # Draw volume bar UI cv2.rectangle(frame, (50, 150), (85, 400), (0, 255, 0), 3) cv2.rectangle( frame, (50, int(vol_bar)), (85, 400), (0, 255, 0), cv2.FILLED ) cv2.putText( frame, f'{int(vol_percent)}%', (35, 450), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 3 ) # Draw hand connections mp_draw.draw_landmarks( frame, hand_landmarks, mp_hands.HAND_CONNECTIONS ) cv2.imshow("Hand Gesture Volume Control", frame) # Press Q to quit if cv2.waitKey(1) & 0xFF == ord('q'): breakcap.release()cv2.destroyAllWindows()