前言

OpenCV练习,技术水平不到位,还望读者大佬们海涵
🦉这是源码

使用OpenCV和Mediapipe实现手势控制电脑音量

OpenCV: 负责视频流的读取、处理以及可视化手势识别结果。
Mediapipe: Google 开发的机器学习库,提供了高效的手部检测和关键点识别功能。
PyCaw: 用于控制电脑音量的Python库,可以直接修改系统音量大小。

实现步骤

依赖库导入

导入所需的Python库。OpenCV 用于视频处理,Mediapipe 用于手部检测,PyCaw 用于音量控制。此外,math 和 numpy 用于计算手指间的距离及其与音量的映射。

1
2
3
4
5
6
7
8
9
import cv2
import mediapipe as mp
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
import time
import math
import numpy as np

初始化

初始化 Mediapipe 的 Hands 模块

1
2
3
4
5
6
7
8
9
10
11
12
class HandControlVolume:
def __init__(self):
self.mp_drawing = mp.solutions.drawing_utils
self.mp_hands = mp.solutions.hands

devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(
IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
self.volume = cast(interface, POINTER(IAudioEndpointVolume))
self.volume.SetMute(0, None)
self.volume_range = self.volume.GetVolumeRange()

摄像头输入与手势检测

使用 OpenCV 打开摄像头,并实时捕捉视频帧。通过 Mediapipe 检测手部关键点,识别大拇指和食指的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cap = cv2.VideoCapture(0)
resize_w = 640
resize_h = 480

with self.mp_hands.Hands(min_detection_confidence=0.7,
min_tracking_confidence=0.5,
max_num_hands=2) as hands:
while cap.isOpened():
success, image = cap.read()
image = cv2.resize(image, (resize_w, resize_h))

# 图像翻转和处理
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = cv2.flip(image, 1)
results = hands.process(image)

image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

计算手指距离并映射为音量

检测到手掌后,系统会识别出大拇指和食指的坐标,通过勾股定理计算两点之间的距离。根据距离大小,使用 numpy.interp() 函数将其映射到音量值的范围(从最小到最大音量)。

为了方便用户理解,程序还在视频流中绘制手指的关键点及连接线,同时在屏幕上以百分比形式显示当前音量。

1
2
3
4
5
6
7
8
image = cv2.circle(image, (thumb_finger_tip_x, thumb_finger_tip_y), 10, (255, 0, 255), -1)
image = cv2.line(image, (thumb_finger_tip_x, thumb_finger_tip_y),
(index_finger_tip_x, index_finger_tip_y), (255, 0, 255), 5)

# 显示音量百分比
cv2.putText(image, str(math.ceil(rect_percent_text)) + "%", (10, 350),
cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 3)