作者: GDragon-creator
发布时间: 2025年5月31日
GitHub 仓库: https://github.com/GDragon-creator/bug-free-memory
关键词: MediaPipe, 手势识别, PyAutoGUI, Python, 自动化控制, GUI
一、前言
在日常电脑操作中,频繁切换键盘和鼠标可能会打断你的工作流,尤其是在演示文稿、媒体播放或需要快速交互的场景中。为了解决这一痛点,我开发了“指尖命令”——一款基于 Google MediaPipe 手部追踪技术和 PyAutoGUI 自动化库的创新应用。通过简单的手势(伸出1至5根手指),你可以轻松控制键盘按键、组合键、鼠标滚动或点击,彻底解放双手,提升效率。
本文将详细介绍“指尖命令”的功能、架构、安装与使用方法,并分享其核心代码实现。如果你对计算机视觉、自动化控制或 Python 开发感兴趣,欢迎体验并为项目贡献代码!点击访问 GitHub 仓库。
二、项目简介
“指尖命令”是一款通过摄像头捕捉手势,结合 MediaPipe 进行手部关键点检测,并通过 PyAutoGUI 执行用户定义的操作的应用程序。它支持以下核心功能:
- 高度可定制:为1至5指手势绑定键盘按键、组合键、鼠标滚动或点击。
- 多语言支持:支持简体中文、繁体中文和英文界面,自动适配系统语言。
- 实时反馈:摄像头窗口显示手部关键点、指数字和左右手信息。
- 防抖机制:通过0.25秒手势保持时间和0.4秒操作间隔避免误触发。
- 便捷退出:双手举起3秒或按 ESC 键快速退出。
- 配置管理:支持保存、导入、导出配置,方便备份和分享。
无论是用于媒体播放控制、PPT翻页,还是其他需要快捷操作的场景,“指尖命令”都能带来流畅的体验。
三、系统架构
“指尖命令”采用模块化设计,包含以下核心模块:
1. 图形界面模块(Tkinter)
- 功能:提供直观的 GUI,用于配置手势绑定、语言切换和状态显示。
- 实现:使用 Tkinter 创建主窗口,包含菜单栏(选项、语言、关于)、手势配置面板和状态栏。支持多语言动态切换,保存配置到 settings.json 和 config.ini。
1.def setup_gui():
2. global gui_root, status_label, action_labels, set_buttons, title_label, control_header, start_button, menubar, options_menu, about_menu, language_menu
3. # 初始化 config.ini 文件
4. config = configparser.ConfigParser()
5. if not os.path.exists("config.ini"):
6. config.add_section("Settings")
7. config.set("Settings", "language", "zh-CN")
8. with open("config.ini", "w", encoding="utf-8") as configfile:
9. config.write(configfile)
10. load_settings()
11. gui_root = tk.Tk()
12. gui_root.title(translations[current_language]["title"])
13. # 添加菜单栏
14. menubar = tk.Menu(gui_root)
15. gui_root.config(menu=menubar)
16. options_menu = tk.Menu(menubar, tearoff=0)
17. language_menu = tk.Menu(menubar, tearoff=0)
18. about_menu = tk.Menu(menubar, tearoff=0)
19. menubar.add_cascade(label=translations[current_language]["options_menu"], menu=options_menu)
20. # ... 菜单项配置 ...
21. # 设置窗口大小和背景颜色
22. gui_root.geometry("700x600")
23. gui_root.configure(bg=neutral_bg)
24. # 样式配置
25. style = ttk.Style()
26. style.theme_use('clam')
27. style.configure(".", font=("SimHei", 10), background=neutral_bg)
28. # ... 其他样式配置 ...
29. # 创建主框架和控件
30. main_frame = ttk.Frame(gui_root, padding="20")
31. main_frame.pack(fill=tk.BOTH, expand=True)
32. title_label = ttk.Label(title_frame, text=translations[current_language]["title"], style="Title.TLabel")
33. # ... 其他控件初始化 ...
2. 手势识别模块(MediaPipe)
- 功能:实时检测最多两只手,识别1-5根手指和左右手方向。
- 实现:使用 MediaPipe Hands 模块处理摄像头帧,count_fingers 函数通过关键点坐标判断手指伸展状态,动态阈值确保准确性。
1.def count_fingers(lst, handedness_label="Unknown"):
2. cnt = 0
3. if not lst or not lst.landmark:
4. return 0
5. try:
6. vertical_thresh = abs(lst.landmark[0].y - lst.landmark[9].y) / 2.8
7. if (lst.landmark[5].y - lst.landmark[8].y) > vertical_thresh:
8. cnt += 1 # 食指
9. if (lst.landmark[9].y - lst.landmark[12].y) > vertical_thresh:
10. cnt += 1 # 中指
11. # ... 其他手指 ...
12. thumb_horizontal_ref_dist = abs(lst.landmark[5].x - lst.landmark[17].x)
13. thumb_thresh = thumb_horizontal_ref_dist * 0.3
14. if handedness_label == "Left":
15. if (lst.landmark[4].x - lst.landmark[2].x) > thumb_thresh:
16. cnt += 1
17. elif handedness_label == "Right":
18. if (lst.landmark[2].x - lst.landmark[4].x) > thumb_thresh:
19. cnt += 1
20. except Exception as e:
21. print(f"手指计数错误: {e}")
22. return 0
23. return cnt
24.
25.# 主循环中的手势检测
26.cap = cv2.VideoCapture(0)
27.hands_module = mp.solutions.hands
28.hand_obj = hands_module.Hands(max_num_hands=2, min_detection_confidence=0.7, min_tracking_confidence=0.6)
29.while True:
30. ret, frm = cap.read()
31. if not ret:
32. print(translations[current_language]["frame_error"])
33. break
34. frm = cv2.flip(frm, 1)
35. rgb_frm = cv2.cvtColor(frm, cv2.COLOR_BGR2RGB)
36. res = hand_obj.process(rgb_frm)
37. if res.multi_hand_landmarks:
38. num_hands_detected = len(res.multi_hand_landmarks)
39. for i, hand_landmarks in enumerate(res.multi_hand_landmarks):
40. drawing.draw_landmarks(frm, hand_landmarks, hands_module.HAND_CONNECTIONS)
41. if num_hands_detected == 1:
42. hand_keyPoints = res.multi_hand_landmarks[0]
43. handedness_info = res.multi_handedness[0].classification[0]
44. current_handedness_label = handedness_info.label
cnt = count_fingers(hand_keyPoints, current_handedness_label)
3. 操作执行模块(PyAutoGUI、Pynput)
- 功能:根据手势执行绑定的键盘或鼠标操作,捕获用户输入用于配置。
- 实现:PyAutoGUI 模拟按键、组合键、鼠标点击和滚动;Pynput 捕获键盘和鼠标输入,防抖机制确保操作精准。
1.def on_key_press(key_event):
2. global capturing_for_finger, current_keys
3. if capturing_for_finger is None:
4. return
5. try:
6. if hasattr(key_event, 'vk') and 65 <= key_event.vk <= 90:
7. key_name = chr(key_event.vk).lower()
8. # ... 其他按键处理 ...
9. current_keys.add(key_name)
10. except Exception as e:
11. print(f"键处理错误: {e}")
12.
13.def on_key_release(key_event):
14. global capturing_for_finger
15. if capturing_for_finger is None:
16. return
17. action_type = 'key' if len(current_keys) == 1 else 'combo'
18. action = {'type': action_type, 'value': format_keys(current_keys)}
19. update_action_display_and_clear_conflicts(capturing_for_finger, action)
20. stop_capture_mode()
21.
22.# 主循环中的操作执行
23.if start_init and (current_time - action_gesture_start_time) > action_hold_time:
24. action_to_perform = finger_actions.get(cnt)
25. if action_to_perform:
26. if (current_time - last_action_time) > min_action_interval:
27. try:
28. if action_to_perform['type'] == 'key':
29. pyautogui.press(action_to_perform['value'])
30. elif action_to_perform['type'] == 'combo':
31. keys_to_press = action_to_perform['value'].split('+')
32. for k_val in keys_to_press:
33. pyautogui.keyDown(k_val)
34. for k_val in reversed(keys_to_press):
35. pyautogui.keyUp(k_val)
36. elif action_to_perform['type'] == 'mouse_scroll':
37. if action_to_perform['value'] == 'scroll_up':
38. pyautogui.scroll(120)
39. elif action_to_perform['value'] == 'scroll_down':
40. pyautogui.scroll(-120)
41. elif action_to_perform['type'] == 'mouse_click':
42. button_val = action_to_perform['button'].replace('Button.', '')
43. pyautogui.click(button=button_val)
44. last_action_time = current_time
45. except Exception as e:
print(f"使用 pyautogui 执行操作时出错: {e}")
4. 配置管理模块
- 功能:管理手势绑定和语言设置,持久化到 settings.json 和 config.ini。
- 实现:JSON 格式存储手势映射,configparser 管理语言偏好,支持导入/导出。
1.def save_settings():
2. global finger_actions
3. try:
4. settings = {str(i): finger_actions[i] for i in range(1, 6)}
5. with open("settings.json", "w", encoding="utf-8") as f:
6. json.dump(settings, f, indent=4, ensure_ascii=False)
7. print(translations[current_language]["export_success"].format("settings.json"))
8. except Exception as e:
9. print(translations[current_language]["export_failed"].format(e))
10. messagebox.showerror(translations[current_language]["error_title"],
11. translations[current_language]["export_failed"].format(e))
12.
13.def load_settings():
14. global finger_actions, current_language
15. config = configparser.ConfigParser()
16. if os.path.exists("config.ini"):
17. config.read("config.ini", encoding="utf-8")
18. if "Settings" in config and "language" in config["Settings"]:
19. lang = config["Settings"]["language"]
20. language_map = {"auto": "auto", "zh-CN": "zh-CN", "zh-TW": "zh-TW", "en": "en"}
21. current_language = language_map.get(lang, "zh-CN")
22. try:
23. if os.path.exists("settings.json"):
24. with open("settings.json", "r", encoding="utf-8") as f:
25. settings = json.load(f)
26. for i in range(1, 6):
27. key = str(i)
28. if key in settings:
29. action = settings[key]
30. if action is None or (
31. isinstance(action, dict) and
32. "type" in action and
33. action["type"] in ["key", "combo", "mouse_scroll", "mouse_click"]):
34. finger_actions[i] = action
35. else:
36. print(f"无效的设置项,手指 {i}: {action}")
37. finger_actions[i] = None
38. print(translations[current_language]["import_success"].format("settings.json"))
39. except Exception as e:
40. print(f"加载设置失败: {e}")
finger_actions = {i: None for i in range(1, 6)}
5. 文本渲染模块(PIL、OpenCV)
- 功能:在摄像头画面上显示多语言提示(手指数量、左右手、退出倒计时)。
- 实现:PIL 渲染中文(simhei.ttf),OpenCV 显示关键点和文本,支持字体回退。
1.def draw_chinese_text(img_cv, text, pos, font_size=30, color=(255, 0, 0)):
2. img_pil = Image.fromarray(cv2.cvtColor(img_cv, cv2.COLOR_BGR2RGB))
3. draw = ImageDraw.Draw(img_pil)
4. try:
5. font = ImageFont.truetype("./fonts/simhei.ttf", font_size)
6. except IOError:
7. try:
8. font = ImageFont.truetype("arial.ttf", font_size)
9. if text != translations[current_language]["font_fallback"]:
10. print(translations[current_language]["font_fallback"])
11. except IOError:
12. print(translations[current_language]["font_missing"])
13. cv2.putText(img_cv, translations[current_language]["font_error"], (pos[0], pos[1] + font_size // 2),
14. cv2.FONT_HERSHEY_SIMPLEX, font_size / 30, color, 2)
15. return img_cv
16. draw.text(pos, text, font=font, fill=color)
17. return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
四、安装与运行
“指尖命令”提供两种使用方式:源码版本(适合开发者或需要自定义的用户)和打包版本(适合快速部署的用户)。以下分别说明安装步骤。
1. 系统需求
-
操作系统:Windows 10/11 64位(Windows 10 版本1803或更高)
-
硬件:
最低配置:
Intel Core i3-1115G4或AMD Ryzen 3 5300U
4GB RAM
640x480 30FPS摄像头
3GB磁盘空间
推荐配置:
Intel Core i5-1235U或AMD Ryzen 5 5600U
8GB RAM
720p摄像头
4GB SSD空间
-
软件:
Python 3.8+(仅源码版本需要)
Microsoft Visual C++ Redistributable 2015-2022 (x64)
-
权限:摄像头访问权限,运行目录写入权限(用于生成settings.json和config.ini)
2. 源码版本安装
适合开发者或需要修改代码的用户,需安装 Python 环境和依赖。
-
安装 Python:
-
下载并安装 Python 3.8+(推荐3.10)从 python.org。
-
确保勾选“Add Python to PATH”。
-
-
克隆仓库:
git clone https://github.com/GDragon-creator/bug-free-memory.git cd bug-free-memory
-
安装依赖:
-
确保网络连接,运行以下命令安装必要库:
pip install -r requirements.txt
-
依赖包括:opencv-python, mediapipe, pyautogui, pynput, pillow, numpy。
-
-
准备文件:
-
确保 languages.json 与 automated_mediaplayer.py 在同一目录。
-
(推荐)创建 fonts/ 目录,放入 simhei.ttf(或系统自带中文字体)。
-
(可选)创建 images/ 目录,放入 wechat.png 用于“联系我们”界面。
-
-
运行程序:
python automated_mediaplayer.py
-
首次运行可能需要下载 MediaPipe 模型,请保持网络畅通。
-
3. 打包版本安装
适合希望快速使用的用户,无需配置 Python 环境。
-
下载打包版本:
- 从 GitHub Releases 下载最新版本的 Fingertip_command.zip。
- 下载链接:Release 基于mediapipe:指尖命令 V1.0——打包 · GDragon-creator/fingertip-commands
-
解压文件:
-
将 Fingertip_command.zip 解压到全英文路径的目录(如 C:\FingertipCommand)。
-
确保目录包含以下文件:
-
基于MediaPipe:指尖命令.exe
-
languages.json
-
(推荐)fonts/simhei.ttf
-
(可选)images/wechat.png
-
-
-
安装运行时依赖:
-
确保系统已安装 Microsoft Visual C++ Redistributable 2015-2022 (x64),可从 Microsoft 官网 下载。
-
-
运行程序:
-
双击 基于MediaPipe:指尖命令.exe。
-
首次运行可能会请求摄像头权限,点击“允许”。
-
-
注意事项:
-
若中文显示异常,请将 simhei.ttf 放入 fonts/ 目录。
-
确保 languages.json 存在,否则程序无法启动。
-
五、使用指南
1. 配置界面
启动程序后,进入 GUI 界面:
- 语言切换:通过“语言”菜单选择简体中文、繁体中文或英文。
- 绑定手势:
点击“设置动作”按钮,进入捕获模式。
执行键盘按键(单键/组合键)、鼠标滚动或点击。
绑定成功后,动作显示为绿色,按钮变为“取消设定”。
如果需要更换/取消绑定,再次点击“取消设定”按钮即可清除配置。
- 配置管理:保存到 settings.json,支持导入/导出。
- 启动识别:点击“完成配置并开始识别”,进入手势控制模式。
2. 手势控制
- 摄像头窗口:显示手部关键点、指数字和左右手信息。
- 执行动作:伸出1-5根手指,保持0.25秒触发绑定操作。
- 退出程序:双手举起3秒或按 ESC 键。
- 重新配置:按 R 键返回 GUI 界面。
3. 注意事项
- 确保光线充足,背景简洁。
- 放置 simhei.ttf 以正确显示中文。
- 检查 languages.json 是否存在。
六、核心特性与优势
- 灵活性:支持多种操作类型,满足不同场景需求。
- 易用性:直观的 GUI 和多语言支持,适合全球用户。
- 稳定性:防抖机制和错误处理确保流畅体验。
- 扩展性:模块化设计便于功能扩展。
七、未来改进方向
-
录制宏:支持录制和回放复杂操作序列,如多步键盘和鼠标操作,提升自动化能力。
-
单个按键长按:允许绑定长按键操作,例如持续按住某个键以实现音量渐增或窗口切换。
-
预定动作:内置常用媒体控制动作(如播放、暂停、音量+、音量-),简化配置过程。
八、结语
“指尖命令”将手势识别与自动化控制无缝结合,为用户提供了一种新颖的交互方式。无论是简化日常操作还是探索计算机视觉的乐趣,这款工具都能带来惊喜。欢迎体验并在 GitHub 上提出宝贵建议!
项目地址: GitHub - GDragon-creator/fingertip-commands: 基于MediaPipe:指尖命令
声明:本文基于“指尖命令”项目文档整理,代码已开源,欢迎 star 和 fork!如果您有任何问题或建议,请在 GitHub Issues 或本文评论区留言。
参考资料: