'''
AI手势虚拟拖动方块
author:MJY
time:2024-07-25
步骤:
1.创建视频流
'''
import cv2
import numpy as np
import math
#导入mediapipe包
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(
model_complexity=0,
min_detection_confidence=0.5,
min_tracking_confidence=0.5)
cap = cv2.VideoCapture(0)
#获取画面的宽度和高度
wideth = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH ))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT ))
#获取方块大小
square_x = 100
square_y = 100
width = 100
square_color = (125,0,125)
L1 = 0
L2 = 0
on_square = False
length = 0
while True:
#读取每一帧
ret,frame = cap.read()
#对图像进行处理
frame = cv2.flip(frame,1)
#mediapipe处理
frame.flags.writeable = False
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = hands.process(frame)
# Draw the hand annotations on the image.
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个,xy坐标
x_list = []
y_list = []
for landmarks in hand_landmarks.landmark :
#添加x坐标
x_list.append(landmarks.x )
# 添加x坐标
y_list.append(landmarks.y )
#获取食指的xy坐标
index_x_list = int(x_list[8]*wideth )
index_y_list = int(y_list[8]*height )
# 获取中指的xy坐标
midle_x_list = int(x_list[12] * wideth)
midle_y_list = int(y_list[12] * height)
#计算食指中指之间的距离
length = math.hypot((midle_x_list-index_x_list),(midle_y_list-index_y_list))
# #画一个圆来检测食指坐标是否正确
# cv2.circle(frame,(index_x_list,index_y_list),25,(0,255,0),-1)
#如果距离小于30算激活,否则取消激活
if length < 30:
# 判断食指指尖是否在方块上
if ((index_x_list > square_x) and (index_x_list < square_x + width)) and (
(index_y_list > square_y) and (index_y_list < square_y + width)):
# 如果已经进入方块,则不需要再次更新距离
if not on_square:
L1 = abs(index_x_list - square_x)
L2 = abs(index_y_list - square_y)
on_square = True
square_color = (0, 255, 127)
else:
# 如果手指离开了方块,重置 on_square
on_square = False
else:
on_square = False
square_color = (125, 0, 125)
if on_square:
square_x = index_x_list - L1
square_y = index_y_list - L2
# 绘制方块
overlay = frame.copy()
cv2.rectangle(frame, (square_x, square_y), (square_x + width, square_y + width), square_color, -1)
frame = cv2.addWeighted(overlay ,0.5,frame ,0.5,0)
#显示
cv2.imshow("virtual",frame)
#退出条件
if cv2.waitKey(10) & 0xff == ord('q'):
break
#释放摄像头
cap.release()
cv2.destroyAllWindows()