简单手势控制系统

news/2024/11/30 9:38:12/

基于摄像头识别的手势控制系统,主要利用Python语言中的Opencv,mediapipa和 pyautogui这两个库,来打开并控制电脑摄像头,使用mediapipa库中的solution方法来对手部信息进行识别和获取。通过对手指竖起的个数以及特定的手指来实现并执行手势控制系统的所有功能。

大致功能如下:

a)  控制电脑音量大小。

b)  控制鼠标的移动,能大致完成鼠标的所有功能。比如鼠标的移动,单击左键或右键,拖动文       件,画图,滑动等

c)  通过手的左右移动来实现键盘左右方向键的功能。比如PPT的翻页,文件和网页的浏览等。

作品的安装与运行说明

安装:下载Python 3.8 和 PyCharm Community Edition 2021.3.3

      下载opencv-python,mediapiia,pyautogui,numpy,pycaw,comtypes库

运行说明:打开摄像头(如果使用电脑默认的,在源代码中的camera = cv2.VideoCapture(1, cv2.CAP_DSHOW的1改为0)

使用方法:
根据作品的安装说明来进行安装相应的编译器,打开摄像头,进行功能执行时将手心对准摄像头。

详细的功能执行操作如下:

  1. 利用改变大拇指和食指间的距离来改变电脑音量的大小。
  2. 将食指和中指竖起时,两指间的中心坐标会作为鼠标的坐标来控制鼠标的移动。并且两指贴合时,执行鼠标一直单击左键的功能。
  3. 当大拇指,食指和中指同时竖起时,执行鼠标的单击左键的功能。
  4. 仅大拇指未竖起时,执行鼠标的单击右键的功能。
  5. 当只有食指竖起时,执行鼠标的滑轮向上的功能,反之,执行鼠标的滑轮向下的功能。
  6. 当五指全都竖起时,向左(右)移动一定距离时,每隔0.5秒执行的键盘的左(右)方向键的功能。

这里是手部方法的代码 

import cv2
import math
import mediapipe as mdclass HandDetector():def __init__(self):self.hand_detector = md.solutions.hands.Hands()self.length = 0self.label = "Right"def hand(self, img, draw=True):img_Rgb = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) #改变视频色彩self.hand_date = self.hand_detector.process(img_Rgb)if draw:if self.hand_date.multi_hand_landmarks:for handlms in self.hand_date.multi_hand_landmarks:md.solutions.drawing_utils.draw_landmarks(img, handlms, md.solutions.hands.HAND_CONNECTIONS)def hand_position(self, img):h, w, c = img.shapeself.position = {'Left': {}, 'Right': {}}  #定义一个字典if self.hand_date.multi_hand_landmarks:i = 0for point in self.hand_date.multi_handedness:score = point.classification[0].scoreif score > 0.8:                             #大于百分之八十是哪只手self.label = point.classification[0].labelhand_lms = self.hand_date.multi_hand_landmarks[i].landmarkfor id, lm in enumerate(hand_lms):x, y = int(lm.x * w), int(lm.y * h)self.position[self.label][id] = (x, y)#print(label)    #输出是那只手i =i + 1return self.position, self.labeldef finger_up(self, hand='Left'):  #输出竖起手的数量self.tips = {4, 8, 12, 16, 20}self.tips_count = {4: 0, 8: 0, 12: 0, 16: 0, 20: 0}for tip in self.tips:self.tip1 = self.position[hand].get(tip, None)self.tip2 = self.position[hand].get(tip-2, None)if self.tip1 and self.tip2:if tip == 4:if self.tip1[0] > self.tip2[0]:if hand == 'Left':self.tips_count[tip] = 1else:self.tips_count[tip] = 0else:if hand == 'Left':self.tips_count[tip] = 0else:self.tips_count[tip] = 1else:if self.tip1[1] > self.tip2[1]:self.tips_count[tip] = 0else:self.tips_count[tip] = 1return list(self.tips_count.values()).count(1), self.tips_countdef handtips_distance(self, img, rp1, rp2, hand = 'Right'):  #测量两指间的距离self.length = 0#cx, cy = 0, 0Right_finger1 = self.position[hand].get(rp1, None)Right_finger2 = self.position[hand].get(rp2, None)if Right_finger1 and Right_finger2:cv2.circle(img, (Right_finger1[0], Right_finger1[1]), 10, (255, 0, 0), cv2.FILLED)cv2.circle(img, (Right_finger2[0], Right_finger2[1]), 10, (255, 0, 0), cv2.FILLED)cv2.line(img, Right_finger1, Right_finger2, (144, 0, 255))x1, y1 = Right_finger1[0], Right_finger1[1]x2, y2 = Right_finger2[0], Right_finger2[1]#cx, cy = (x1 + x2) // 2, (y1 + y2) // 2self.length = math.hypot((x2 - x1), (y2 - y1))return self.length

主函数

import cv2
import pyautogui as pb
from HandWay import HandDetector
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
import numpy as nb
import math, timecamera = cv2.VideoCapture(1, cv2.CAP_DSHOW) #使用摄像头,视屏捕捉
camera.set(3, 1080)  #设置摄像头屏幕的大小
camera.set(4, 720)
hand_detector = HandDetector()
devices = AudioUtilities.GetSpeakers() #初始化windows音频控制对象
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None) #调用系统的音频控制接口
volume = cast(interface, POINTER(IAudioEndpointVolume))
volRange = volume.GetVolumeRange() #获取电脑音量范围
frameR = 50
plocx, plocy = 0, 0
finger_count = {'Left': {}, 'Right': {}}
tip = {'Left': {4: 0, 8: 0, 12: 0, 16: 0, 20: 0}, 'Right': {4: 0, 8: 0, 12: 0, 16: 0, 20: 0}}
#获取电脑最大最小音量
minVol = volRange[0]
maxVol = volRange[1]while True:success, img = camera.read() #获取是否读成功和视频帧if success:h, w, c = img.shape  #获取摄像头的屏幕大小h1, w1 = pb.size()   #获取电脑屏幕的大小#print(h1, w1)x, y = pb.position()#print(x, y)img = cv2.flip(img, 1)hand_detector.hand(img, draw=False)position, label = hand_detector.hand_position(img)  #获取手部的信息center = hand_detector.position[label].get(0, None)finger_count[label], tip[label] = hand_detector.finger_up(label) #获取竖起的手指数量和哪只手指是否竖起left_finger_count, tip['Left'] = hand_detector.finger_up('Left')#  print(left_finger_count)cv2.putText(img, str(left_finger_count), (100, 150), cv2.FONT_HERSHEY_DUPLEX, 5, (0, 0, 255), 3)right_finger_count, tip['Right'] = hand_detector.finger_up('Right')#  print(right_finger_count)cv2.putText(img, str(right_finger_count), (w - 200, 150), cv2.FONT_HERSHEY_DUPLEX, 5, (255, 0, 255), 3)hand_length1 = hand_detector.handtips_distance(img, 8, 12, label)#  print(hand_length1)hand_length2 = hand_detector.handtips_distance(img, 4, 8, label)if tip[label][4] == 1 and tip[label][8] == 1 and finger_count[label] == 2: #当大拇指和食指竖起时,改变两指间的距离来调整音量大小vol = nb.interp(hand_length2, [40, 250], [minVol, maxVol])print(tip[label][4])print(vol, hand_length2)volume.SetMasterVolumeLevel(vol, None)if finger_count[label] == 5:  #当五指全部竖起时,掌心的横坐标向左或右超过某一值时,将执行向左或右的键盘功能if label == 'Right':if center[0] > w - 300:time.sleep(0.5)pb.press('right')print("Right")else:if center[0] < w - 460:time.sleep(0.5)pb.press('left')print("Left")else:print("center")else:if label == 'Left':if center[0] < 250:pb.press('left')print("Left")else:if center[0] > 360:pb.press('right')print("Right")else:print("center")Right_roll = hand_detector.position[label].get(8, None) #得到食指的相关信息if Right_roll:rx, ry = Right_roll[0], Right_roll[1]if tip[label][8] == 0 and finger_count[label] == 0: #只有食指竖起时,执行鼠标向上滑动的功能,反之向下pb.scroll(-50, x, y)print("down")else:if tip[label][8] == 1 and finger_count[label] == 1:pb.scroll(50, x, y)print("up")Right_finger1 = hand_detector.position[label].get(8, None)Right_finger2 = hand_detector.position[label].get(12, None)"""hand_length3 = hand_detector.handtips_distance(img, 9, 12)hand_length4 = hand_detector.handtips_distance(img, 0, 9)hand_length5 = hand_detector.handtips_distance(img, 0, 12)hand_length6 = hand_detector.handtips_distance(img, 5, 8)hand_length7 = hand_detector.handtips_distance(img, 0, 5)hand_length8 = hand_detector.handtips_distance(img, 0, 8)"""if Right_finger1 and Right_finger2:cx = (Right_finger1[0] + Right_finger2[0]) // 2  #得到食指和中指的中心坐标cy = (Right_finger1[1] + Right_finger2[1]) // 2tx = nb.interp(cx, (frameR, w - frameR), (0, w1))  #转化为屏幕坐标ty = nb.interp(cy, (frameR, h - frameR), (0, h1))#print(cx, cy)输出中点坐标if tip[label][8] == 1 and tip[label][12] == 1 and finger_count[label] == 2:  #当左手或右手的食指和中指竖起时,通过两指的指尖中心的坐标来控制移动鼠标pb.FAILSAFE = Falsetip_x = (plocx + (tx - plocx)) * 2tip_y = plocy + (ty - plocy)time.sleep(0.01)pb.moveTo(tip_x, tip_y)plocx, plocy = tip_x, tip_y  #记录上次的位置if hand_length1 < 52:  #当两指的指尖距离小于52mm时一直执行鼠标的单击功能pb.mouseDown(button='left')print("first")cv2.circle(img, (cx, cy), 15, (144, 144, 144), cv2.FILLED)else:pb.mouseUp(button='left')#当食指和中指以及大拇指竖起时,执行鼠标的左键点击:if tip[label][4] == 1 and tip[label][8] == 1 and tip[label][12] == 1 and finger_count[label] == 3: pb.leftClick()print("Left")#当食指和中指以及无名指和小拇指竖起时,执行鼠标的右键点击if tip[label][8] == 1 and tip[label][12] == 1 and tip[label][16] == 1 and tip[label][20] == 1 and finger_count[label] == 4:pb.rightClick()print("Right")cv2.imshow('Hand', img)   #视频窗口if cv2.waitKey(1) & 0XFF == 27:   #按下Esc按键退出breakcamera.release()
cv2.destroyAllWindows()

作品思路

首先,确认作品的大致的框架和方向,选择需要的编译语言和相应的编译软件。再确认完成后,选择了Python语言。在网上搜索并确认所需的Python库和使用方法。

  1. 根据作品的概念设计上使用opencv和mediapipa这两个库的方法并进行初步的测试了解后,开始设计大致的判断方法以及对信息的获取。然后设计相应的实现代码测量并改进。
  2. 开始查询并设计控制系统的功能。根据作品大致的框架和概念设计来进行控制系统的功能设计,并在网上查询对应的库和使用方法。开始设计代码
  3. 测试代码的效果。
  4. 完善系统的功能,提升执行效果。

作品应用场景:

可以适用于多媒体教学的智能教育方面,在课上可以利用手的移动来去移动PPT来更方便教学,以及画图和划重点时可以不用往返移动。

日常的观看电视剧或者其他视频不方便用手时,就可以利用本操作系统来去进行快进,改变音量等操作。

设计理念:

利用手部的一些简单的动作来执行在生活中常用的一些基本操作,能更加方便来解决和提高生活中的问题和趣味性。利用手指的竖起和放下的简单操作和摄像头的捕捉和识别来隔空操作电脑

技术方案:

主要利用Python语言中的Opencv库来打开并控制电脑摄像头,pyautogui库来控制鼠标的移动和简单按键,mediapipa库来识别手部的信息和使用mediapipa库中的solution方法来对手部信息进行识别和获取。使用pycaw库来获取Windows电脑音频控制,并使用comtypes库来调用系统的音频控制接口。Ctypes库提供了与 C 兼容的数据类型,并允许调用 DLL 或共享库中的函数。可使用该模块以纯 Python 形式对这些库进行封装。


http://www.ppmy.cn/news/521385.html

相关文章

模糊控制在matlab的实现,模糊控制系统的MATLAB实现

基于MATLAB 的模糊控制器设计及仿真 专业:学号:姓名:控制科学与工程 [1**********]7 许兴培 摘 要 在深入了解系统的基础上针对传统控制精度不高、系统稳定性差的问题进行创新和探索研究详细介绍了模糊控制原理和实现步骤。并在MATLAB 环境下对完成了模糊控制器仿真研究 发现…

控制系统的振荡

今天调试某个三闭环控制系统&#xff0c;从内到外依次是电流闭环、流速闭环、压力闭环&#xff0c;当调试好电流闭环、流速闭环&#xff0c;经过阶跃测试和正弦测试都OK&#xff0c;稳定性也OK。但是&#xff0c;当加上压力外环&#xff0c;系统开始变得不稳定&#xff0c;开始…

控制系统的传递函数

【自控笔记】2.4 控制系统的复域数学模型 一、传递函数的定义 二、传递函数的性质 拉普拉斯变换是一种线性变换&#xff0c;所以传递函数只适用于描述线性定常系统&#xff0c;并且只适用于零初始条件情况下&#xff0c;对于非零初始条件可将初始条件看作输入使用。传递函数的…

基于多传感器的AUV控制系统

摘 要 微小型AUV具有体积小&#xff0c;灵活性高、隐蔽性好等特点&#xff0c;可以工作于其它大型水下机器人无法进入的区域。民用上可以应用于海洋矿产勘探、海底地形探测&#xff0c;沉船打捞&#xff0c;水下考古&#xff0c;海洋生物探测等&#xff1b;军事上可以用来反…

计算机控制系统笔记

蓝皮第二版 刘建昌 科学出版社 18 自动化的夏zy同学&#xff0c;请不要再卷了&#xff0c;你都会了。 这些题可以看看 为了及格&#xff0c;加油。 第一章 什么是计算机控制系统 较模拟系统有何优点 由计算机参与并作为核心环节的自动控制系统。 设计控制灵活&#xff0c;能实…

DCS分布式控制系统总结

背景 今天大学同学群里讨论DCS项目的问题&#xff0c;因之前工作中&#xff0c;相关工控系统多依赖于首钢自动化公司来实现&#xff0c;关于DCS的应用&#xff0c;没过多关注&#xff0c;特此翻看相关资料&#xff0c;记录总结。 DCS是什么 DCS是分布式控制系统的英文缩写&a…

伺服控制系统

本文非原创&#xff0c;内容摘自网络&#xff0c;文末注明出处&#xff0c;侵权必删&#xff01; 伺服电机为了达到生产的精准控制,电机一般采用三环控制,这主要是为了使伺服电机系统形成闭环控制&#xff0c;所谓三环就是3个闭环负反馈PID调节系统。电压映射电流变化&#xff…

PLC温室大棚自动控制系统

河北机电职业技术学院 毕 业 论 文 基于PLC的温室大棚自动控制系统 姓 名 马锡鹏 班 级 1203班 学 号 030523120323 专 业 机电一体化技术 指导教师 高健 电 气 工 程 系 二○一五年六月 基于PLC的温室大棚自动控制系统 摘 要 植物生长讲究适时、适地&#xff0c;也就是对生长环…