Opencv实现眼睛控制鼠标的实践

如何用眼睛来控制鼠标?一种基于单一前向视角的机器学习眼睛姿态估计方法。在此项目中,每次单击鼠标时,我们都会编写代码来裁剪你们的眼睛图像。使用这些数据,我们可以反向训练模型,从你们您的眼睛预测鼠标的位置。在开始项目之前,我们需要引入第三方库。

# For monitoring web camera and performing image minipulations
import cv2
# For performing array operations
import numpy as np
# For creating and removing directories
import os
import shutil
# For recognizing and performing actions on mouse presses
from pynput.mouse import Listener

首先让我们了解一下Pynput的Listener工作原理。pynput.mouse.Listener创建一个后台线程,该线程记录鼠标的移动和鼠标的点击。这是一个简化代码,当你们按下鼠标时,它会打印鼠标的坐标:

from pynput.mouse import Listener
def on_click(x, y, button, pressed):
"""
  Args:
    x: the x-coordinate of the mouse
    y: the y-coordinate of the mouse
    button: 1 or 0, depending on right-click or left-click
    pressed: 1 or 0, whether the mouse was pressed or released
  """
if pressed:
print (x, y)
with Listener(on_click = on_click) as listener:
  listener.join()

现在,为了实现我们的目的,让我们扩展这个框架。但是,我们首先需要编写裁剪眼睛边界框的代码。我们稍后将在on_click函数内部调用此函数。我们使用Haar级联对象检测来确定用户眼睛的边界框。你们可以在此处下载检测器文件,让我们做一个简单的演示来展示它是如何工作的:

import cv2
# Load the cascade classifier detection object
cascade = cv2.CascadeClassifier("haarcascade_eye.xml")
# Turn on the web camera
video_capture = cv2.VideoCapture(0)
# Read data from the web camera (get the frame)
_, frame = video_capture.read()
# Convert the image to grayscale
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Predict the bounding box of the eyes
boxes = cascade.detectMultiScale(gray, 1.3, 10)
# Filter out images taken from a bad angle with errors
# We want to make sure both eyes were detected, and nothing else
if len(boxes) == 2:
eyes = []
for box in boxes:
    # Get the rectangle parameters for the detected eye
x, y, w, h = box
    # Crop the bounding box from the frame
eye = frame[y:y + h, x:x + w]
    # Resize the crop to 32x32
eye = cv2.resize(eye, (32, 32))
    # Normalize
eye = (eye - eye.min()) / (eye.max() - eye.min())
    # Further crop to just around the eyeball
eye = eye[10:-10, 5:-5]
    # Scale between [0, 255] and convert to int datatype
eye = (eye * 255).astype(np.uint8)
    # Add the current eye to the list of 2 eyes
eyes.append(eye)
  # Concatenate the two eye images into one
eyes = np.hstack(eyes)

现在,让我们使用此知识来编写用于裁剪眼睛图像的函数。首先,我们需要一个辅助函数来进行标准化:

def normalize(x):
  minn, maxx = x.min(), x.max()
return (x - minn) / (maxx - minn)

这是我们的眼睛裁剪功能。如果发现眼睛,它将返回图像。否则,它返回None:

def scan(image_size=(32, 32)):
_, frame = video_capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
boxes = cascade.detectMultiScale(gray, 1.3, 10)
if len(boxes) == 2:
eyes = []
for box in boxes:
x, y, w, h = box
eye = frame[y:y + h, x:x + w]
eye = cv2.resize(eye, image_size)
eye = normalize(eye)
eye = eye[10:-10, 5:-5]
eyes.append(eye)
return (np.hstack(eyes) * 255).astype(np.uint8)
else:
return None

现在,让我们来编写我们的自动化,该自动化将在每次按下鼠标按钮时运行。(假设我们之前已经root在代码中将变量定义为我们要存储图像的目录):

def on_click(x, y, button, pressed):
# If the action was a mouse PRESS (not a RELEASE)
if pressed:
# Crop the eyes
    eyes = scan()
# If the function returned None, something went wrong
if not eyes is None:
# Save the image
      filename = root + "{} {} {}.jpeg".format(x, y, button)
      cv2.imwrite(filename, eyes)

现在,我们可以回忆起pynput的实现Listener,并进行完整的代码实现:

import cv2
import numpy as np
import os
import shutil
from pynput.mouse import Listener

root = input("Enter the directory to store the images: ")
if os.path.isdir(root):
  resp = ""
while not resp in ["Y", "N"]:
    resp = input("This directory already exists. If you continue, the contents of the existing directory will be deleted. If you would still like to proceed, enter [Y]. Otherwise, enter [N]: ")
if resp == "Y":
    shutil.rmtree(root)
else:
    exit()
os.mkdir(root)

# Normalization helper function
def normalize(x):
  minn, maxx = x.min(), x.max()
return (x - minn) / (maxx - minn)

# Eye cropping function
def scan(image_size=(32, 32)):
  _, frame = video_capture.read()
  gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  boxes = cascade.detectMultiScale(gray, 1.3, 10)
if len(boxes) == 2:
    eyes = []
for box in boxes:
      x, y, w, h = box
      eye = frame[y:y + h, x:x + w]
      eye = cv2.resize(eye, image_size)
      eye = normalize(eye)
      eye = eye[10:-10, 5:-5]
      eyes.append(eye)
return (np.hstack(eyes) * 255).astype(np.uint8)
else:
return None

def on_click(x, y, button, pressed):
# If the action was a mouse PRESS (not a RELEASE)
if pressed:
# Crop the eyes
    eyes = scan()
# If the function returned None, something went wrong
if not eyes is None:
# Save the image
      filename = root + "{} {} {}.jpeg".format(x, y, button)
      cv2.imwrite(filename, eyes)

cascade = cv2.CascadeClassifier("haarcascade_eye.xml")
video_capture = cv2.VideoCapture(0)

with Listener(on_click = on_click) as listener:
  listener.join()

运行此命令时,每次单击鼠标(如果两只眼睛都在视线中),它将自动裁剪网络摄像头并将图像保存到适当的目录中。图像的文件名将包含鼠标坐标信息,以及它是右击还是左击。

这是一个示例图像。在此图像中,我在分辨率为2560x1440的监视器上在坐标(385,686)上单击鼠标左键:

级联分类器非常准确,到目前为止,我尚未在自己的数据目录中看到任何错误。现在,让我们编写用于训练神经网络的代码,以给定你们的眼睛图像来预测鼠标的位置。

import numpy as np
import os
import cv2
import pyautogui
from tensorflow.keras.models import *
from tensorflow.keras.layers import *
from tensorflow.keras.optimizers import *

现在,让我们添加级联分类器:

cascade = cv2.CascadeClassifier("haarcascade_eye.xml")
video_capture = cv2.VideoCapture(0)

正常化:

def normalize(x):
  minn, maxx = x.min(), x.max()
return (x - minn) / (maxx - minn)

捕捉眼睛:

def scan(image_size=(32, 32)):
_, frame = video_capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
boxes = cascade.detectMultiScale(gray, 1.3, 10)
if len(boxes) == 2:
eyes = []
for box in boxes:
x, y, w, h = box
eye = frame[y:y + h, x:x + w]
eye = cv2.resize(eye, image_size)
eye = normalize(eye)
eye = eye[10:-10, 5:-5]
eyes.append(eye)
return (np.hstack(eyes) * 255).astype(np.uint8)
else:
return None

让我们定义显示器的尺寸。你们必须根据自己的计算机屏幕的分辨率更改以下参数:

# Note that there are actually 2560x1440 pixels on my screen
# I am simply recording one less, so that when we divide by these
# numbers, we will normalize between 0 and 1. Note that mouse
# coordinates are reported starting at (0, 0), not (1, 1)
width, height = 2559, 1439

现在,让我们加载数据(同样,假设你们已经定义了root)。我们并不在乎是单击鼠标右键还是单击鼠标左键,因为我们的目标只是预测鼠标的位置:

filepaths = os.listdir(root)
X, Y = [], []
for filepath in filepaths:
x, y, _ = filepath.split(' ')
x = float(x) / width
y = float(y) / height
X.append(cv2.imread(root + filepath))
Y.append([x, y])
X = np.array(X) / 255.0
Y = np.array(Y)
print (X.shape, Y.shape)

让我们定义我们的模型架构:

model = Sequential()
model.add(Conv2D(32, 3, 2, activation = 'relu', input_shape = (12, 44, 3)))
model.add(Conv2D(64, 2, 2, activation = 'relu'))
model.add(Flatten())
model.add(Dense(32, activation = 'relu'))
model.add(Dense(2, activation = 'sigmoid'))
model.compile(optimizer = "adam", loss = "mean_squared_error")
model.summary()

这是我们的摘要:

接下来的任务是训练模型。我们将在图像数据中添加一些噪点:

epochs = 200
for epoch in range(epochs):
  model.fit(X, Y, batch_size = 32)

现在让我们使用我们的模型来实时移动鼠标。请注意,这需要大量数据才能正常工作。但是,作为概念证明,你们会注意到,实际上只有200张图像,它确实将鼠标移到了你们要查看的常规区域。当然,除非你们拥有更多的数据,否则这是不可控的。

while True:
  eyes = scan()
if not eyes is None:
      eyes = np.expand_dims(eyes / 255.0, axis = 0)
      x, y = model.predict(eyes)[0]
      pyautogui.moveTo(x * width, y * height)

这是一个概念证明的例子。请注意,在进行此屏幕录像之前,我们只训练了很少的数据。这是我们的鼠标根据眼睛自动移动到终端应用程序窗口的视频。就像我说的那样,这很容易,因为数据很少。有了更多的数据,它有望稳定到足以以更高的特异性进行控制。仅用几百张图像,你们就只能将其移动到注视的整个区域内。另外,如果在整个数据收集过程中,你们在屏幕的特定区域(例如边缘)都没有拍摄任何图像,则该模型不太可能在该区域内进行预测。

到此这篇关于Opencv实现眼睛控制鼠标的实践的文章就介绍到这了,更多相关Opencv 眼睛控制鼠标内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++&&Opencv实现控制台字符动画的方法

    原理概述 首先利用opencv获取到图片中特定像素点的颜色 根据颜色所处的范围选择不同的字符 再在控制台的特定位置打印即可 重点就是获取像素点的颜色 获取图像中某像素点的颜色图片载入变量 opencv中可使用Mat类型来储存图片 Mat img; img = imread("图片路径"); 将图片转化为灰度图 为什么要把图片转为灰度图呢? 主要是为了使图片颜色单一 减少后面条件判断的工作量 不过也可以不去做这一步的处理 Mat gimg; //img转化为灰度图后输出到gimg中 cv

  • Opencv实现视频播放与进度控制

    视频画面本质上是由一帧一帧的连续图像组成的,播放视频其实就是在播放窗口把一系列连续图像按一定的时间间隔一幅幅贴上去实现的. 人眼在连续图像的刷新最少达到每秒24帧的时候,就分辨不出来图像间的闪动了,使人感觉呈现出来的是连续的画面,视频的播放就是利用了这一点.我们知道,电影被称为"24帧的艺术",意思就是电影画面每秒刷新24帧,即每秒显示24副图像,它的帧率(Frames per Second,简称:FPS)为24. 一般情况下帧率要大于等于24,以下先测试一下两个视频文件的帧率,一个是

  • Python摸鱼神器之利用树莓派opencv人脸识别自动控制电脑显示桌面

    前言 老早就看到新闻员工通过人脸识别监控老板来摸鱼. 有时候摸鱼太入迷了,经常在上班时间玩其他的东西被老板看到.自从在咸鱼上淘了一个树莓派3b,尝试做了一下内网穿透,搭建网站就吃灰了,接下来突发奇想就买了一个摄像头和延长线 接下来就是敲代码了 环境 树莓派3+ python3.7 win7 python3.6 过程 首先树莓派和电脑要在一个内网下面,就是一个路由器下面吧.要在树莓派设置里面开启摄像头,然后安装cv2,cv2有很多依赖库需要手动安装,很是费脑筋.原理介绍一下,人脸识别主要是依赖op

  • Opencv实现眼睛控制鼠标的实践

    如何用眼睛来控制鼠标?一种基于单一前向视角的机器学习眼睛姿态估计方法.在此项目中,每次单击鼠标时,我们都会编写代码来裁剪你们的眼睛图像.使用这些数据,我们可以反向训练模型,从你们您的眼睛预测鼠标的位置.在开始项目之前,我们需要引入第三方库. # For monitoring web camera and performing image minipulations import cv2 # For performing array operations import numpy as np #

  • 用VBS控制鼠标的实现代码(获取鼠标坐标、鼠标移动、鼠标单击、鼠标双击、鼠标右击)

    怎么用VBS模拟鼠标左键单击.左键双击.右键单击?-- 网上搜到的答案普遍是VBS无法实现,或者是要用第三方COM(ActiveX?)组件.我对第三方组件是很反感的,使用第三方组件毫无可移植性可言,因为别人的系统中不一定注册了这个组件.我的建议是,尽量不要在VBS代码中调用第三方组件,除非你的程序只是写来自己用.(顺便说一下,也尽量不要用不靠谱的Sendkeys方法,原因不解释) 好了,废话就说这么多,现在说说用VBS控制鼠标的方法.我以前写过一篇<VBS调用Windows API函数>,本以

  • 一段眼睛跟着鼠标转动的跟踪眼代码

    复制代码 代码如下: import java.applet.Applet; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import net.java2000.tools.NoNull; /** * 一段眼睛跟着鼠标转动的跟踪眼代码.<br> * 你可以单独运行,或者放在html里面<br&g

  • 深入Java Robot实现控制鼠标和键盘的方法详解

    Java.awt.Robot 类用于控制鼠标和键盘.一旦你得到这种控制,你能够通过你的Java代码做与鼠标和键盘任何类型的操作.这个类通常用于自动化测试.下面的代码样例将向您展示Robot类如何处理键盘事件.如果你运行此代码,并打开notepad,您将在notepad中看到HI CAOER.赶快试一试吧. 复制代码 代码如下: import java.awt.AWTException;import java.awt.Robot;import java.awt.event.KeyEvent;pub

  • java通过控制鼠标实现屏幕广播的方法

    本文实例讲述了java通过控制鼠标实现屏幕广播的方法.分享给大家供大家参考.具体分析如下: 在前面一篇<java实现屏幕共享功能实例分析>中提到截取屏幕时是没鼠标,为了看到教师端界面上的鼠标,可以在截取屏幕的时候,把鼠标绘制到每一张截图上去,但是由于截图的时候是一张张截取的,所以看到的鼠标难免会有点卡,之前写了java鼠标操控小程序,可以通过这种方式来看到鼠标的演示. 实现的方式也挺简单的,前面两篇文章分别实现了鼠标控制和不带鼠标的屏幕分享功能,把这两个结合一下就ok了,下面简单分析下. 服务

  • JS控制鼠标拒绝点击某一按钮的实例

    JS控制按钮禁止被选择 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script> window.onload=function(){ document.getElementById("s").onmouseover=function

  • Python PyAutoGUI模块控制鼠标和键盘实现自动化任务详解

    本文实例讲述了Python PyAutoGUI模块控制鼠标和键盘实现自动化任务.分享给大家供大家参考,具体如下: PyAutoGUI是用Python写的一个模块,使用它可以控制鼠标和键盘. 利用它可以实现自动化任务,再也不用担心有重复枯燥的任务了. pyautogui模块的功能: 移动鼠标.点击左右键和滚轮 发送虚拟按键 # 安装pyautogui 这个模块支持Windows, Mac OS X 和 Linux. 根据系统不同,你可能需要安装一些依赖. Linux系统(Debian系列): $

  • Python小程序 控制鼠标循环点击代码实例

    这篇文章主要介绍了Python小程序 控制鼠标循环点击代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 from ctypes import * import pyautogui import time time.sleep(5) while 1: pyautogui.click(400, 400, clicks=1, interval=0.0, button='left') time.sleep(10) Note: 坐标(400,400

  • python实现键盘控制鼠标移动

    玩QQ桌球游戏时,有时候用鼠标控制鼠标指针的微小移动比较费劲儿,所以想写个程序,可以用键盘的上下左右键来控制鼠标的移动,每次只移动一个像素. 本脚本依赖pywin32.pyHook和pymouse这两个库,请自行安装.代码中的pythoncom是pywin32库的一部分,运行脚本后,即可通过键盘的上下左右键控制鼠标移动了. # -*- coding:utf-8 -*- # 左37 上38 右39 下40 import pythoncom import pyHook from pymouse im

  • pyautogui自动化控制鼠标和键盘操作的步骤

    PyAutoGUI是一个纯Python的GUI自动化工具,其目的是可以用程序自动控制鼠标和键盘操作,多平台支持(Windows,OS X,Linux). 安装 pip3 install pyautogui pyautogui鼠标操作样例 import pyautogui # 获取当前屏幕分辨率 screenWidth, screenHeight = pyautogui.size() # 获取当前鼠标位置 currentMouseX, currentMouseY = pyautogui.posit

随机推荐