# gesture-cursor **Repository Path**: wangxiaopeng2/gesture-cursor ## Basic Information - **Project Name**: gesture-cursor - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-20 - **Last Updated**: 2026-09-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README --- AIGC: ContentProducer: '001191110102MAD55U9H0F10002' ContentPropagator: '001191110102MAD55U9H0F10002' Label: '1' ProduceID: '791ecc53-7532-4dfc-9932-8cee4a803b9f' PropagateID: '791ecc53-7532-4dfc-9932-8cee4a803b9f' ReservedCode1: '1f651cd9-78ad-4b9d-bbfc-a9049033b8e1' ReservedCode2: '1f651cd9-78ad-4b9d-bbfc-a9049033b8e1' --- # 手势鼠标控制(Gesture Mouse Control) 基于 **MediaPipe**、**OpenCV** 和 **PyAutoGUI** 的实时手势控制虚拟鼠标。无需触碰触摸板,仅凭摄像头即可移动并点击电脑光标。 项目按单一职责拆分为多个小模块,每个模块(手部检测、手势解释、系统交互)都可以独立替换或扩展。 --- ## 功能特性 - 基于 MediaPipe 的 21 个手部关键点单手追踪(中端笔记本约 30 FPS)。 - 平滑、低抖动的光标移动(中值滤波 + 指数平滑 + 滞回死区)。 - 完整的鼠标操作指令: - **移动** —— 仅伸出食指。 - **左键单击** —— 快速捏合(拇指 + 食指)。 - **拖拽** —— 捏合并**保持**(≥ 0.3 秒),松开即放下。 - **右键单击** —— 拇指 + 中指捏合。 - **滚动** —— 食指 + 中指同时伸出,上下移动。 - 实时 HUD 显示 FPS、当前状态、最近动作以及光标有效区域。 - 点击防抖,避免误触发连击。 - 所有阈值、灵敏度和平滑参数集中在 `config.py` 中,可随时调整。 - 模块职责清晰:`HandTracker` / `GestureController` / `MouseController`。 - 支持 `q` / `Esc` / 关闭窗口 / `Ctrl+C` 优雅退出,拖拽中途退出也不会卡住鼠标按键。 --- ## 硬件前提 | 硬件 | 要求 | 说明 | |---|---|---| | 摄像头 | **必需**,内置或 USB 外接均可 | 分辨率建议 ≥ 640×480;使用时确保不被浏览器、视频会议等应用占用 | | CPU | 建议 ≥ 4 核 2GHz(x86_64 / ARM64) | 手部关键点推理运行在 CPU(TFLite XNNPACK),中端笔记本约 30 FPS | | 内存 | ≥ 1GB 可用 | 程序占用很低 | | GPU | **非必需** | 当前技术栈(mediapipe 0.10.21 legacy API)固定使用 CPU 推理,独立显卡不会加速(详见下文"运行方式:CPU 还是 GPU?") | | 平台 | Windows 10/11、macOS、Linux | macOS 需"辅助功能 + 屏幕录制"权限;Linux 需 X11(非 Wayland)并安装 `xdotool` | > 光照建议:手部区域光线均匀、背景简洁,MediaPipe 在暗光/逆光下关键点精度下降,会放大光标抖动。 --- ## 项目结构 ``` gesture_mouse/ ├── main.py # 入口 —— 采集循环与组件装配 ├── config.py # 全部可调参数(阈值、灵敏度……) ├── hand_tracker.py # MediaPipe 封装 —— 返回 21 个像素坐标关键点 ├── gesture_controller.py # 状态机 —— 关键点 → 鼠标动作 ├── mouse_controller.py # PyAutoGUI 封装 ├── utils.py # FPS 计数、HUD 绘制、数学工具 ├── requirements.txt └── README.md / README.zh-CN.md ``` --- ## 安装 ### 1. Python 版本 **必须使用 Python 3.12**(3.9–3.12 均可;3.13 不行)。 项目固定使用 mediapipe 0.10.21,这是最后一个同时保留可用 `mp.solutions.hands` API 且提供稳定 Windows wheel 的版本。更新的版本要么移除了 `mp.solutions`(0.10.22+),要么 Windows ctypes 绑定存在缺陷(0.10.30+)。 - **Windows:** `winget install Python.Python.3.12`(或从 [python.org](https://www.python.org/downloads/release/python-3128/) 下载) - **macOS(Homebrew):** `brew install python@3.12` - **Ubuntu/Debian:** `sudo apt install python3.12 python3.12-venv` ### 2. 创建虚拟环境(强烈建议,不是可选项) mediapipe 0.10.21 与 numpy < 2 的版本固定会与全局 Python 中的其他 ML 项目冲突,因此务必为该项目使用独立 venv。 ```bash # Windows py -3.12 -m venv .venv .venv\Scripts\activate # macOS / Linux python3.12 -m venv .venv source .venv/bin/activate ``` > 注意:如果系统 PATH 中的 `python` 指向了其他运行时(例如某些工具自带环境),创建 venv 时请显式使用 `py -3.12`。 ### 3. 安装依赖 ```bash pip install -r requirements.txt ``` > **Apple Silicon(M1/M2/M3)注意:** 如果 `mediapipe` 安装失败,可尝试 `pip install mediapipe-silicon`,或改用 Python 3.10/3.11。 ### 4. 运行 ```bash python main.py ``` 屏幕会出现标题为 **Gesture Mouse Control** 的窗口,显示摄像头画面。把手伸进画面即可控制光标。 按下 **`q`**(或 `Esc`)退出预览窗口。 ### 5. 首次运行自检(30 秒) | 检查项 | 预期结果 | 失败处理 | |---|---|---| | 窗口出现 | 标题 `Gesture Mouse Control` 的摄像头预览窗口 | 检查摄像头是否被其他应用占用 | | 画面正常 | 能看到自己,左右镜像 | 调整 `CAMERA_INDEX`(0/1/2…) | | 骨架线 | 手入画后出现 21 点连线 | 保证手在画面内、光线均匀 | | 控制光标 | 伸食指移动,光标跟随 | 确认终端/IDE 已授予辅助功能权限(macOS) | | FPS | 约 25–30 | `MODEL_COMPLEXITY=0` 或降低分辨率可提速 | --- ## 本机开发环境(已实测通过) 以下为本项目在 Windows 开发机(RTX 4060 Laptop)上验证过的环境,可直接照搬: | 项目 | 值 | |---|---| | 操作系统 | Windows 10/11 | | Python | 3.12.5(`D:\app\python\python3.12.5\`) | | 虚拟环境 | `.venv`(位于项目根目录) | | 依赖版本 | mediapipe 0.10.21 / opencv-python 4.11.0 / numpy 1.26.4 / pyautogui 0.9.54 | | 摄像头 | 索引 0,640×480@30 | > 注意:如果 PATH 里的 `python` 指向了其它运行时(如部分 AI 工具自带环境),创建 venv 必须显式用 `py -3.12 -m venv .venv`,运行也要用 `.venv\Scripts\python.exe main.py`。 --- ## 手势对照表 | 手势 | 动作 | 做法 | |---|---|---| | ☝️ 仅食指伸出 | **移动光标** | 只伸出食指。 | | 🤏 快速捏合 | **左键单击** | 拇指尖触碰食指尖并在约 0.3 秒内松开。 | | 🤏 捏合保持 | **拖拽** | 捏合后保持并移动,松开即放下。 | | ✌️ 拇指 + 中指捏合 | **右键单击** | 拇指尖轻触中指尖。 | | ✌️ 食指 + 中指伸出(剪刀手) | **滚动** | 剪刀手势保持,手向上移动=向上滚,向下移动=向下滚,松手退出。连续、方向直觉(业界主流方案)。 | 当前识别到的手势会显示在屏幕 HUD 上。 --- ## 激活与中断 为避免手意外闯入画面导致光标乱晃,系统引入了**激活门控**机制: | 状态 | 说明 | |---|---| | **INACTIVE(休眠)** | 鼠标完全冻结,画面中央显示提示"Show Open Palm (3s) to Start" | | **ACTIVATING(激活中)** | 检测到五指向上(张开手掌),HUD 显示倒计时,鼠标仍冻结 | | **ACTIVE(已激活)** | 3 秒倒计时完成,手势鼠标正常工作 | **激活**:在摄像头前张开手掌(≥4 指向上),保持 **3 秒** 不变即可激活。前 5 帧为防抖确认,之后开始倒计时。 **中断**:激活后如果手离开画面 **≥2 秒**,系统自动回到休眠态,下次使用需重新五指向上激活。手短暂离开(<2 秒)不影响激活状态。 **相关配置**(`config.py`): | 设置项 | 作用 | 默认值 | |---|---|---| | `ACTIVATION_HOLD_TIME` | 五指向上保持多少秒激活 | `1.0` | | `ACTIVATION_MIN_FRAMES` | 连续多少帧确认才开始计时(防抖) | `5` | | `DEACTIVATION_TIMEOUT` | 手离开多少秒后休眠 | `2.0` | --- ## 配置说明 所有可调参数都在 `config.py` 中,最常用的旋钮: | 设置项 | 作用 | |---|---| | `FRAME_REDUCTION` | 摄像头画面四周的"死区"像素数。越大越灵敏(手的小幅移动覆盖更大屏幕范围)。 | | `SMOOTHING_FACTOR` | `0.0`(冻结)→ `1.0`(即时)。`0.3 – 0.5` 为最佳区间。 | | `CURSOR_SENSITIVITY` | 以屏幕中心为基准的灵敏度倍率,`1.0` 为中性。 | | `CURSOR_DEAD_ZONE` | 滞回死区(屏幕像素)。静止时位移小于此值则光标不动,消除"静止晃动"。`0` 禁用。典型值 10–15。 | | `LANDMARKS_MEDIAN_WINDOW` | 关键点中值滤波窗口(帧数)。剔除 MediaPipe 跳变离群点。`0`/`1` 禁用,3–5 为佳。 | | `PINCH_THRESHOLD` | 拇指与食指距离低于该像素值视为捏合。 | | `RIGHT_CLICK_THRESHOLD` | 拇指与中指的右键手势距离阈值。 | | `DRAG_HOLD_TIME` | 捏合保持多少秒后进入拖拽。 | | `CLICK_DEBOUNCE` | 两次点击的最小间隔(防抖)。 | | `SCROLL_SENSITIVITY` | 数值越大滚动越慢。 | | `CAMERA_WIDTH/HEIGHT` | 调低可提升 FPS,调高可提升精度。 | 无需额外工具,修改后重新运行即可生效。 --- ## 性能调优 - 将 `config.py` 中的 `MODEL_COMPLEXITY` 改为 `0`,弱硬件上推理可提升约 30%。 - 在慢速 CPU 上降低 `CAMERA_WIDTH` / `CAMERA_HEIGHT`(如 480×360)。 - 关闭其他占用摄像头的应用(浏览器、视频会议),它们常把摄像头拖到低帧率模式。 - 有效区域矩形(品红色框)表示手指尖需要处于的光标映射区域;如果经常触边,请增大 `FRAME_REDUCTION`。 - 光标抖动时:增大 `CURSOR_DEAD_ZONE`(如 18–20)或 `LANDMARKS_MEDIAN_WINDOW`(如 5–7);感觉"粘"则减小死区(如 6–8)。 --- ## 运行方式:CPU 还是 GPU? **默认 CPU;`USE_GPU = True` 时自动尝试 GPU,失败则回退 CPU。** - 默认使用 mediapipe 0.10.21 旧版 `mp.solutions.hands` API(TensorFlow Lite XNNPACK CPU 推理)。 - 在 `config.py` 中设置 `USE_GPU = True` 会尝试切换到 MediaPipe Tasks API + GPU delegate。 - **注意:MediaPipe GPU delegate 目前不支持 Windows 桌面**(初始化会报 "GPU Delegate is not yet supported for Windows" 并自动回退 CPU)。该选项主要为 Linux/macOS 或未来版本预留。 - GPU 模式首次运行时会自动下载 `hand_landmarker.task` 模型文件。 --- ## 常见问题 **`AttributeError: module 'mediapipe' has no attribute 'solutions'`** 你安装了 **mediapipe ≥ 0.10.22**,它移除了旧版 `mp.solutions` API。请在 Python 3.12 上重建 venv 并执行 `pip install -r requirements.txt` —— 固定版本保证会装回 0.10.21。 **`AttributeError: function 'free' not found`(Windows)** 你安装了 **mediapipe ≥ 0.10.30**,其 Windows ctypes 绑定有已知缺陷。同样按上面的方式重建 Python 3.12 venv 并使用固定版本 `requirements.txt`。 **`ERROR: Could not find a version that satisfies the requirement mediapipe==0.10.21`** 当前 Python 为 3.13(或低于 3.9)。mediapipe 0.10.21 仅提供 cp39–cp312 的 wheel。请切换到 Python 3.12 venv 再试。 **"Could not open camera at index 0"** 有应用正占用摄像头,或默认摄像头不在索引 0。可尝试在 `config.py` 中将 `CAMERA_INDEX` 改为 `1`(或 `2`)。 **macOS 上光标不动** 需要为运行脚本的终端/IDE 授予 *辅助功能* 与 *屏幕录制* 权限: *系统设置 → 隐私与安全性 → 辅助功能 / 屏幕录制。* **Linux 上光标不动** PyAutoGUI 底层依赖 `xdotool`。用包管理器安装: `sudo apt install scrot python3-tk python3-dev`,并确保使用 X11(Wayland 支持有限)。 **光标跳变或抖动** 增大 `CURSOR_DEAD_ZONE`(如 18–20),增大 `LANDMARKS_MEDIAN_WINDOW`(如 5–7),降低 `SMOOTHING_FACTOR`(如 `0.3`),并保证手部光照均匀。 **不想点击时却触发点击** 增大 `PINCH_THRESHOLD`(默认 `40` 像素)和/或 `CLICK_DEBOUNCE`。 **PyAutoGUI 的 failsafe 老是触发** 光标到达屏幕角落会中止动作。请让光标远离屏幕角落,或(不建议)在 `main.py` 构造 `MouseController` 时设置 `failsafe=False`。 --- ## 扩展系统 `GestureController` 是一个小型有限状态机。要新增一个手势: 1. 在 `config.py` 中添加所需阈值。 2. 在 `gesture_controller.py` 的 `update()` 顶部,与其它"意图"布尔值(`is_pinch`、`is_scroll` 等)并列分类。 3. 插入对应的状态转移代码块 —— 保持优先级顺序,高优先级手势(捏合/拖拽)要先于低优先级(光标移动)检查。 4. 在 `self.mouse` 上调用对应动作(如需要新的原语可扩展 `MouseController`,例如 `pyautogui.hotkey('ctrl', 'c')`)。 可以扩展的方向: - **音量控制** —— 捏合后旋转手势。 - **切换工作区** —— 三指滑动。 - **多手支持** —— 将 `config.py` 中 `MAX_NUM_HANDS` 调为 2,并扩展 `HandTracker.process` 返回列表。 - **动态标定** —— 录制几秒"自然"手姿自动调节阈值。 --- ## 许可证 本项目仅用于学习和个人使用,按原样提供。