多人步态分析结果显示匹配异常问题求助
多人步态分析结果显示不匹配问题
我接手了一个人体步态分析项目,目前遇到如下问题:多人步态分析的计算结果正确(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列表存储的结果是正确的,但颜色判断没有对应到当前人物的结果。
修复步骤
修改显示循环,绑定当前人物的结果
将显示循环中的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)确保人物顺序一致性
检查keypoints_list的顺序与nose_coordinates、results的顺序是否完全对应。如果draw_keypoints返回的人物顺序在帧与帧之间变化,需要加入人物跟踪逻辑(比如基于IOU匹配上一帧人物位置),避免顺序错乱导致结果错位。优化变量作用域
在处理每个人物时,用局部变量存储当前人物的结果,减少全局变量依赖。比如在for idx, keypoints in enumerate(keypoints_list)循环内,直接将当前人物的结果存入results,而非依赖全局text。
额外建议
- 可以将人物的坐标和结果打包成字典存储,比如
person_data = {"nose": (x,y), "result": current_text},降低列表索引匹配出错的概率。 - 引入专业人物跟踪算法(如DeepSORT),确保跨帧的人物身份稳定,彻底解决因检测顺序变化导致的结果匹配问题。
内容的提问来源于stack exchange,提问作者voidsheep
相关产品推荐
相关产品推荐

