Python實戰(zhàn)之手勢識別控制電腦音量
今天給大家?guī)硪粋€OpenCV的實戰(zhàn)小項目——手勢識別控制電腦音量
先上個效果圖:


通過大拇指和食指間的開合距離來調(diào)節(jié)電腦音量,即通過識別大拇指與食指這兩個關(guān)鍵點之間的距離來控制電腦音量大小
一、環(huán)境配置
這個項目需要的環(huán)境比較簡單,主要就是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讀取攝像頭視頻流進(jìn)行顯示
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)識別手掌,獲取手掌關(guān)鍵點坐標(biāo)
# 判斷是否有手掌
if results.multi_hand_landmarks:
# 遍歷每個手掌
for hand_landmarks in results.multi_hand_landmarks:
# 在畫面標(biāo)注手指
# 解析手指,存入各個手指坐標(biāo)
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:
# 獲取大拇指指尖坐標(biāo)
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)
# 獲取食指指尖坐標(biāo)
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)
# 獲取中指尖坐標(biāo)
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)將拇指與食指距離與電腦音量進(jìn)行關(guān)聯(lián)
# 當(dāng)食指中指距離大于65像素允許調(diào)音量
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])
# 設(shè)置電腦音量
self.volume.SetMasterVolumeLevel(vol, None)
#鎖定調(diào)音量,進(jìn)行鼠標(biāo)控制
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=手部關(guān)鍵點
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)把手掌靠近攝像頭,置于矩形框內(nèi)

3)通過拇指與食指的開合即可調(diào)節(jié)音量

到此這篇關(guān)于Python實戰(zhàn)之手勢識別控制電腦音量的文章就介紹到這了,更多相關(guān)Python手勢識別控制電腦音量內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中的List sort()與torch.sort()
這篇文章主要介紹了python中的List sort()與torch.sort()使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
Python開發(fā)生產(chǎn)環(huán)境常用的4個工具(實用推薦)
構(gòu)建優(yōu)秀的軟件需要遵循特定的規(guī)則并執(zhí)行行業(yè)標(biāo)準(zhǔn),如何在真實的生產(chǎn)環(huán)境開發(fā)中體現(xiàn)呢?在這篇文章中,我將向您展示我在Python項目中設(shè)置的4種工具,以簡化開發(fā)工作流程并執(zhí)行一些最佳實踐,這些工具幫助我提高了效率,節(jié)省了時間,希望你讀完也能有所收獲2024-01-01
Python中使用format函數(shù)的小結(jié)
在Python中,format()函數(shù)是一種用于格式化字符串的方法主要介紹了Python中使用format函數(shù)的小結(jié),本文就來介紹一下format()函數(shù)的使用示例,感興趣的可以了解一下2023-08-08
Python探索之靜態(tài)方法和類方法的區(qū)別詳解
這篇文章主要介紹了Python探索之靜態(tài)方法和類方法的區(qū)別詳解,小編覺得還是挺不錯的,這里分享給大家,供需要的朋友參考。2017-10-10
TensorFlow神經(jīng)網(wǎng)絡(luò)優(yōu)化策略學(xué)習(xí)
這篇文章主要介紹了TensorFlow神經(jīng)網(wǎng)絡(luò)優(yōu)化策略2018-03-03

