如何截取Mediapipe Pose的pose_landmarks,仅绘制排除前10个的关键点?
解决Mediapipe Pose只绘制第10个及以后关键点的问题
你遇到的TypeError是因为results.pose_landmarks是**NormalizedLandmarkList类型的Protobuf对象**,不是Python列表,所以不能直接用[10:]切片。真正存储关键点的是它的landmark属性——这才是包含所有姿态关键点的列表,可以直接切片。
具体实现步骤
1. 过滤关键点
先提取从第10个索引开始的关键点:
import cv2 import mediapipe as mp mp_pose = mp.solutions.pose mp_drawing = mp.solutions.drawing_utils # 初始化Pose模型 with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose: # 读取图像/视频帧 image = cv2.imread("your_image.jpg") image_height, image_width, _ = image.shape # 转换为RGB(Mediapipe要求输入为RGB) image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = pose.process(image_rgb) if results.pose_landmarks: # 提取第10个及以后的关键点(索引从0开始) filtered_landmarks = results.pose_landmarks.landmark[10:]
2. 绘制关键点(仅点)
如果只需要绘制关键点,直接遍历过滤后的列表,转换为像素坐标后画圆:
for landmark in filtered_landmarks: # 将归一化坐标转为图像像素坐标 x = int(landmark.x * image_width) y = int(landmark.y * image_height) # 绘制绿色实心圆,半径5,线宽-1表示填充 cv2.circle(image, (x, y), 5, (0, 255, 0), -1)
3. 绘制过滤后的连接线(可选)
如果需要保留关键点之间的连接,要先过滤Mediapipe自带的连接关系,只保留两个端点都在第10个及以后的连接:
# 获取Pose默认的连接关系 all_connections = mp_pose.POSE_CONNECTIONS # 过滤连接:仅保留两端索引都≥10的连接 filtered_connections = [(start, end) for start, end in all_connections if start >=10 and end >=10] # 绘制连接线 for start_idx, end_idx in filtered_connections: start_landmark = results.pose_landmarks.landmark[start_idx] end_landmark = results.pose_landmarks.landmark[end_idx] # 转换为像素坐标 start_point = (int(start_landmark.x * image_width), int(start_landmark.y * image_height)) end_point = (int(end_landmark.x * image_width), int(end_landmark.y * image_height)) # 绘制蓝色线条,线宽2 cv2.line(image, start_point, end_point, (255, 0, 0), 2)
4. 显示结果
最后展示处理后的图像:
cv2.imshow("Filtered Pose Landmarks", image) cv2.waitKey(0) cv2.destroyAllWindows()
关键说明
- 不要直接对
results.pose_landmarks做切片,必须访问它的landmark属性,这是Protobuf对象中存储列表的字段。 - 如果不需要连接线,只保留绘制关键点的代码即可;如果需要连接线,一定要过滤连接关系,避免出现连接到前10个关键点的无效线条。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

