虚拟键盘(不是软键盘)——科幻世界!!!

虚拟键盘(不是软键盘)——科幻世界!!!如何使用摄像头 Mediapipe 和 OpenCV 创建一个虚拟键盘 用户可以通过手部动作来 按压 虚拟键盘上的按键

大家好,欢迎来到IT知识分享网。

        

目录

流程说明

导入所需的库

初始化Mediapipe的手部检测模块

键盘控制器

打开摄像头

定义虚拟键盘的按键布局

记录每个按键的上次按压时间

显示虚拟键盘的函数

检测手指是否按压按键的函数

主循环

释放资源

总结

代码实现

效果展示


        这段代码展示了如何使用摄像头、Mediapipe和OpenCV创建一个虚拟键盘,用户可以通过手部动作来“按压”虚拟键盘上的按键。代码通过检测手部位置和动作来确定哪个按键被按压,然后模拟实际的键盘输入。


流程说明

虚拟键盘(不是软键盘)——科幻世界!!!

导入所需的库
import cv2 import mediapipe as mp import time from pynput.keyboard import Controller
  • cv2:OpenCV库,用于图像处理和计算机视觉。
  • mediapipe:Mediapipe库,用于手部检测和跟踪。
  • timePython内置的时间库,用于记录和计算时间。
  • pynput.keyboard.Controller:用于模拟键盘输入。

 初始化Mediapipe的手部检测模块
# 初始化Mediapipe的手部检测模块 mp_hands = mp.solutions.hands hands = mp_hands.Hands(min_detection_confidence=0.7, min_tracking_confidence=0.7) mp_drawing = mp.solutions.drawing_utils
  • mp_hands:初始化Mediapipe的手部检测模块。
  • hands:创建一个手部检测对象,设置最小检测和跟踪置信度为0.7。
  • mp_drawing:用于在图像上绘制手部关键点和连接线。

键盘控制器
keyboard = Controller()
  • keyboard:创建一个键盘控制器对象,用于模拟键盘输入。

打开摄像头
cap = cv2.VideoCapture(0)
  • cap:打开默认摄像头。

定义虚拟键盘的按键布局
# 定义虚拟键盘的按键布局 keys = [ ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'], ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'], ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'], ['Z', 'X', 'C', 'V', 'B', 'N', 'M'], [' ', 'BACKSPACE'] ]
  • keys:定义虚拟键盘的按键布局,每个元素表示一行按键。

记录每个按键的上次按压时间
key_press_times = {key: 0 for row in keys for key in row}
  • key_press_times:记录每个按键的上次按压时间,以防止在短时间内重复按压。

显示虚拟键盘的函数
def draw_keyboard(image): """ 在图像上绘制虚拟键盘 """ for i, row in enumerate(keys): for j, key in enumerate(row): # 计算按键的x坐标 x = j * 60 + 50 # 计算按键的y坐标 y = i * 60 + 150 # 绘制按键矩形 cv2.rectangle(image, (x, y), (x + 50, y + 50), (255, 255, 255), -1) # 绘制按键文本 cv2.putText(image, key, (x + 15, y + 35), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2) 
  • draw_keyboard(image):在图像上绘制虚拟键盘。
    • 遍历每一行的按键,计算每个按键的位置并绘制按键矩形和文字。

检测手指是否按压按键的函数
def detect_key_press(landmarks, image): """ 检测手指是否按压按键 """ # 食指指尖 index_finger_tip = landmarks[8] # 其他手指指尖 other_fingers_tips = [landmarks[i] for i in [4, 12, 16, 20]] # 食指指尖的z坐标 index_z = index_finger_tip.z # 其他手指指尖的z坐标 other_z = [tip.z for tip in other_fingers_tips] # 检测食指是否显著低于其他手指(z轴坐标显著不同) if all(index_z < z - 0.004 for z in other_z): # 转换食指坐标到图像坐标 x, y = int(index_finger_tip.x * image.shape[1]), int(index_finger_tip.y * image.shape[0]) # 获取当前时间 current_time = time.time() for i, row in enumerate(keys): for j, key in enumerate(row): # 计算按键的x坐标 key_x = j * 60 + 50 # 计算按键的y坐标 key_y = i * 60 + 150 # 检查食指坐标是否在按键范围内 if key_x < x < key_x + 50 and key_y < y < key_y + 50: # 检查按键是否在1秒内被按压过 if current_time - key_press_times[key] > 1: # 更新按键的上次按压时间 key_press_times[key] = current_time # 绘制按压效果 cv2.rectangle(image, (key_x, key_y), (key_x + 50, key_y + 50), (0, 255, 0), -1) cv2.putText(image, key, (key_x + 15, key_y + 35), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) print(f'Key {key} pressed') # 模拟键盘输入 if key == ' ': keyboard.press(' ') keyboard.release(' ') elif key == 'BACKSPACE': keyboard.press('\b') keyboard.release('\b') else: keyboard.press(key) keyboard.release(key)
  • detect_key_press(landmarks, image):检测手指是否按压按键。
    • index_finger_tip:获取食指指尖的位置。
    • other_fingers_tips:获取其他手指指尖的位置。
    • 通过比较食指和其他手指的z轴坐标,检测食指是否显著低于其他手指(表示按压动作)。
    • 计算食指在图像上的位置,遍历按键,检查食指是否在某个按键的范围内。
    • 如果按键在1秒内未被按压过,绘制按压效果并模拟键盘输入。

主循环
while True: # 读取摄像头图像 success, image = cap.read() if not success: break # 翻转图像 image = cv2.flip(image, 1) # 转换为RGB格式 image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 处理图像,检测手部 results = hands.process(image_rgb) if results.multi_hand_landmarks: for hand_landmarks in results.multi_hand_landmarks: # 绘制手部连接线 mp_drawing.draw_landmarks(image, hand_landmarks, mp_hands.HAND_CONNECTIONS) landmarks = hand_landmarks.landmark # 检测按压 detect_key_press(landmarks, image) # 绘制虚拟键盘 draw_keyboard(image) # 显示图像 cv2.imshow('Virtual Keyboard', image) # 按下ESC键退出 if cv2.waitKey(1) & 0xFF == 27: break
  • 在主循环中,代码不断读取摄像头图像并翻转图像以获得镜像效果。
  • 将图像从BGR格式转换为RGB格式,以便Mediapipe处理。
  • 使用Mediapipe检测手部位置,并绘制手部连接线。
  • 检测手指是否按压按键,并绘制虚拟键盘。
  • 显示图像,并检查是否按下ESC键以退出循环。

释放资源
cap.release() # 释放摄像头 cv2.destroyAllWindows() # 销毁所有窗口
  • 释放摄像头资源并销毁所有OpenCV窗口。

总结

        这段代码展示了如何使用摄像头捕捉手部动作,通过手部检测和位置跟踪来模拟按压虚拟键盘上的按键。代码通过OpenCV绘制虚拟键盘,并通过pynput模拟实际的键盘输入。这种技术可以用于各种交互式应用,如虚拟输入设备和手势控制系统。        

        还是挺简单的嘛。

虚拟键盘(不是软键盘)——科幻世界!!!


代码实现

        下面的是完整的全部代码,下载完对应的Python包即可运行。

import cv2 import mediapipe as mp import time from pynput.keyboard import Controller # 初始化Mediapipe的手部检测模块 mp_hands = mp.solutions.hands hands = mp_hands.Hands(min_detection_confidence=0.7, min_tracking_confidence=0.7) mp_drawing = mp.solutions.drawing_utils # 键盘控制器,用于模拟键盘输入 keyboard = Controller() # 打开摄像头 cap = cv2.VideoCapture(0) # 定义虚拟键盘的按键布局 keys = [ ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'], ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'], ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'], ['Z', 'X', 'C', 'V', 'B', 'N', 'M'], [' ', 'BACKSPACE'] ] # 记录每个按键的上次按压时间,以防止在1秒内重复按压 key_press_times = {key: 0 for row in keys for key in row} # 显示虚拟键盘的函数 def draw_keyboard(image): """ 在图像上绘制虚拟键盘 """ for i, row in enumerate(keys): for j, key in enumerate(row): # 计算按键的x坐标 x = j * 60 + 50 # 计算按键的y坐标 y = i * 60 + 150 # 绘制按键矩形 cv2.rectangle(image, (x, y), (x + 50, y + 50), (255, 255, 255), -1) # 绘制按键文本 cv2.putText(image, key, (x + 15, y + 35), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2) # 检测手指是否按压按键的函数 def detect_key_press(landmarks, image): """ 检测手指是否按压按键 """ # 食指指尖 index_finger_tip = landmarks[8] # 其他手指指尖 other_fingers_tips = [landmarks[i] for i in [4, 12, 16, 20]] # 食指指尖的z坐标 index_z = index_finger_tip.z # 其他手指指尖的z坐标 other_z = [tip.z for tip in other_fingers_tips] # 检测食指是否显著低于其他手指(z轴坐标显著不同) if all(index_z < z - 0.004 for z in other_z): # 转换食指坐标到图像坐标 x, y = int(index_finger_tip.x * image.shape[1]), int(index_finger_tip.y * image.shape[0]) # 获取当前时间 current_time = time.time() for i, row in enumerate(keys): for j, key in enumerate(row): # 计算按键的x坐标 key_x = j * 60 + 50 # 计算按键的y坐标 key_y = i * 60 + 150 # 检查食指坐标是否在按键范围内 if key_x < x < key_x + 50 and key_y < y < key_y + 50: # 检查按键是否在1秒内被按压过 if current_time - key_press_times[key] > 1: # 更新按键的上次按压时间 key_press_times[key] = current_time # 绘制按压效果 cv2.rectangle(image, (key_x, key_y), (key_x + 50, key_y + 50), (0, 255, 0), -1) cv2.putText(image, key, (key_x + 15, key_y + 35), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) print(f'Key {key} pressed') # 模拟键盘输入 if key == ' ': keyboard.press(' ') keyboard.release(' ') elif key == 'BACKSPACE': keyboard.press('\b') keyboard.release('\b') else: keyboard.press(key) keyboard.release(key) while True: # 读取摄像头图像 success, image = cap.read() if not success: break # 翻转图像 image = cv2.flip(image, 1) # 转换为RGB格式 image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 处理图像,检测手部 results = hands.process(image_rgb) if results.multi_hand_landmarks: for hand_landmarks in results.multi_hand_landmarks: # 绘制手部连接线 mp_drawing.draw_landmarks(image, hand_landmarks, mp_hands.HAND_CONNECTIONS) landmarks = hand_landmarks.landmark # 检测按压 detect_key_press(landmarks, image) # 绘制虚拟键盘 draw_keyboard(image) # 显示图像 cv2.imshow('Virtual Keyboard', image) # 按下ESC键退出 if cv2.waitKey(1) & 0xFF == 27: break # 释放摄像头 cap.release() # 销毁所有窗口 cv2.destroyAllWindows() 

效果展示

虚拟键盘(不是软键盘)——科幻世界!!!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/142934.html

(0)
上一篇 2025-05-06 22:00
下一篇 2025-05-06 22:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信