0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何手势控制鼠标

454398 来源:wv 2019-08-30 11:20 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

步骤1:安装Anaconda和需要的软件包

Anaconda本质上是一个包装精美的Python IDE,随附了大量有用的软件包,如NumPy,Pandas,IPython笔记本等似乎在科学界的各个地方都值得推荐。查看Anaconda以安装它。

所需的软件包:

PyAutoGUI

OpenCv

安装上述软件包:

OpenCV:

点击此链接逐步安装for opencv

PyAutoGUI:

PyAutoGUI是一个Python模块,用于以编程方式控制鼠标和键盘。

PyAutoGUI可以从 pip 工具中安装

打开你的anaconda命令提示并粘贴它:

pip install PyAutoGUI

现在我们准备好了代码。..。..

第2步:技术概述

它本质上是一个程序,它应用图像处理,检索必要的数据,并根据预定义的概念将其实现到计算机的鼠标接口

代码是用Python编写的。它使用跨平台图像处理模块OpenCV,并使用Python特定库PyAutoGUI实现鼠标操作。

处理网络摄像头的视频捕获,仅提取三个彩色指尖。他们的中心是用矩量法计算的,根据它们的相对位置决定要执行什么动作。

第3步:视频入门

目标一:

cv2.VideoCapture()

从中捕获视频相机

通常,我们必须使用相机捕捉直播。 OpenCV为此提供了一个非常简单的接口。让我们从相机中捕捉视频(我正在使用笔记本电脑的内置网络摄像头),将其转换为灰度视频并显示它。入门只是一项简单的任务。要捕获视频,您需要创建一个VideoCapture对象。它的参数可以是设备索引或视频文件的名称。设备索引只是指定哪个摄像头的数量。通常会连接一台摄像机(如我的情况)。所以我只传递0(或-1)。您可以通过传递1来选择第二个摄像头,依此类推。之后,您可以逐帧捕获。但最后,不要忘记发布捕获。

我们要做的第一件事就是将捕获的视频转换为HSV格式。

代码:

# All packages needed for the program are imported ahead

import cv2

cap = cv2.VideoCapture(0)

while(1):

# Capture frame-by-frame

_, frameinv = cap.read()

# flip horizontaly to get mirror image in camera

frame = cv2.flip( frameinv, 1)

# Our operations on the frame come here

hsv = cv2.cvtColor( frame, cv2.COLOR_BGR2HSV)

# Display the resulting frame

cv2.imshow(‘Frame’, hsv)

k = cv2.waitKey(10) & 0xFF

if k == 27:

break

cap.release()

cv2.destroyAllWindows()

第4步:颜色范围

目标二:

calibrateColor()

校准颜色范围

现在,用户可以分别校准他的三个手指的颜色范围。这可以通过在程序开头三次调用 calibrateColor()函数来完成。

用户也可以选择使用默认设置。

代码:

import cv2

import numpy as np

def nothing(x):

pass

# Create a black image, a window

kernel = np.zeros((300,512,3), np.uint8)

name = ‘Calibrate’

cv2.namedWindow(name)

# create trackbars for color change

cv2.createTrackbar(‘Hue’, name, 0, 255, nothing)

cv2.createTrackbar(‘Sat’, name, 0, 255, nothing)

cv2.createTrackbar(‘Val’, name, 0, 255, nothing)

# create switch for ON/OFF functionality

switch = ‘0 : OFF 1 : ON’

cv2.createTrackbar(switch, name,0,1,nothing)

while(1):

cv2.imshow(name,kernel)

k = cv2.waitKey(1) & 0xFF

if k == 27:

break

# get current positions of four trackbars

hue = cv2.getTrackbarPos(‘Hue’, name)

sat = cv2.getTrackbarPos(‘Sat’, name)

val = cv2.getTrackbarPos(‘Val’, name)

s = cv2.getTrackbarPos(switch,name)

if s == 0:

kernel[:] = 0

else:

kernel[:] = [hue,sat,val]

cv2.destroyAllWindows()

第5步:删除噪音&在视频源中定义函数

取决于校准,只使用 cv2.inRange()功能逐一从视频中提取三个指尖。为了消除视频输入中的噪声,我们应用两步态射,即侵蚀和扩张。 然后发送程序中称为掩码的噪声滤波图像以定位中心。

# cv2.inRange function is used to filter out a particular color from the frame

# The result then undergoes morphosis i.e. erosion and dilation

# Resultant frame is returned as mask

def makeMask(hsv_frame, color_Range):

mask = cv2.inRange( hsv_frame, color_Range[0], color_Range[1])

# Morphosis next 。..

eroded = cv2.erode( mask, kernel, iterations=1)

dilated = cv2.dilate( eroded, kernel, iterations=1)

return dilated

三个中心的位置包括:

在与该颜色范围相关的遮罩中查找轮廓。

使用区域过滤器丢弃不相关区域的轮廓。

在剩余的轮廓中找到最大的轮廓,并应用力矩的方法找到它的中心。

然后是定义光标在屏幕上的位置的步骤。黄色的拇指负责光标的位置。为此目的使用了以下技术:

通常我们使用的网络摄像头以640x480像素的分辨率捕获视频。假设此帧线性映射到1920x1080像素显示屏幕。如果我们有一个惯用右手的用户,他会发现与右边缘相比,访问屏幕的左边缘会感觉不舒服。访问屏幕的底部也会在手腕处产生压力。

我们意识到,不是将整个视频帧映射到屏幕,我们宁愿考虑更偏向右侧的矩形子部分(考虑右手用户)和帧的上部以便改进安慰。测量480x270像素的子部分然后以比例因子4线性映射到屏幕。

# Contours on the mask are detected.。 Only those lying in the previously set area

# range are filtered out and the centroid of the largest of these is drawn and returned

def drawCentroid(vid, color_area, mask, showCentroid):

contour, _ = cv2.findContours( mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

l=len(contour)

area = np.zeros(l)

# filtering contours on the basis of area rane specified globally

for i in range(l):

if cv2.contourArea(contour[i])》color_area[0] and cv2.contourArea(contour[i])

# bringing contours with largest valid area to the top

for i in range(l):

for j in range(1):

if area[i] == a[j]:

swap( contour, i, j)

if l 》 0 :

# finding centroid using method of ‘moments’

M = cv2.moments(contour[0])

if M[‘m00’] != 0:

cx = int(M[‘m10’]/M[‘m00’])

cy = int(M[‘m01’]/M[‘m00’])

center = (cx,cy)

if showCentroid:

cv2.circle( vid, center, 5, (0,0,255), -1)

return center

else:

# return error handling values

return (-1,-1)

由于网络摄像头捕获的噪声和手中的振动,中心保持不变围绕一个平均位置振动。在按比例放大时,这些振动会对光标位置的准确性产生很多问题。为了减少光标中的抖动,我们使用光标的差分位置分配。我们将新中心与光标的先前位置进行比较。如果差异小于5个像素,则通常是由于噪声。因此,新光标位置更倾向于前一个。但是,先前位置和新中心的较大差异被视为自愿移动,新光标位置设置为接近新中心。有关详细信息,请通过代码中的setCursorPosition()函数。

‘’‘

This function takes as input the center of yellow region (yc) and

the previous cursor position (pyp)。 The new cursor position is calculated

in such a way that the mean deviation for desired steady state is reduced.

’‘’

def setCursorPos( yc, pyp):

yp = np.zeros(2)

if abs(yc[0]-pyp[0])《5 and abs(yc[1]-pyp[1])《5:

yp[0] = yc[0] + .7*(pyp[0]-yc[0])

yp[1] = yc[1] + .7*(pyp[1]-yc[1])

else:

yp[0] = yc[0] + .1*(pyp[0]-yc[0])

yp[1] = yc[1] + .1*(pyp[1]-yc[1])

return yp

现在发送三个中心,根据

的相对位置决定需要执行哪些操作。这是在代码中的chooseAction()函数中完成的。根据其输出,performAction()函数使用PyAutoGUI库执行以下任一操作:

自由光标移动

左键单击

右键单击

拖动/选择

向上滚动

向下滚动

# Depending upon the relative positions of the three centroids, this function chooses whether

# the user desires free movement of cursor, left click, right click or dragging

def chooseAction(yp, rc, bc):

out = np.array([‘move’, ‘false’])

if rc[0]!=-1 and bc[0]!=-1:

if distance(yp,rc)《50 and distance(yp,bc)《50 and distance(rc,bc)《50 :

out[0] = ‘drag’

out[1] = ‘true’

return out

elif distance(rc,bc)《40:

out[0] = ‘right’

return out

elif distance(yp,rc)《40:

out[0] = ‘left’

return out

elif distance(yp,rc)》40 and rc[1]-bc[1]》120:

out[0] = ‘down’

return out

elif bc[1]-rc[1]》110:

out[0] = ‘up’

return out

else:

return out

else:

out[0] = -1

return out def performAction( yp, rc, bc, action, drag, perform):

if perform:

cursor[0] = 4*(yp[0]-110)

cursor[1] = 4*(yp[1]-120)

if action == ‘move’:

if yp[0]》110 and yp[0]《590 and yp[1]》120 and yp[1]《390:

pyautogui.moveTo(cursor[0],cursor[1])

elif yp[0]《110 and yp[1]》120 and yp[1]《390:

pyautogui.moveTo( 8 , cursor[1])

elif yp[0]》590 and yp[1]》120 and yp[1]《390:

pyautogui.moveTo(1912, cursor[1])

elif yp[0]》110 and yp[0]《590 and yp[1]《120:

pyautogui.moveTo(cursor[0] , 8)

elif yp[0]》110 and yp[0]《590 and yp[1]》390:

pyautogui.moveTo(cursor[0] , 1072)

elif yp[0]《110 and yp[1]《120:

pyautogui.moveTo(8, 8)

elif yp[0]《110 and yp[1]》390:

pyautogui.moveTo(8, 1072)

elif yp[0]》590 and yp[1]》390:

pyautogui.moveTo(1912, 1072)

else:

pyautogui.moveTo(1912, 8)

elif action == ‘left’:

pyautogui.click(button = ‘left’)

elif action == ‘right’:

pyautogui.click(button = ‘right’)

time.sleep(0.3)

elif action == ‘up’:

pyautogui.scroll(5)

# time.sleep(0.3)

elif action == ‘down’:

pyautogui.scroll(-5)

# time.sleep(0.3)

elif action == ‘drag’ and drag == ‘true’:

global y_pos

drag = ‘false’

pyautogui.mouseDown()

while(1):

k = cv2.waitKey(10) & 0xFF

changeStatus(k)

_, frameinv = cap.read()

# flip horizontaly to get mirror image in camera

frame = cv2.flip( frameinv, 1)

hsv = cv2.cvtColor( frame, cv2.COLOR_BGR2HSV)

b_mask = makeMask( hsv, blue_range)

r_mask = makeMask( hsv, red_range)

y_mask = makeMask( hsv, yellow_range)

py_pos = y_pos

b_cen = drawCentroid( frame, b_area, b_mask, showCentroid)

r_cen = drawCentroid( frame, r_area, r_mask, showCentroid)

y_cen = drawCentroid( frame, y_area, y_mask, showCentroid)

if py_pos[0]!=-1 and y_cen[0]!=-1:

y_pos = setCursorPos(y_cen, py_pos)

performAction(y_pos, r_cen, b_cen, ‘move’, drag, perform)

cv2.imshow(‘Frame’, frame)

if distance(y_pos,r_cen)》60 or distance(y_pos,b_cen)》60 or distance(r_cen,b_cen)》60:

break

pyautogui.mouseUp()

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 鼠标
    +关注

    关注

    6

    文章

    599

    浏览量

    41910
  • 手势控制
    +关注

    关注

    4

    文章

    44

    浏览量

    22224
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    一文读懂手势识别传感器:原理、优势与应用场景

    引言人机交互的方式正在经历深刻变革。从早期的物理按键到触摸屏,再到如今逐步普及的语音控制手势操作,人们与电子设备之间的沟通变得越来越自然直观。手势识别作为一种非接触式的交互手段,近年来在智能家居
    的头像 发表于 04-28 17:41 1098次阅读
    一文读懂<b class='flag-5'>手势</b>识别传感器:原理、优势与应用场景

    瑞芯微(EASY EAI)RV1126B 手势识别算法识别

    1.手势识别算法简介Gestures手势识别算法一种先进的姿势估计模型,使用关键点数据集进行训练,能够检测图像或视频中人物的21个关键点与26种手势,每个关键点代表手部的不同部位。该算法广泛应用
    的头像 发表于 04-07 10:36 150次阅读
    瑞芯微(EASY EAI)RV1126B <b class='flag-5'>手势</b>识别算法识别

    零知IDE——基于零知标准板驱动PAJ7620U2手势控制L9110风扇模块和SG90舵机系统

    控制器,结合PAJ7620U2手势传感器实现对L9110风扇模块和SG90舵机的智能控制。系统通过识别9种不同的手势动作(上下、左右、顺时针/逆时针、挥手、前推、后拉)分别
    发表于 01-06 11:56

    零知IDE——基于STM32F103RBT6的PAJ7620U2手势控制WS2812 RGB灯带系统

    先进的PAJ7620U2手势识别传感器和WS2812B RGB LED灯带,实现智能手势开关控制功能。系统能够实时检测手部在三维空间中的位置和运动轨迹,并将这些动作信息转换为直观、绚丽的灯光效果项目
    发表于 12-29 19:04

    零知IDE——基于STM32F103RBT6的PAJ7620U2手势控制WS2812 RGB灯带系统

    基于STM32F103RBT6的手势控制LED系统,通过PAJ7620U2传感器识别手势动作,驱动WS2812B灯带实现交互式灯光效果。系统采用软件I2C通信和SPI+DMA驱动方案,支持挥手开关机、手部位置跟踪及彩虹尾影效果。
    的头像 发表于 12-29 17:48 2126次阅读
    零知IDE——基于STM32F103RBT6的PAJ7620U2<b class='flag-5'>手势</b><b class='flag-5'>控制</b>WS2812 RGB灯带系统

    传统油烟机智能化升级之雷达手势感应唤醒控制方案

    唤醒和手势控制的目的 。 红海突围:小品牌的功能升级难题 油烟机市场早已是一片红海。头部品牌占据高端市场,小品牌若想在夹缝中生存,必须在产品力上做文章。在智能家居发展趋势下,加入微波雷达人体感应功能作为氛围灯的触
    的头像 发表于 11-12 09:28 618次阅读
    传统油烟机智能化升级之雷达<b class='flag-5'>手势</b>感应唤醒<b class='flag-5'>控制</b>方案

    基于STMicroelectronics AEK-SNS-2TOFM1手势检测系统的技术解析与应用实践

    STMicroelectronics AEK-SNS-2TOFM1预定义手势检测系统包括两个飞行时间测距传感器。这些传感器彼此距离23cm放置。车载SPC582B60E1微控制器读取传感器数据并检测预定义的手势/脚势。该解决方案
    的头像 发表于 10-29 16:07 823次阅读
    基于STMicroelectronics AEK-SNS-2TOFM1<b class='flag-5'>手势</b>检测系统的技术解析与应用实践

    【技术讨论】智能戒指手势交互:如何优化PCBA成本与实现<20ms低延迟?

    我们正在开发一款通过手势实时控制音乐的嵌入式可穿戴设备(架构如图:nRF5340主控 + ICM-42607 IMU)。希望重构听众与音乐之间的关系。在早期小批量生产中,我们面临两个核心挑战,希望
    发表于 10-18 13:04

    无需手持更灵活!纳祥科技智能帽夹灯方案(红外感应+手势控制

    控制技术,有效解决了传统手持电筒笨重、依赖手持操作的局限性。方案概述本方案以低功耗单片机为中枢,支持感应和常规2种工作模式:感应模式可通过红外对管实现手势识别,来
    的头像 发表于 10-10 15:09 698次阅读
    无需手持更灵活!纳祥科技智能帽夹灯方案(红外感应+<b class='flag-5'>手势</b><b class='flag-5'>控制</b>)

    XenG202G | 挥手手势识别参考设计(三维)

    WEMAKERFSMART-赋予万物感知的灵魂-矽典微ICLEGENDMICROXenG202G挥手手势识别(三维)毫米波传感器特征手势识别:非接触式控制,高精度手势动作识别,支持方向
    的头像 发表于 08-29 08:25 875次阅读
    XenG202G | 挥手<b class='flag-5'>手势</b>识别参考设计(三维)

    无线鼠标可以用充电宝充电吗?

    无线鼠标可通过充电宝续命,需考虑电池类型、接口匹配及功率适配。
    的头像 发表于 08-22 08:26 2162次阅读
    无线<b class='flag-5'>鼠标</b>可以用充电宝充电吗?

    基于LabVIEW的鼠标滑动方向检测教程

    本篇教程源于一位客户的真实需求,需要LabVIEW能够检测到鼠标滑动的方向,然后通过判断滑动方向处理后续的功能。
    的头像 发表于 07-30 13:51 1029次阅读
    基于LabVIEW的<b class='flag-5'>鼠标</b>滑动方向检测教程

    如何打造一个属于自己的手势识别应用

    上一期小编给大家介绍了和MediaPipe的相遇之路,本期小编将带着大家一起来动手,如何打造一个属于自己的手势识别应用。
    的头像 发表于 07-29 10:12 1295次阅读
    如何打造一个属于自己的<b class='flag-5'>手势</b>识别应用

    基于stm32和mpu9250的usb hid键盘、鼠标、游戏控制器实例打包下载

    基于stm32和mpu9250的usb hid键盘、鼠标、游戏控制器实例打包,推荐下载!
    发表于 05-29 21:44

    基于stm32和mpu9250的usb hid键盘、鼠标、游戏控制

    基于stm32和mpu9250的usb hid键盘、鼠标、游戏控制器 项目实例下载! 纯分享帖,需要者可点击附件免费获取完整资料~~~【免责声明】本文系网络转载,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请第一时间告知,删除内容!
    发表于 05-23 20:53