NTU60-XSub 是人体动作识别最经典的标准数据集,专门用来练模型、做实验、发论文。
能干什么
人体骨骼动作识别
识别人体在做什么动作:走路、坐下、挥手、喝水、摔倒、握手 等一共60 种日常动作。主要给这些模型用
ST-GCN、2s-AGCN、MSG3D、Pose-Former、行为识别、图卷积网络 都拿它跑标准对比实验。XSub 作用
就是固定的训练/测试划分规则:
- 用一部分人的动作训练模型
- 用完全没见过的另一批人测试
用来检验模型能不能泛化到陌生人的动作。
适合什么场景
- 做基于骨骼的行为识别、姿态分析
- 做人机交互、监控异常行为检测、机械臂视觉控制
- 研究生/毕设/发论文 跑基线、对比模型精度
简单总结
你下载的NTU60Xsub=
现成的60类人体动作骨骼数据 + 标准跨人物训练测试划分,
拿来直接喂给动作识别模型,训练、测试、跑准确率、做对比实验用的。
下面把NTU60‑XSub(Cross‑Subject)给你讲清楚,从数据集含义、下载、目录结构到怎么用,一次性说明白,你自己下的原始数据也能对应上。
1. NTU60 与 XSub 是什么?
NTU60(NTU RGB+D 60):
- 60 类动作,共56,880 个样本
- 40 个演员(subject),3 个 Kinect 相机同时拍摄
- 每个样本包含:RGB 视频、深度图、3D 骨骼(25 个关节)、红外图
XSub(Cross‑Subject,跨主体)划分:
- 按演员 ID 划分训练/测试:
- 训练:20 个演员 →40,320 样本
- 测试:剩下 20 个演员 →16,560 样本
- 训练集演员 ID:
1,2,4,5,8,9,13,14,15,16,17,18,19,25,27,28,31,34,35,38 - 目的:训练和测试的人完全不重叠,验证模型泛化到新主体的能力。
- 按演员 ID 划分训练/测试:
2. 你自己下载的 NTU60 XSub 原始数据长什么样?
2.1 官方原始骨骼数据(你大概率下的是这个)
从官网申请后下载:
nturgbd_skeletons_s001_to_s017.zip→ NTU60 骨骼数据(所有主体)
解压后大概是:
nturgb+d_skeletons/ ├── S001C001P001R001A001.skeleton ├── S001C001P001R001A002.skeleton └── ...文件名含义:
Sxxx:subject(演员)IDCxxx:camera(相机)IDPxxx:performer(同主体下编号)Rxxx:repetition(动作重复次数)Axxx:action(动作类别,1~60)
2.2 处理好的 XSub 划分(常用于 ST‑GCN 等)
网上常见的预处理好的版本(如 PaddleVideo、ST‑GCN 提供)结构是:
NTU-RGB-D/ ├── xsub/ │ ├── train_data.npy │ ├── train_label.pkl │ ├── val_data.npy │ └── val_label.pkl └── xview/ └── ...train_data.npy:(N, C, T, V, M) → 样本数×3×帧数×25关节×1/2人train_label.pkl:对应标签
3. 怎么把你自己下的原始数据转成 XSub 训练/测试集?
核心逻辑:
- 遍历所有
.skeleton文件 - 从文件名提取
Sxxx(主体ID)和Axxx(动作ID) - 按XSub 训练主体ID列表分到训练集,其余到测试集
- 解析骨骼文件,整理成
(C, T, V, M)格式,保存为.npy+.pkl
伪代码思路(Python):
train_subjects={1,2,4,5,8,9,13,14,15,16,17,18,19,25,27,28,31,34,35,38}train_data,train_label=[],[]val_data,val_label=[],[]forfileinall_skeleton_files:# 解析文件名S=int(file[1:4])A=int(file[-7:-4])-1# 标签0~59# 解析骨骼内容 -> array(3, T, 25, M)skel=parse_skeleton(file)ifSintrain_subjects:train_data.append(skel)train_label.append(A)else:val_data.append(skel)val_label.append(A)# 保存np.save("xsub/train_data.npy",np.array(train_data))pickle.dump(train_label,open("xsub/train_label.pkl","wb"))...