手指拖拽屏幕上的方块儿
1 步骤:
1.opencv获取视频流
2.获取手指关节关键点坐标
3.判断手指是否在方块上
4.如果在方块上,方块跟着手指移动
2 代码
import cv2
import numpy as np
import math
import mediapipe as mp
## 检测手掌参数设置
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands
# 获取手的21个关节
hands = mp_hands.Hands(
model_complexity=0,
min_detection_confidence=0.5,
min_tracking_confidence=0.5)
# 获取摄像头的视频流
cap = cv2.VideoCapture(0)
# 获取画面宽度,高度
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 方块的相关参数
## box左上角坐标、宽度、颜色
box_x = 100
box_y = 100
box_width = 100
box_high = 120
box_color = (255, 0, 255)
## 阈值,当食指和中指指尖距离大于阈值时,停止移动box
threth = 80
## 食指指尖与box左上角坐标的距离
d1 = 0
d2 = 0
## 食指指尖是否在方块上
on_box = False
while True:
# 1. 读取每一帧
ret, frame = cap.read()
# 对图像进行处理
# 镜像处理,对y轴进行翻转
frame = cv2.flip(frame, 1)
# mediapipe处理RGB通道的图像
frame.flags.writeable = False
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
## 2.手掌检测RGB图像
results = hands.process(frame)
frame.flags.writeable = True
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
# 判断是否检测到手掌
if results.multi_hand_landmarks:
# 遍历每一只手掌
for hand_landmarks in results.multi_hand_landmarks:
# 绘制手掌的21个关键点
mp_drawing.draw_landmarks(
frame,
hand_landmarks,
mp_hands.HAND_CONNECTIONS,
mp_drawing_styles.get_default_hand_landmarks_style(),
mp_drawing_styles.get_default_hand_connections_style()
)
# 保存手掌的21个x,y的坐标
x_list = []
y_list = []
for landmark in hand_landmarks.landmark: # 会循环21次把手的关节弄好
# 添加x坐标
x_list.append(landmark.x) # append表示添加x坐标
# 添加y坐标
y_list.append(landmark.y)
# 获取食指指尖xy坐标
index_finger_x = int(x_list[8] * width)
index_finger_y = int(y_list[8] * height)
# 获取中指指尖,用于退出方块
middle_finger_x = int(x_list[12] * width)
middle_finger_y = int(y_list[12] * height)
# 计算食指指尖和中指指尖的欧式距离
finger_len = math.hypot((index_finger_x - middle_finger_x),
(index_finger_y - middle_finger_y))
if finger_len < threth:
# 3. 判断指尖是否在方块上面
if (box_x < index_finger_x < box_x + box_width and box_y < index_finger_y < box_y + box_high):
if on_box == False:
## 如果食指在box内移动,则保持d1、d2不更新,即box与食指的相对位置不变
d1 = abs(index_finger_x - box_x)
d2 = abs(index_finger_y - box_y)
on_box = True
## 如果食指在box上,则变换box为水红色
box_color = (255, 0, 255)
else:
on_box = False
## 如果食指不在box上,则变换box为蓝颜
box_color = (255, 0, 0)
if on_box: # 如果手指在方块上面
box_x = index_finger_x - d1 # 根据算法
box_y = index_finger_y - d2
# 4. 画出box
cv2.rectangle(frame, (box_x, box_y), (box_x + box_width, box_y + box_high), box_color, -1)
frame = cv2.addWeighted(frame.copy(), 0.5, frame, 0.5, 0) # 做一个半透明
# 显示图像
cv2.imshow('Box drag', frame)
# 退出条件
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
标签:02,box,index,frame,cv2,案例,图像处理,finger,mp
From: https://www.cnblogs.com/shanjuqiuming/p/18339048