手绘舞者——使用OpenCV和MediaPipe实现手势控制鼠标

本文介绍了一个使用Python编写的程序,利用OpenCV处理视频,MediaPipe进行手部关键点检测,实现通过手势控制鼠标,适用于辅助技术、VR/AR、医疗保健等领域,提升用户体验和交互自由度。
摘要由CSDN通过智能技术生成

简介

        这个小的Python程序旨在通过手势识别实现鼠标控制,其中使用OpenCV进行视频处理,MediaPipe进行手部关键点检测,以及PyAutoGUI实现鼠标操作。


应用领域

  1. 辅助技术:

            对于那些因身体残障无法使用传统鼠标和键盘的用户,手势控制可以提供一种更自由和自主的交互方式。
  2. 虚拟现实和增强现实:

           在VR和AR环境中,手势控制可以为用户提供更自然的交互方式,使其能够直观地操控虚拟对象或界面元素。
  3. 医疗保健:

           在医疗领域,手势控制可以用于手术室内的触摸无感操作,也可以用于康复和运动疗法。
  4. 展示和演示:

           在展示和演示中,手势控制可以为演讲者或演员提供更生动和引人入胜的方式来交流和互动。
  5. 娱乐:

           在游戏和娱乐产业中,手势控制可以提高游戏的交互性,使玩家能够更深度地参与到游戏体验中。
  6. 手势操控HUD:

           头盔显示器(HUD)是一种将信息投射到驾驶员视野中的技术。手势控制可以用于操控HUD上显示的信息,例如接听电话、切换显示信息等。

涉及到的Python库

首先我们需要下载一下Python库

pyautogui

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ pyautogui

 mediapipe

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ mediapipe

OpenCV

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ opencv-python

下载就完事啦,兄弟们~~~


代码解析

(1)初始化

        初始化所需的库和变量。其中包括MediaPipe Hands模块、视频捕捉对象、帧率计算变量、屏幕尺寸和鼠标移动的阈值

        其中鼠标移动的阈值的设定是为了平衡对手势变化的敏感度和对手部微小运动的抵抗力,从而使鼠标的移动更加稳定、准确。

import cv2
import mediapipe as mp
import time
import pyautogui

mp_hands = mp.solutions.hands
hands = mp_hands.Hands()
mp_drawing = mp.solutions.drawing_utils

cap = cv2.VideoCapture(0)
fps_time = time.time()
screen_width, screen_height = pyautogui.size()
threshold = 10
smooth_duration = 0.25
hand_detected = False

(2)主循环

        通过OpenCV捕获实时视频流,然后在每个迭代中进行处理。使用MediaPipe Hands模块检测手部关键点,然后根据手指位置更新鼠标光标

while cap.isOpened():
    ret, frame = cap.read()

    # ...(帧处理的代码)

    cv2.imshow('Hand grasping', frame)

    if cv2.waitKey(1) & 0xFF == 27:
        break

(3)手部检测和鼠标控制

        在每个帧中,使用MediaPipe Hands模块检测手部关键点,提取食指位置,并将其映射到屏幕坐标。根据阈值检查手指移动,并使用PyAutoGUI平滑移动鼠标光标

results = hands.process(frame_rgb)

if results.multi_hand_landmarks:
    hand_landmarks = results.multi_hand_landmarks[0]

    index_finger = hand_landmarks.landmark[8]
    finger_x, finger_y = int((1 - index_finger.x) * screen_width), int(index_finger.y * screen_height)

    if abs(finger_x - pyautogui.position().x) > threshold or abs(finger_y - pyautogui.position().y) > threshold:
        pyautogui.moveTo(finger_x, finger_y, duration=smooth_duration)
    
    hand_detected = True
else:
    hand_detected = False

(4)手指骨骼可视化

        如果检测到手,脚本将手指关键点之间的骨骼可视化为线条,并显示在屏幕上。

        当然了,这里我只是为了观察演示的效果,实际部署到项目之中并不需要显示这些内容从而可以减免不必要的硬件算力损耗。

if results.multi_hand_landmarks:
    finger_points = [hand_landmarks.landmark[i] for i in [4, 8, 12, 16, 20]]

    for i in range(4):
        start_point = (int(finger_points[i].x * frame.shape[1]), int(finger_points[i].y * frame.shape[0]))
        end_point = (int(finger_points[i + 1].x * frame.shape[1]), int(finger_points[i + 1].y * frame.shape[0]))
        cv2.line(frame, start_point, end_point, (173, 186, 97), 2)

(5)结束和资源释放

        最后,当我们按下ESC键时,循环退出,并释放使用的资源。

        其实这里我还有一个想法就是通过判断是否保持握拳姿势5s来达到直接关闭程序的效果,但是我没有成功,如果大家可以研究出来的话,欢迎发到评论区讨论呀!~~

cap.release()
cv2.destroyAllWindows()

总体代码

那么总体可以运行的代码就如下所示啦

import cv2
import mediapipe as mp
import time
import pyautogui

# 初始化MediaPipe Hand模块
mp_hands = mp.solutions.hands
hands = mp_hands.Hands()
mp_drawing = mp.solutions.drawing_utils

# 打开摄像头
cap = cv2.VideoCapture(0)

# 初始化计时器
fps_time = time.time()

# 屏幕宽度和高度
screen_width, screen_height = pyautogui.size()

# 阈值和平滑移动参数
threshold = 10
smooth_duration = 0.25

# 是否已经检测到手
hand_detected = False

while cap.isOpened():
    # 读取视频流中的一帧
    ret, frame = cap.read()
    if not ret:
        break

    # 将图像转换为RGB格式(MediaPipe要求输入为RGB格式)
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # 使用MediaPipe Hands模块处理图像
    results = hands.process(frame_rgb)

    # 绘制手部关键点及骨骼线
    if results.multi_hand_landmarks:
        # 获取第一个检测到的手的信息
        hand_landmarks = results.multi_hand_landmarks[0]
        mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)

        # 获取食指关键点
        index_finger = hand_landmarks.landmark[8]

        # 将食指位置映射到屏幕坐标,添加阈值
        finger_x, finger_y = int((1 - index_finger.x) * screen_width), int(index_finger.y * screen_height)
        if abs(finger_x - pyautogui.position().x) > threshold or abs(finger_y - pyautogui.position().y) > threshold:
            # 控制鼠标平滑移动
            pyautogui.moveTo(finger_x, finger_y, duration=smooth_duration)

        # 获取手指关键点
        finger_points = [hand_landmarks.landmark[i] for i in [4, 8, 12, 16, 20]]

        # 绘制手指骨骼线,修改颜色为#61BAAD
        for i in range(4):
            start_point = (int(finger_points[i].x * frame.shape[1]), int(finger_points[i].y * frame.shape[0]))
            end_point = (int(finger_points[i + 1].x * frame.shape[1]), int(finger_points[i + 1].y * frame.shape[0]))
            cv2.line(frame, start_point, end_point, (173, 186, 97), 2)  # 修改颜色为#61BAAD

        # 设置 hand_detected 为 True
        hand_detected = True
    else:
        # 如果没有检测到手,重置hand_detected
        hand_detected = False

    # 计算帧率
    current_time = time.time()
    fps = 1 / (current_time - fps_time)
    fps_time = current_time

    # 显示帧率
    cv2.putText(frame, f'FPS: {int(fps)}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

    # 显示处理后的图像
    cv2.imshow('Hand grasping', frame)

    # 检测按键,按下ESC键退出循环
    if cv2.waitKey(1) & 0xFF == 27:
        break

# 释放资源
cap.release()
cv2.destroyAllWindows()

总结

        由于这里需要一个视频来展示效果,我就不展示效果图了,大家可以自行复制原始代码来研究。

### 回答1: Python的OpenCV库和MediaPipe工具包是可以一起使用的,以实现手势识别的功能。 首先,需要在Python中安装OpenCV库和MediaPipe工具包。可以使用pip命令来安装它们: ``` pip install opencv-python pip install mediapipe ``` 安装完成后,就可以开始使用了。 首先,导入必要的库: ```python import cv2 import mediapipe as mp ``` 接下来,创建一个MediaPipe的Hand对象和一个OpenCV的VideoCapture对象,用于读取摄像头输入: ```python mp_hands = mp.solutions.hands hands = mp_hands.Hands() cap = cv2.VideoCapture(0) ``` 然后,使用一个循环来读取摄像头输入并进行手势识别: ```python while True: ret, frame = cap.read() if not ret: break frame_RGB = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results = hands.process(frame_RGB) if results.multi_handedness: for hand_landmarks in results.multi_hand_landmarks: # 在这里可以对hand_landmarks进行处理和识别手势的操作 cv2.imshow('Gesture Recognition', frame) if cv2.waitKey(1) == ord('q'): break ``` 在循环中,首先将读取到的帧转换为RGB格式,然后使用Hands对象的process方法对该帧进行手势识别。得到的结果存储在results变量中。 在对每个检测到的手部进行循环处理时,可以使用hand_landmarks来获取该手的关键点坐标。可以根据这些关键点的位置和运动轨迹来实现手势的识别和分析。 最后,通过cv2.imshow方法显示图像,并使用cv2.waitKey方法等待用户操作。当用户按下"q"键时,循环终止,程序退出。 通过以上步骤,就可以使用Python的OpenCV库和MediaPipe工具包实现手势识别的功能了。当然,实际的手势识别算法和操作需要根据具体需求进行进一步的开发和优化。 ### 回答2: Python OpenCVMediaPipe结合使用可以实现手势识别。首先,我们需要安装必要的库和工具,包括Python、opencv-python、mediapipe和其他依赖项。 然后,我们可以使用MediaPipe提供的HandTracking模块来检测手部的关键点。它使用机器学习模型来识别手势,并返回手部关键点的坐标。我们可以通过OpenCV的视频捕捉模块读取摄像头的实时图像。 接下来,我们通过应用MediaPipe的HandTracking模块获取手部关键点的坐标,并使用OpenCV将这些坐标绘制到图像上,以便我们可以实时看到手部的位置和动作。 完成这些基本的设置后,我们可以定义特定的手势,例如拇指和食指的指尖接触,作为一个简单的示例。我们可以通过检查特定的关键点之间的距离和角度来识别这种手势。如果关键点之间的距离较小并且角度较小,则我们可以确定手势是拇指和食指的指尖接触。 我们可以使用类似的方法来识别其他手势,比如手掌的张开和闭合,拳头的形成等等。我们可以定义一系列规则和阈值来确定特定手势的识别。 最后,我们可以根据检测到的手势执行特定的操作。例如,当识别到拇指和食指的指尖接触时,我们可以触发相机的快门,实现手势拍照。 总之,Python的OpenCVMediaPipe结合使用可以实现手势识别。我们可以利用MediaPipe的HandTracking模块检测手部关键点,并使用OpenCV实时绘制手势位置。通过定义特定手势的规则,我们可以识别各种手势并执行相应操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WenJGo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值