🚀 用Python和OpenCV实现手势虚拟拖拽,让你的双手成为魔法棒!🪄
文章目录
前言
大家好!今天,我们要探索一个超酷的Python项目——使用OpenCV实现手势虚拟拖拽。想象一下,通过简单的手势,就能在屏幕上拖动物体,就像使用魔法一样!🧙♂️
🌟 项目简介
这个项目不仅能让你深入了解Python编程和OpenCV库的强大功能,还能让你体验到手势识别的神奇。通过这个项目,你将学会如何通过摄像头捕捉手部动作,并用这些动作来控制屏幕上的虚拟对象。
🛠️ 技术栈
- Python:简洁而强大的编程语言。
- OpenCV:开源的计算机视觉库,用于图像和视频处理。
- mediapipe:用于手部关键点检测和姿势估计的预训练模型。
📝 核心步骤与代码
1. 导入库
import cv2
import mediapipe as mp
import time
import math
2. 初始化mediapipe手部识别
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(min_detection_confidence=0.7, min_tracking_confidence=0.5)
3. 读取视频流
cap = cv2.VideoCapture(0)
4. 手部识别与关键点检测
在循环中处理视频流的每一帧:
while cap.isOpened():
success, image = cap.read()
if not success:
continue
# 将BGR图像转换为RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 镜像翻转
image = cv2.flip(image, 1)
# 处理图像并检测手部
results = hands.process(image)
# 将RGB图像转换回BGR
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
5. 绘制手部关键点
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp.solutions.drawing_utils.draw_landmarks(
image,
hand_landmarks,
mp_hands.HAND_CONNECTIONS,
mp.solutions.drawing_styles.get_default_hand_landmarks_style(),
mp.solutions.drawing_styles.get_default_hand_connections_style())
6. 方块管理
创建一个管理方块的类:
class SquareManager:
def __init__(self, rect_width):
self.rect_width = rect_width
self.square_count = 0
self.rect_left_x_list = []
self.rect_left_y_list = []
self.alpha_list = []
self.drag_active = False
self.active_index = -1
def create(self, rect_left_x, rect_left_y, alpha=0.4):
self.rect_left_x_list.append(rect_left_x)
self.rect_left_y_list.append(rect_left_y)
self.alpha_list.append(alpha)
self.square_count += 1
def display(self, class_obj):
for i in range(self.square_count):
x = self.rect_left_x_list[i]
y = self.rect_left_y_list[i]
alpha = self.alpha_list[i]
overlay = class_obj.image.copy()
if i == self.active_index:
cv2.rectangle(overlay, (x, y), (x + self.rect_width, y + self.rect_width), (255, 0, 255), -1)
else:
cv2.rectangle(overlay, (x, y), (x + self.rect_width, y + self.rect_width), (255, 0, 0), -1)
class_obj.image = cv2.addWeighted(overlay, alpha, class_obj.image, 1 - alpha, 0)
7. 交互控制
在循环中更新方块位置:
squareManager = SquareManager(150)
for i in range(5):
squareManager.create(200 * i + 20, 200, 0.6)
# 检测手指距离并更新方块位置
if squareManager.drag_active:
squareManager.updateSquare(between_finger_tip[0], between_finger_tip[1])
if line_len > 100:
squareManager.drag_active = False
squareManager.active_index = -1
elif line_len < 100 and squareManager.checkOverlay(between_finger_tip[0], between_finger_tip[1]) != -1:
squareManager.drag_active = True
squareManager.setLen(between_finger_tip[0], between_finger_tip[1])
8. 显示图像
squareManager.display(hands)
cv2.imshow('virtual drag and drop', image)
if cv2.waitKey(5) & 0xFF == 27:
break
9. 释放资源
cap.release()
cv2.destroyAllWindows()