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

多人步态分析结果显示匹配异常问题求助

多人步态分析结果显示不匹配问题

我接手了一个人体步态分析项目,目前遇到如下问题:多人步态分析的计算结果正确(print(results)可正常输出每个人的对应结果),但在通过笔记本摄像头实时显示时,所有人物均展示最后一个人的分析结果,无法将结果与对应人物匹配。我尝试过多线程、输出层等方法均未解决问题,以下是相关代码:

显示结果代码

import cv2, numpy

print(results) 

for _, item in enumerate(nose_coordinates):
    #  print(f'Person {_+1}: item {item} ')
    person_text = f"Person {_+1}: {results[_][0]}"
    frame = cv2.flip(frame, 1)
    if text == 'Steady':
        color = (0, 255, 0)
    elif text == 'Unsteady':
        color = (0, 0, 255)
    else:
        color = (0, 255, 255)
    cv2.putText(frame, person_text, (item[0], item[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.75, color, 2, cv2.LINE_AA)
    frame = cv2.flip(frame, 1)

尝试的输出层代码

def get_output_layers(net):
    layer_names = net.getLayerNames()
    output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
    return output_layers

完整步态分析代码

ret, frame = camera.read()
if not ret:
    break

frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

try:
    # Check for the 'esc' key to exit
    if cv2.waitKey(1) == 27:
        break

    output, frame = run_inference(frame)
    frame, distances, output, keypoints_list = draw_keypoints(output, frame)

    # Calculate FPS
    frame_count += 1
    elapsed_time = (datetime.now() - start_time).total_seconds()
    fps = frame_count / elapsed_time

    frame = cv2.flip(frame, 1)
    # Put FPS text on the frame
    cv2.putText(frame, f"FPS: {fps:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 255), 2, cv2.LINE_AA)
    frame = cv2.flip(frame, 1)
    # Initialize lists to store results for each person
    # results_per_person = [[] for _ in range(len(keypoints_list))]

    for idx, keypoints in enumerate(keypoints_list):
        
        p_count = keypoints['total_person']
        
        if len(arr) <= idx:
            arr.append([])
            # print(f'Person {idx+1}:  {arr[idx]} in {arr}')
        elif len(arr) > p_count:
            arr.pop()
            # print(f'Person {idx+1}: Updated {arr[idx]} in {arr}')

        # Get Nose coordinates
        Nose_x = keypoints['keypoints'][0]
        Nose_y = keypoints['keypoints'][1]

        Nose_x = int(Nose_x)
        Nose_y = int(Nose_y)
            
        LS_y = keypoints['keypoints'][16]
        RS_y = keypoints['keypoints'][19]
        LHip_x = keypoints['keypoints'][33]
        LHip_y = keypoints['keypoints'][34]
        RHip_x = keypoints['keypoints'][36]
        RHip_y = keypoints['keypoints'][37]
        LA_x = keypoints['keypoints'][45]
        LA_y = keypoints['keypoints'][46]
        RA_x = keypoints['keypoints'][48]
        RA_y = keypoints['keypoints'][49]
        LA_conf = keypoints['keypoints'][47]
        RA_conf = keypoints['keypoints'][50]

        Hip_x = ((LHip_x - RHip_x) / 2) + RHip_x
        Hip_y = (LHip_y + RHip_y) / 2
        shoulder_y = (LS_y + RS_y) / 2
        d = abs(Hip_y - shoulder_y)

        if len(arr[idx]) < counting:
            
            if LA_conf > 0.8 and RA_conf > 0.8:
                if text != "Default":
                    text = text

                if d == 0.0:
                    LAx = 15
                    LAy = 90
                    RAx = 15
                    RAy = 90
                else:
                    LA_x = round(abs((LA_x - Hip_x) / d) * 100, 2)
                    LA_y = round(abs((LA_y - Hip_y) / d) * 100, 2)
                    RA_x = round(abs((RA_x - Hip_x) / d) * 100, 2)
                    RA_y = round(abs((RA_y - Hip_y) / d) * 100, 2)

                    if LA_x == 0.0:
                        LAx = LAx
                    elif LA_x < 5.0:
                        LAx = 15
                    else:
                        LAx = LA_x

                    if LA_y == 0.0:
                        LAy = LAy
                    elif LA_y < 70.0:
                        LAy=90
                    else:
                        LAy = LA_y

                    if RA_x == 0.0:
                        RAx = RAx
                    elif RA_x < 5.0:
                        RAx=15
                    else:
                        RAx = RA_x

                    if RA_y == 0.0:
                        RAy = RAy
                    elif RA_y < 70.0:
                        RAy = 90
                    else:
                        RAy=RA_y
                
                keypoints_sequence = [LAx,LAy,RAx,RAy]
                # print(f'Person {idx+1} Keypoints Data|| {arr[idx]}')
                arr[idx].append(keypoints_sequence)

                x = x + 1

            else:
                
                check += 1
                if check == 48:
                    # print(f'\n No Foot detected|| Left Ankle: {str(keypoints[47])} + Right Ankle: {str(keypoints[50])}')
                    check = 0
                    text = "No Foot Detected"

        elif len(arr[idx]) == counting:
            # print(f'Person {idx+1} Keypoints Data|| {arr[idx]}')
            
            # Extract individual keypoint coordinates
            keypoints_data = np.array(arr[idx])  # Convert the list of lists to a NumPy array
            LAx_data = keypoints_data[:, 0]  # Extract LAx values
            RAx_data = keypoints_data[:, 2]  # Extract RAx values
            # print(f' LAx: {LAx_data} |||\n RAx: {RAx_data}')

            # Calculate standard deviations
            STDKP_R = statistics.stdev(RAx_data)
            STDKP_L = statistics.stdev(LAx_data)
            # print(f' STD_R: {STDKP_R}\n STD_L: {STDKP_L}')

            if (STDKP_R > 3.6) or (STDKP_L > 3.6):
                
                # Extract individual keypoint coordinates
                keypoints_data = np.array(arr[idx])  # Convert the list of lists to a NumPy array                        
                keypoints_data = keypoints_data.reshape(-1, sequence_length, feature_dims)
                # print(f' Input Data Shape: {keypoints_data}')
                print(f'Person {idx+1} Input Data Shape: {keypoints_data.shape}')
                predictions = model.predict(keypoints_data)  # Assuming X is your input data
                print(f'Prediction: {predictions}')
                predicted = np.argmax(predictions, axis=1)
                # print(f'Predicted: {predicted}')
                if 0 in predicted:
                    text = 'Steady'
                else:
                    text = 'Unsteady'
            else:
                text = 'No Movement Detected'

            arr[idx].clear()
            x = 0

        #  # Append classification result to the corresponding results list
        # results_per_person[idx].append(text)
        # append to results list 
        nose_coordinates.append([Nose_x-230, Nose_y])
        results.append([text])
        #print(f'Person {idx+1}: {results}')

    print(results)
    for _, item in enumerate(nose_coordinates):
        # print(f'Person {_+1}: item {item} ')
        person_text = f"Person {_+1}: {results[_][0]}"
        frame = cv2.flip(frame, 1)
        if text == 'Steady':
            color = (0, 255, 0)
        elif text == 'Unsteady':
            color = (0, 0, 255)
        else:
            color = (0, 255, 255)
        cv2.putText(frame, person_text, (item[0], item[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.75, color, 2, cv2.LINE_AA)
        frame = cv2.flip(frame, 1)

    # for idx, result_list in enumerate(results_per_person):
    #     for j, result in enumerate(result_list):
    #         person_text = f"Person {idx+1}: {result}"
    #         frame = cv2.flip(frame, 1)
    #         if result == 'Steady':
    #             color = (0, 255, 0)  # Green color for steady
    #         elif result == 'Unsteady':
    #             color = (0, 0, 255)  # Red color for unsteady
    #         else:
    #             color = (0, 255, 255)  # Yellow color for no movement detected
    #         nose_x, nose_y = nose_coordinates[idx]
    #         frame = cv2.putText(frame, person_text, (nose_x, nose_y + (30 * (j + 1))),
    #                             cv2.FONT_HERSHEY_SIMPLEX, 0.75, color, 2, cv2.LINE_AA)
    #         frame = cv2.flip(frame, 1)
    #         results_per_person[idx].append(result)

    cv2.imshow('Yolov7 Pose', cv2.flip(frame, 1))

    nose_coordinates, results = [], []

except Exception as e:
    print(e)

# Release the camera
camera.release()
cv2.destroyAllWindows()

问题原因及解决方案

核心问题

显示结果时,你使用全局变量text判断颜色,但这个变量在循环处理每个人物时会被持续覆盖,最终所有人物都使用了最后一次循环的text值。虽然results列表存储的结果是正确的,但颜色判断没有对应到当前人物的结果。

修复步骤

  1. 修改显示循环,绑定当前人物的结果
    将显示循环中的text替换为results[_][0],让每个人物的颜色匹配自己的分析结果:

    for _, item in enumerate(nose_coordinates):
        person_result = results[_][0]
        person_text = f"Person {_+1}: {person_result}"
        frame = cv2.flip(frame, 1)
        if person_result == 'Steady':
            color = (0, 255, 0)
        elif person_result == 'Unsteady':
            color = (0, 0, 255)
        else:
            color = (0, 255, 255)
        cv2.putText(frame, person_text, (item[0], item[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.75, color, 2, cv2.LINE_AA)
        frame = cv2.flip(frame, 1)
    
  2. 确保人物顺序一致性
    检查keypoints_list的顺序与nose_coordinates、results的顺序是否完全对应。如果draw_keypoints返回的人物顺序在帧与帧之间变化,需要加入人物跟踪逻辑(比如基于IOU匹配上一帧人物位置),避免顺序错乱导致结果错位。

  3. 优化变量作用域
    在处理每个人物时,用局部变量存储当前人物的结果,减少全局变量依赖。比如在for idx, keypoints in enumerate(keypoints_list)循环内,直接将当前人物的结果存入results,而非依赖全局text。

额外建议

  • 可以将人物的坐标和结果打包成字典存储,比如person_data = {"nose": (x,y), "result": current_text},降低列表索引匹配出错的概率。
  • 引入专业人物跟踪算法(如DeepSORT),确保跨帧的人物身份稳定,彻底解决因检测顺序变化导致的结果匹配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:55:56