前几天看见一位博主用mediapipe写的拖动方块,于是我就有了写一个这个 代码 的想法,我原本要实现的功能是一只手给另一只手带上,但是随着我对里面函数的探索,我发现有点难实现,因为他results.multi_handedness里面可以知道左右手,但是点位在hand_landmarks.landmark这个里面,hand_landmarks.landmark不管你是左手还是右手,只要是手就往里面加点。于是戴戒指这个功能我就分成了两部分,右手拇指和食指达到一定距离后可以移动,左手的中指三个点位分别穿过戒指后,戒指就随左手中指的10号点位移动。
手的点 位图 :

这个 程序 目前只可以做到戒指的一维移动,也就是说戒指还只是图片,他只能保持原有的状态直线运动,当手竖起来的时候戒指的形状和手就不匹配了,这就需要通过其他算法完成了,我目前的水平还做不到。
这是戒指图片:

由于我还不会怎么弄动图,就只有放几张 截图 了


import cv2import timeimport mathimport numpy as npimport mediapipe as mp mp_drawing = mp.solutions.drawing_utilsmp_drawing_styles = mp.solutions.drawing_stylesmp_hands = mp.solutions.handshands = mp_hands.Hands( static_image_mode=True, max_num_hands=2, min_detection_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)) img=cv2.imread("./ring.png")ring_h,ring_w,ring_ch=img.shapeL1 = 0L2 = 0x=100y=100on_square = Falsemid_12=Falsemid_11=Falsemid_10=Falsewhile True: rec,frame = cap.read() frame = cv2.flip(frame,1) frame.flags.writeable = False frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 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: if results.multi_handedness: for hand in results.multi_handedness: #如果是右手 if hand.classification[0].label=='Right':# 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()) x_list = [] y_list = [] for landmark in hand_landmarks.landmark: x_list.append(landmark.x) y_list.append(landmark.y) index_finger_x, index_finger_y = int(x_list[8] * width),int(y_list[8] * height) thumb_finger_x,thumb_finger_y = int(x_list[4] * width), int(y_list[4] * height) finger_distance = math.hypot((thumb_finger_x - index_finger_x), (thumb_finger_y - index_finger_y)) if finger_distance < 100 : if (index_finger_x > x-10 and index_finger_x < (x + ring_h+10)) and ( index_finger_y > y-10 and index_finger_y < (y + ring_w+10)): if on_square == False: L1 = index_finger_x - x L2 = index_finger_y - y on_square = True else: on_square = False if on_square: x = index_finger_x - L1 y = index_finger_y - L2 if hand.classification[0].label=='Left': #如果识别为左手,处理左手中指的行为 x_list = [] y_list = [] for landmark in hand_landmarks.landmark: x_list.append(landmark.x) y_list.append(landmark.y) mid_finger_12_x,mid_finger_12_y=int(x_list[12]*width),int(y_list[12]*width) mid_finger_11_x,mid_finger_11_y=int(x_list[11]*width),int(y_list[11]*width) mid_finger_10_x,mid_finger_10_y=int(x_list[10]*width),int(y_list[10]*width)# if(mid_finger_12_y<y+ring_w and mid_finger_12_y>y and not mid_10):# mid_12=True# if(mid_finger_11_y<y+ring_w and mid_finger_11_y>y and mid_12 and mid_finger_12_x>x):# mid_11=True# if(mid_finger_10_y<y+ring_w and mid_finger_10_y>y and mid_11):# mid_10=True# if mid_10: #跟随中指10点位移动#这里可以先注释了省去戴的过程 x=mid_finger_10_x y=mid_finger_10_y-130 overlay = frame.copy() for i in range(ring_h):#这里是将原图片中接近白色的颜色筛除,只剩余戒指颜色 for j in range(ring_w): px=img[i,j] src2_beta=1 if(px[0],px[1],px[2])>=(245,245,245): continue color=(int(px[0]),int(px[1]),int(px[2])) cv2.rectangle(frame, (x+i, y+j), (x+i,y+j),color,-1) frame = cv2.addWeighted(overlay, 0.5, frame, src2_beta, 0) cv2.imshow('frame',frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release()cv2.destroyAllWindows()
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删