如何在MediaPipe与OpenCV中区分左右手同编号关键点?
解决MediaPipe区分左右手同编号关键点的问题
问题根源
你的代码里,遍历每只手的关键点时,始终调用results.multi_handedness[0]获取标签——这意味着不管当前处理的是哪只手,都只会用第一只检测到的手的左右标签,导致两只手的同编号关键点被标记成同一个颜色。
修正后的完整代码
只需要在遍历手的时候,同步获取当前手的索引,对应到multi_handedness的对应项就能解决:
import cv2 import mediapipe as mp import time cap = cv2.VideoCapture(0) mpHands = mp.solutions.hands hands = mpHands.Hands(max_num_hands=2) mpDraw = mp.solutions.drawing_utils while True: success, img = cap.read() if not success: break img = cv2.flip(img, 1) # time.sleep(0.1) # 该语句会降低帧率,建议按需保留 imgRGB = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) results = hands.process(imgRGB) if results.multi_hand_landmarks: # 遍历手时同时获取索引,对应到multi_handedness的对应项 for hand_idx, handLms in enumerate(results.multi_hand_landmarks): # 获取当前手的左右标签 lbl = results.multi_handedness[hand_idx].classification[0].label for id, lm in enumerate(handLms.landmark): h,w,c = img.shape cx, cy = int(lm.x*w), int(lm.y*h) # 标记关键点#8 if id == 8: if lbl == 'Right': cv2.circle(img, (cx,cy), 8, (255,0,0), cv2.FILLED) else: cv2.circle(img, (cx,cy), 8, (255,255,0), cv2.FILLED) mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS, mpDraw.DrawingSpec(color=(121,0,255)), mpDraw.DrawingSpec(color=(0,255,0))) cv2.imshow("image", img) c = cv2.waitKey(7) % 0x100 if c == 27: break cap.release() cv2.destroyAllWindows()
提取左右手全部关键点的方法
如果需要单独提取并存储左右手所有40个关键点的坐标,可以用字典分类存储:
# 在循环外初始化存储容器 left_hand_coords = {} right_hand_coords = {} # 在处理results的循环内 if results.multi_hand_landmarks: for hand_idx, handLms in enumerate(results.multi_hand_landmarks): lbl = results.multi_handedness[hand_idx].classification[0].label for id, lm in enumerate(handLms.landmark): h,w,c = img.shape cx, cy = int(lm.x*w), int(lm.y*h) # 按标签存入对应字典,键为关键点ID if lbl == 'Right': right_hand_coords[id] = (cx, cy) else: left_hand_coords[id] = (cx, cy) # 之后可以直接通过ID获取对应坐标 # 比如获取右手关键点#8:right_hand_coords.get(8) # 获取左手关键点#8:left_hand_coords.get(8)
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

