| | import os |
| | import json |
| | import matplotlib.pyplot as plt |
| | import numpy as np |
| | from pose_classifier import PoseClassifier |
| | import torch |
| | from collections import defaultdict |
| |
|
| | def analyze_turning_patterns_detailed(dataset_path, num_samples=50): |
| | """详细分析转弯模式,基于相对于reference的pose变化""" |
| | classifier = PoseClassifier() |
| | samples_path = os.path.join(dataset_path, "samples") |
| | |
| | all_analyses = [] |
| | sample_count = 0 |
| | |
| | |
| | class_samples = defaultdict(list) |
| | |
| | print("=== 开始分析样本(基于相对于reference的变化)===") |
| | |
| | for item in sorted(os.listdir(samples_path)): |
| | if sample_count >= num_samples: |
| | break |
| | |
| | sample_dir = os.path.join(samples_path, item) |
| | if os.path.isdir(sample_dir): |
| | poses_path = os.path.join(sample_dir, "poses.json") |
| | if os.path.exists(poses_path): |
| | try: |
| | with open(poses_path, 'r') as f: |
| | poses_data = json.load(f) |
| | |
| | target_relative_poses = poses_data['target_relative_poses'] |
| | |
| | if len(target_relative_poses) > 0: |
| | |
| | pose_vecs = [] |
| | for pose_data in target_relative_poses: |
| | |
| | translation = torch.tensor(pose_data['relative_translation'], dtype=torch.float32) |
| | |
| | |
| | current_rotation = torch.tensor(pose_data['current_rotation'], dtype=torch.float32) |
| | reference_rotation = torch.tensor(pose_data['reference_rotation'], dtype=torch.float32) |
| | |
| | |
| | relative_rotation = calculate_relative_rotation(current_rotation, reference_rotation) |
| | |
| | |
| | pose_vec = torch.cat([translation, relative_rotation], dim=0) |
| | pose_vecs.append(pose_vec) |
| | |
| | if pose_vecs: |
| | pose_sequence = torch.stack(pose_vecs, dim=0) |
| | |
| | |
| | analysis = classifier.analyze_pose_sequence(pose_sequence) |
| | analysis['sample_name'] = item |
| | all_analyses.append(analysis) |
| | |
| | |
| | print(f"\n--- 样本 {sample_count + 1}: {item} ---") |
| | print(f"总帧数: {analysis['total_frames']}") |
| | print(f"总距离: {analysis['total_distance']:.4f}") |
| | |
| | |
| | class_dist = analysis['class_distribution'] |
| | print(f"分类分布:") |
| | for class_name, count in class_dist.items(): |
| | percentage = count / analysis['total_frames'] * 100 |
| | print(f" {class_name}: {count} 帧 ({percentage:.1f}%)") |
| | |
| | |
| | print(f"前3帧的详细分类过程:") |
| | for i in range(min(3, len(pose_vecs))): |
| | debug_info = classifier.debug_single_pose( |
| | pose_vecs[i][:3], pose_vecs[i][3:7] |
| | ) |
| | print(f" 帧{i}: {debug_info['classification']} " |
| | f"(yaw: {debug_info['yaw_angle_deg']:.2f}°, " |
| | f"forward: {debug_info['forward_movement']:.3f})") |
| | |
| | |
| | print(f"运动段落:") |
| | for i, segment in enumerate(analysis['motion_segments']): |
| | print(f" 段落{i+1}: {segment['class']} (帧 {segment['start_frame']}-{segment['end_frame']}, 持续 {segment['duration']} 帧)") |
| | |
| | |
| | dominant_class = max(class_dist.items(), key=lambda x: x[1]) |
| | dominant_class_name = dominant_class[0] |
| | dominant_percentage = dominant_class[1] / analysis['total_frames'] * 100 |
| | |
| | print(f"主要运动类型: {dominant_class_name} ({dominant_percentage:.1f}%)") |
| | |
| | |
| | class_samples[dominant_class_name].append({ |
| | 'name': item, |
| | 'percentage': dominant_percentage, |
| | 'analysis': analysis |
| | }) |
| | |
| | sample_count += 1 |
| | |
| | except Exception as e: |
| | print(f"❌ 处理样本 {item} 时出错: {e}") |
| | |
| | print("\n" + "="*60) |
| | print("=== 按类别分组的样本统计(基于相对于reference的变化)===") |
| | |
| | |
| | for class_name in ['forward', 'backward', 'left_turn', 'right_turn']: |
| | samples = class_samples[class_name] |
| | print(f"\n🔸 {class_name.upper()} 类样本 (共 {len(samples)} 个):") |
| | |
| | if samples: |
| | |
| | samples.sort(key=lambda x: x['percentage'], reverse=True) |
| | |
| | for i, sample_info in enumerate(samples, 1): |
| | print(f" {i:2d}. {sample_info['name']} ({sample_info['percentage']:.1f}%)") |
| | |
| | |
| | segments = sample_info['analysis']['motion_segments'] |
| | segment_summary = [] |
| | for seg in segments: |
| | if seg['duration'] >= 2: |
| | segment_summary.append(f"{seg['class']}({seg['duration']})") |
| | |
| | if segment_summary: |
| | print(f" 段落: {' -> '.join(segment_summary)}") |
| | else: |
| | print(" (无样本)") |
| | |
| | |
| | print(f"\n" + "="*60) |
| | print("=== 总体统计 ===") |
| | |
| | total_forward = sum(a['class_distribution']['forward'] for a in all_analyses) |
| | total_backward = sum(a['class_distribution']['backward'] for a in all_analyses) |
| | total_left_turn = sum(a['class_distribution']['left_turn'] for a in all_analyses) |
| | total_right_turn = sum(a['class_distribution']['right_turn'] for a in all_analyses) |
| | total_frames = total_forward + total_backward + total_left_turn + total_right_turn |
| | |
| | print(f"总样本数: {len(all_analyses)}") |
| | print(f"总帧数: {total_frames}") |
| | print(f"Forward: {total_forward} 帧 ({total_forward/total_frames*100:.1f}%)") |
| | print(f"Backward: {total_backward} 帧 ({total_backward/total_frames*100:.1f}%)") |
| | print(f"Left Turn: {total_left_turn} 帧 ({total_left_turn/total_frames*100:.1f}%)") |
| | print(f"Right Turn: {total_right_turn} 帧 ({total_right_turn/total_frames*100:.1f}%)") |
| | |
| | |
| | print(f"\n按主要类型的样本分布:") |
| | for class_name in ['forward', 'backward', 'left_turn', 'right_turn']: |
| | count = len(class_samples[class_name]) |
| | percentage = count / len(all_analyses) * 100 if all_analyses else 0 |
| | print(f" {class_name}: {count} 样本 ({percentage:.1f}%)") |
| | |
| | return all_analyses, class_samples |
| |
|
| | def calculate_relative_rotation(current_rotation, reference_rotation): |
| | """计算相对旋转四元数""" |
| | q_current = torch.tensor(current_rotation, dtype=torch.float32) |
| | q_ref = torch.tensor(reference_rotation, dtype=torch.float32) |
| |
|
| | |
| | q_ref_inv = torch.tensor([q_ref[0], -q_ref[1], -q_ref[2], -q_ref[3]]) |
| |
|
| | |
| | w1, x1, y1, z1 = q_ref_inv |
| | w2, x2, y2, z2 = q_current |
| |
|
| | relative_rotation = torch.tensor([ |
| | w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2, |
| | w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2, |
| | w1 * y2 - x1 * z2 + y1 * w2 + z1 * x2, |
| | w1 * z2 + x1 * y2 - y1 * x2 + z1 * w2 |
| | ]) |
| |
|
| | return relative_rotation |
| |
|
| | if __name__ == "__main__": |
| | dataset_path = "/share_zhuyixuan05/zhuyixuan05/nuscenes_video_generation_2" |
| | |
| | print("开始详细分析pose分类(基于相对于reference的变化)...") |
| | all_analyses, class_samples = analyze_turning_patterns_detailed(dataset_path, num_samples=4000) |
| | |
| | print(f"\n🎉 分析完成! 共处理 {len(all_analyses)} 个样本") |