赞
踩
今天给大家带来一个OpenCV的实战小项目——手势识别控制电脑音量
先上个效果图:
通过大拇指和食指间的开合距离来调节电脑音量,即通过识别大拇指与食指这两个关键点之间的距离来控制电脑音量大小
技术要学会分享、交流,不建议闭门造车。一个人走的很快、一堆人可以走的更远。
本文来自技术群粉丝分享整理,文章源码、数据、技术交流,均可加交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。
方式①、添加微信号:pythoner666,备注:来自CSDN +音量控制
方式②、微信搜索公众号:Python学习与数据挖掘,后台回复:资料
一、环境配置
这个项目需要的环境比较简单,主要就是opencv和mediapipe库
import cv2
import mediapipe as mp
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
import pyautogui
缺库的话直接:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 库名称
二、代码介绍
1)初始化mediapipe库
self.mp_drawing = mp.solutions.drawing_utils
self.mp_drawing_styles = mp.solutions.drawing_styles
self.mp_hands = mp.solutions.hands
2)获取电脑音量范围
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()
3)利用OpenCV读取摄像头视频流进行显示
cap = cv2.VideoCapture(0)
resize_w = 640
resize_h = 480
while cap.isOpened():
success, image = cap.read()
image = cv2.resize(image, (resize_w, resize_h))
4)识别手掌,获取手掌关键点坐标
# 判断是否有手掌
if results.multi_hand_landmarks:
# 遍历每个手掌
for hand_landmarks in results.multi_hand_landmarks:
# 在画面标注手指
# 解析手指,存入各个手指坐标
landmark_list = []
for landmark_id, finger_axis in enumerate(
hand_landmarks.landmark):
landmark_list.append([
landmark_id, finger_axis.x, finger_axis.y,
finger_axis.z
])
if landmark_list:
# 获取大拇指指尖坐标
thumb_finger_tip = landmark_list[4]
thumb_finger_tip_x = math.ceil(thumb_finger_tip[1] * resize_w)
thumb_finger_tip_y = math.ceil(thumb_finger_tip[2] * resize_h)
# 获取食指指尖坐标
index_finger_tip = landmark_list[8]
index_finger_tip_x = math.ceil(index_finger_tip[1] * resize_w)
index_finger_tip_y = math.ceil(index_finger_tip[2] * resize_h)
# 获取中指尖坐标
middle_finger_tip = landmark_list[12]
middle_finger_tip_x = math.ceil(middle_finger_tip[1] * resize_w)
middle_finger_tip_y = math.ceil(middle_finger_tip[2] * resize_h)
# 中指与食指中间点
middle_index_finger_middle_point = (middle_finger_tip_x + index_finger_tip_x) // 2, (
middle_finger_tip_y + index_finger_tip_y) // 2
# print(thumb_finger_tip_x)
middle_finger_point = (middle_finger_tip_x, middle_finger_tip_y)
index_finger_point = (index_finger_tip_x, index_finger_tip_y)
# 画指尖2点
image = cv2.circle(image, middle_finger_point, 10, (255, 0, 255), -1)
image = cv2.circle(image, index_finger_point, 10, (255, 0, 255), -1)
image = cv2.circle(image, middle_index_finger_middle_point, 10, (255, 0, 255), -1)
# 画2点连线
image1 = cv2.line(image, middle_finger_point, index_finger_point, (255, 0, 255), 5)
# 勾股定理计算长度
middle_index_line_len = math.hypot((middle_finger_tip_x - index_finger_tip_x),
(middle_finger_tip_y - index_finger_tip_y))
5)将拇指与食指距离与电脑音量进行关联
# 当食指中指距离大于65像素允许调音量
if middle_index_line_len < 65.0:
# 拇指与食指中间点
finger_middle_point = (thumb_finger_tip_x + index_finger_tip_x) // 2, (
thumb_finger_tip_y + index_finger_tip_y) // 2
# print(thumb_finger_tip_x)
thumb_finger_point = (thumb_finger_tip_x, thumb_finger_tip_y)
index_finger_point = (index_finger_tip_x, index_finger_tip_y)
# 画2点连线
image = cv2.line(image, thumb_finger_point, index_finger_point, (255, 0, 255), 5)
# 勾股定理计算长度
line_len = math.hypot((index_finger_tip_x - thumb_finger_tip_x),
(index_finger_tip_y - thumb_finger_tip_y))
# 获取电脑最大最小音量
min_volume = self.volume_range[0]
max_volume = self.volume_range[1]
# 将指尖长度映射到音量上
vol = np.interp(line_len, [50, 300], [min_volume, max_volume])
# 将指尖长度映射到矩形显示上
rect_height = np.interp(line_len, [50, 300], [0, 200])
rect_percent_text = np.interp(line_len, [50, 300], [0, 100])
# 设置电脑音量
self.volume.SetMasterVolumeLevel(vol, None)
#锁定调音量,进行鼠标控制
else:
for id, lm in enumerate(hand_landmarks.landmark):
# print(id,lm)
h, w, c = image.shape
cx, cy = int(lm.x * w), int(lm.y * h)
# id=手部关键点
if id == 0:
if cx > dot[0] and cx < dot[2] and cy > dot[1] and cy < dot[3]:
x0 = ((cx-dot[0])/(dot[2]-dot[0]))*1920
y0 = ((cy-dot[1])/(dot[3]-dot[1]))*1080
pyautogui.moveTo(x0, y0, duration=0.02)
# print(thumb_finger_tip_x)
thumb_finger_point = (thumb_finger_tip_x, thumb_finger_tip_y)
index_finger_point = (index_finger_tip_x, index_finger_tip_y)
# 画指尖2点
image = cv2.circle(image, thumb_finger_point, 10, (255, 0, 255), -1)
image = cv2.circle(image, index_finger_point, 10, (255, 0, 255), -1)
image = cv2.circle(image, finger_middle_point, 10, (255, 0, 255), -1)
# 画2点连线
image = cv2.line(image, thumb_finger_point, index_finger_point, (255, 0, 255), 5)
# 勾股定理计算长度
line_len = math.hypot((index_finger_tip_x - thumb_finger_tip_x),
(index_finger_tip_y - thumb_finger_tip_y))
# 操作
# 左键双击
if line_len < 20:
pyautogui.doubleClick()
ms_d = 0
三、使用方式
1)直接运行程序
2)把手掌靠近摄像头,置于矩形框内
3)通过拇指与食指的开合即可调节音量
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。