You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Mediapipe人体测量程序中的IndexError: tuple index out of range

人体尺寸测量代码报错修复方案

错误日志

Traceback (most recent call last):
File "c:/Users/user/Desktop/Body detect/measurements4.py", line 23, in
results = pose.process(gray)
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\mediapipe\python\solutions\pose.py", line 185, in process
results = super().process(input_data={'image': image})
File "C:\Users\user\AppData\Local\Programs\Python\Python37\lib\site-packages\mediapipe\python\solution_base.py", line 353, in process
if data.shape[2] != RGB_CHANNELS:
IndexError: tuple index out of range

用户原始代码

import cv2
import mediapipe as mp
import math

# Set up Mediapipe Pose model
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.5, min_tracking_confidence=0.5)

# Capture video from webcam
cap = cv2.VideoCapture(0)

while True:
    # Read a frame from the webcam
    ret, frame = cap.read()

    # Flip the frame horizontally
    frame = cv2.flip(frame, 1)

    # Convert the frame to grayscale
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # Detect the pose landmarks in the frame
    results = pose.process(gray)

    # Check if any pose landmarks were detected
    if results.pose_landmarks:
        # Extract the coordinates of the shoulder, elbow, wrist, and chest landmarks
        landmarks = results.pose_landmarks.landmark
        shoulder_left = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER].x, landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER].y
        shoulder_right = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER].x, landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER].y
        elbow_left = landmarks[mp_pose.PoseLandmark.LEFT_ELBOW].x, landmarks[mp_pose.PoseLandmark.LEFT_ELBOW].y
        elbow_right = landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW].x, landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW].y
        wrist_left = landmarks[mp_pose.PoseLandmark.LEFT_WRIST].x, landmarks[mp_pose.PoseLandmark.LEFT_WRIST].y
        wrist_right = landmarks[mp_pose.PoseLandmark.RIGHT_WRIST].x, landmarks[mp_pose.PoseLandmark.RIGHT_WRIST].y
        chest = landmarks[mp_pose.PoseLandmark.MIDCHEST].x, landmarks[mp_pose.PoseLandmark.MIDCHEST].y

        # Calculate the distance between the shoulder joints to obtain the user's shoulder width in centimeters
        pixels_per_cm = 37  # adjust this value based on your camera and distance from camera to user
        shoulder_width = int(abs(shoulder_left[0] - shoulder_right[0]) * pixels_per_cm)

        # Calculate the distance between the elbow joints to obtain the user's arm length in centimeters
        arm_length_left = int(math.sqrt((elbow_left[0] - shoulder_left[0])**2 + (elbow_left[1] - shoulder_left[1])**2) * pixels_per_cm)
        arm_length_right = int(math.sqrt((elbow_right[0] - shoulder_right[0])**2 + (elbow_right[1] - shoulder_right[1])**2) * pixels_per_cm)

        # Measure the distance between the highest point of the shoulder joint to the bottom of the ribcage to obtain the user's upper body height in centimeters
        upper_body_height = int(abs(shoulder_left[1] - chest[1]) * pixels_per_cm)

        # Measure the distance between the chest points to obtain the user's chest size in centimeters
        chest_size = int(abs(chest[0] - chest[1]) * pixels_per_cm)

        # Display the measurements on the frame
        cv2.putText(frame, f"Shoulder width: {shoulder_width} cm", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
        cv2.putText(frame, f"Arm length (left): {arm_length_left} cm", (50, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
        cv2.putText(frame, f"Arm length (right): {arm_length_right} cm", (50, 110), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
        cv2.putText(frame, f"Upper body height: {upper_body_height} cm", (50, 140), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
        cv2.putText(frame, f"Chest size: {chest_size} cm", (50, 170), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)

        # Show the frame
        cv2.imshow('Frame', frame)

    # Exit if the user presses the 'q' key
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release the webcam and close the window
cap.release()
cv2.destroyAllWindows()

错误原因

Mediapipe Pose模型要求输入图像为RGB三通道格式,但代码中将帧转为了单通道灰度图,导致模型在读取通道维度(shape[2])时触发索引越界错误。此外代码缺少帧读取失败的判断,且胸部尺寸计算逻辑错误。

修复方案

1. 修正图像输入格式

移除灰度转换步骤,将OpenCV读取的BGR帧转为RGB格式后传入模型:

# 替换灰度转换代码为:
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = pose.process(rgb_frame)

2. 增加帧读取失败判断

在处理帧前检查ret值,避免空帧导致后续报错:

ret, frame = cap.read()
if not ret:
    print("无法读取摄像头帧")
    break

3. 修正胸部尺寸计算逻辑

原代码取同一个胸部 landmark的x、y差值无意义,改为使用左右胸点的横向距离计算:

# 新增左右胸点提取
chest_left = landmarks[mp_pose.PoseLandmark.LEFT_PECTORAL].x, landmarks[mp_pose.PoseLandmark.LEFT_PECTORAL].y
chest_right = landmarks[mp_pose.PoseLandmark.RIGHT_PECTORAL].x, landmarks[mp_pose.PoseLandmark.RIGHT_PECTORAL].y
# 计算胸部宽度
chest_size = int(abs(chest_left[0] - chest_right[0]) * pixels_per_cm)

修复后的完整代码

import cv2
import mediapipe as mp
import math

# Set up Mediapipe Pose model
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.5, min_tracking_confidence=0.5)

# Capture video from webcam
cap = cv2.VideoCapture(0)

while True:
    # Read a frame from the webcam
    ret, frame = cap.read()
    if not ret:
        print("无法读取摄像头帧")
        break

    # Flip the frame horizontally
    frame = cv2.flip(frame, 1)

    # Convert BGR frame to RGB for Mediapipe
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    # Detect the pose landmarks in the frame
    results = pose.process(rgb_frame)

    # Check if any pose landmarks were detected
    if results.pose_landmarks:
        # Extract the coordinates of the shoulder, elbow, wrist, and chest landmarks
        landmarks = results.pose_landmarks.landmark
        shoulder_left = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER].x, landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER].y
        shoulder_right = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER].x, landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER].y
        elbow_left = landmarks[mp_pose.PoseLandmark.LEFT_ELBOW].x, landmarks[mp_pose.PoseLandmark.LEFT_ELBOW].y
        elbow_right = landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW].x, landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW].y
        wrist_left = landmarks[mp_pose.PoseLandmark.LEFT_WRIST].x, landmarks[mp_pose.PoseLandmark.LEFT_WRIST].y
        wrist_right = landmarks[mp_pose.PoseLandmark.RIGHT_WRIST].x, landmarks[mp_pose.PoseLandmark.RIGHT_WRIST].y
        chest_mid = landmarks[mp_pose.PoseLandmark.MIDCHEST].x, landmarks[mp_pose.PoseLandmark.MIDCHEST].y
        chest_left = landmarks[mp_pose.PoseLandmark.LEFT_PECTORAL].x, landmarks[mp_pose.PoseLandmark.LEFT_PECTORAL].y
        chest_right = landmarks[mp_pose.PoseLandmark.RIGHT_PECTORAL].x, landmarks[mp_pose.PoseLandmark.RIGHT_PECTORAL].y

        # Calculate the distance between the shoulder joints to obtain the user's shoulder width in centimeters
        pixels_per_cm = 37  # adjust this value based on your camera and distance from camera to user
        shoulder_width = int(abs(shoulder_left[0] - shoulder_right[0]) * pixels_per_cm)

        # Calculate the distance between the elbow joints to obtain the user's arm length in centimeters
        arm_length_left = int(math.sqrt((elbow_left[0] - shoulder_left[0])**2 + (elbow_left[1] - shoulder_left[1])**2) * pixels_per_cm)
        arm_length_right = int(math.sqrt((elbow_right[0] - shoulder_right[0])**2 + (elbow_right[1] - shoulder_right[1])**2) * pixels_per_cm)

        # Measure the distance between the highest point of the shoulder joint to the bottom of the ribcage to obtain the user's upper body height in centimeters
        upper_body_height = int(abs(shoulder_left[1] - chest_mid[1]) * pixels_per_cm)

        # Measure the distance between left and right chest points to obtain chest size
        chest_size = int(abs(chest_left[0] - chest_right[0]) * pixels_per_cm)

        # Display the measurements on the frame
        cv2.putText(frame, f"Shoulder width: {shoulder_width} cm", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
        cv2.putText(frame, f"Arm length (left): {arm_length_left} cm", (50, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
        cv2.putText(frame, f"Arm length (right): {arm_length_right} cm", (50, 110), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
        cv2.putText(frame, f"Upper body height: {upper_body_height} cm", (50, 140), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
        cv2.putText(frame, f"Chest size: {chest_size} cm", (50, 170), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)

    # Show the frame
    cv2.imshow('Frame', frame)

    # Exit if the user presses the 'q' key
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release the webcam and close the window
cap.release()
cv2.destroyAllWindows()

内容的提问来源于stack exchange,提问作者Anji_Ishu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:57:02