ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Python获取Human3.6M数据集全流程:申请、FTP下载与坐标解析

Python获取Human3.6M数据集全流程:申请、FTP下载与坐标解析 简介Human3.6M是3D人体姿态估计领域常用的基准数据集包含多视角视频、3D关节位置以及相机参数等标注。围绕该数据集的获取与预处理这里提供一套面向Python开发者和机器学习学习者的工具包重点解决从数据集下载、压缩包解压到元数据解析的完整流程适合研究者、课程设计者快速上手。压缩包共14个文件以Python脚本为主覆盖下载、解压、批处理与元数据提取等环节同时附有依赖配置、配置示例、说明文档以及Dockerfile/docker-compose.yml可一键复现运行环境。资源整体仅34KB轻量实用已有3624人学习/下载。通过这套脚本可以省去手工查找下载链接、处理HDF5格式与搭建环境的重复劳动直接获得可用的数据准备流程对于初学者脚本结构简明注释清晰也可作为学习Python数据处理与人体姿态数据规范的参考。 在3D人体姿态估计这个方向里Human3.6M经常也被写成Human36M基本是一块绕不开的招牌数据集。不管是复现论文、做对比实验还是拿预训练模型估指标前期第一道坎往往不是算法本身而是怎么把这套庞大数据集完整拿到手。我前后申请、下载、解析过这套数据好几次每次都会碰到新问题比如FTP连接方式不对、下载中断、Mat文件打不开、3D坐标坐标系没搞明白。今天就把我用Python完整获取Human3.6M人体姿态数据集的过程整理一遍从官网申请、账号权限、FTP批量下载到最后的Mat/XML解析和3D坐标提取都写清楚。准备入坑3D人体姿态估计的同学或者刚拿到数据集下载权限正对着目录发愁的朋友这篇可以直接当操作手册用。1. 为什么都在搞Human3.6M数据集与选型思路1.1 Human3.6M到底装了什么Human3.6M这套数据集是2014年前后发布的全称叫“Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments”来自慕尼黑工业大学等机构。名字里的“3.6M”指的是大约360万个3D人体姿态标注这是它最大的卖点规模够大、动作场景够全而且是真实环境、多视角同步采集不是合成数据。具体内容可以从几个维度拆开看演员数量总共11个专业演员其中公开带3D标注的是7个通常记为S1、S5、S6、S7、S8、S9、S11。动作场景17个日常动作包括Directions、Discussion、Eating、Greeting、Phoning、Photo、Posing、Purchases、Sitting、SittingDown、Smoking、Waiting、WalkDog、Walking、WalkTogether等等每个动作大概一两分钟按50Hz帧率录制。拍摄设备4个VGA摄像头从不同视角同步拍摄RGB视频同时有10个Vicon红外动捕相机以100Hz频率采集精确的3D关节坐标。数据格式官方发布的文件里既有mp4视频也有XML格式的2D标注、Mat格式的3D坐标还有加速度计数据等元信息。这个数据集之所以是标杆是因为它同时提供了多视角2D图像、精准3D真值、以及动作类别标签刚好覆盖了“从2D图像估计3D姿态”这条研究主线需要的全部要素。相比后来出的MPI-INF-3DHP、AMASS、TotalCaptureHuman3.6M在动作种类和样本规模上依然是最常用的基准之一。1.2 用Python脚本获取这套数据的核心思路获取Human3.6M不是像下载开源代码那样点个链接就能拉下来它走的是“官网申请 → 人工审核 → 邮件下发FTP账号 → 登录FTP批量下载”这条路子。为什么推荐用Python写脚本而不是用FileZilla之类工具手动拖原因很简单文件太多、目录太深。假设你要把7个演员的17个动作全部拉下来每个动作又有4个视角的视频和整套标注文件手动下载基本不现实而且中途断线了你很难知道哪个文件坏了一半。用ftplib加断点续传逻辑可以做到“跑到一半断了重新跑自动跳过已下载文件”这是手工方式替代不了的。我的完整流程是申请通过后拿到FTP凭证先用脚本探测目录结构再写一个可断点续传的批量下载器最后把Mat格式的3D坐标解析成npy或者json方便后续喂给深度学习模型。2. 申请与准备把权限拿到手2.1 官网注册申请的那些细节Human3.6M官网有一个专门的下载申请入口不是直接给链接需要填一张表单。我记得大致要提交这几项姓名、所属机构、邮箱地址、使用用途说明。提交之后就是等人工审核快的话一两天慢的话可能一周多。这里有几个实操经验邮箱尽量填机构邮箱比如大学或者研究所的edu邮箱审核通过率会高很多。填个人邮箱不是不行只是有些维护者会谨慎一些。用途说明别写太宽泛比如“I want to use this dataset for research on 3D human pose estimation”明确说明做3D姿态估计研究、非商用、不会二次分发就够了。审核通过后官方回复邮件里一般会附上FTP服务器地址和账号密码。有些版本的申请流程是直接在网页上显示凭证务必保存好后面每个下载步骤都要用。有一点需要特别提醒数据集的使用协议通常只允许学术研究拿到账号后不要公开分享也不要把数据集重新打包上传到网盘或GitHub上。这既关系到学术诚信也是维护渠道能被长期使用的基本共识。2.2 本地Python运行环境准备下载和解析Human3.6M用不到太重型的框架但有几个基础环境最好提前配好。如果你机器上还没装Python建议直接装3.10或者3.11版本别用太老的2.7很多依赖库已经不支持了。需要用到的库不多核心是这几个ftplibPython内置的FTP客户端支持FTP_TLS加密连接不需要额外安装。scipy用来读取Mat格式的3D坐标文件。tqdm下载进度条纯体验增强但建议装。numpy解析后数据格式转换必备。h5py如果你的Mat文件是v7.3版本loadmat打不开就需要h5py来处理。安装命令很简单pip install scipy numpy tqdm h5py如果你在公司或者学校内网pip下载慢可以先把pip源切换成国内镜像这个属于常规操作不展开说了。3. 用Python批量下载Human3.6M核心文件3.1 FTP连接与目录结构探测拿到账号后的第一步不是直接下载而是先摸清FTP目录长什么样。Human3.6M的目录结构比较规整大体上是“演员代号 → 动作场景 → 具体文件”。比如S1这个演员下面会有Directions、Discussion这些动作文件夹每个动作文件夹里放着视频、XML标注和Mat文件。用Python连接FTP的代码如下from ftplib import FTP_TLS ftp FTP_TLS(your.ftp.server.address) ftp.login(your_username, your_password) ftp.prot_p() # 切换为加密数据传输通道 # 列出根目录 ftp.retrlines(LIST) # 进入某个演员目录并列出内容 ftp.cwd(S1) ftp.retrlines(LIST)这里有个容易踩的坑很多FTP服务器要求显式TLS加密也就是连接后必须调用prot_p()把数据通道切换成加密模式否则登录成功了一执行LIST或下载就会报错。第一次拿到账号时我直接照搬普通ftplib.FTP的写法结果卡在列目录上后来换成FTP_TLS加prot_p()才通过。列目录这一步很关键因为官方目录里除了演员数据还有说明文档、序列文件列表之类的乱七八糟内容。搞清楚哪些是你要的能省下不少磁盘空间和下载时间。3.2 批量下载脚本实战目录结构摸清楚之后就可以写批量下载脚本了。我的做法是先维护一个files_to_download列表每一项是FTP上的相对路径比如S1/Directions_1/Directions_1.mat然后循环下载。一个可用的下载示例import os from ftplib import FTP_TLS from tqdm import tqdm ftp FTP_TLS(your.ftp.server.address) ftp.login(your_username, your_password) ftp.prot_p() def download_file(remote_path, local_path): os.makedirs(os.path.dirname(local_path), exist_okTrue) # 如果本地文件已存在且大小一致就跳过 if os.path.exists(local_path): local_size os.path.getsize(local_path) remote_size ftp.size(remote_path) if local_size remote_size: print(fskip {remote_path}) return ftp.voidcmd(TYPE I) with open(local_path, wb) as f: ftp.retrbinary(fRETR {remote_path}, f.write) print(fdone {remote_path}) remote_files [ S1/Directions_1/Directions_1.mat, S1/Directions_1/Directions_1.avi, # 这里按实际目录补充 ] for remote in tqdm(remote_files): local os.path.join(data/h36m, remote) download_file(remote, local)脚本里最关键的就是ftp.size()和本地文件大小对比这一步就是断点续传的基础。只要本地文件大小和远端一致就默认下载完整直接跳过。虽然这个判断不校验内容但对大规模下载来说已经够用真正要保证完整性可以在全部下完后做一次MD5抽查。另外TYPE I一定要记得设置否则FTP默认可能是ASCII模式下载二进制文件时会把文件搞坏。这也是一个很容易被忽略的细节。3.3 小技巧怎么避免重复下载如果你只做算法验证没必要把7个演员的数据全下载下来。我一般建议先只下载S1这一个演员的完整数据跑通整个流程再按需补数据。原因有两个第一Human3.6M视频文件不小7个演员全量下载要占几TB空间第二大多数论文对比实验只用到部分演员S1加S5基本能覆盖常规需求。下载目录的命名也建议和FTP保持完全一致比如data/h36m/S1/Directions_1/Directions_1.mat。这样后续写数据加载器时路径可以直接拼接不用做多余映射。还有一点别边下载边改文件名后续对照官方序列列表时会非常痛苦。4. 数据解析把3D坐标从Mat和XML里抽出来4.1 读取3D关键点的标准姿势下载完成后最核心的工作就是把Mat文件里的3D坐标解析出来。Human3.6M的3D关节坐标是以毫米为单位的坐标系是相机坐标系也就是以相机光心为原点Z轴朝外。这一点非常关键我见过有人在没搞清楚坐标系的情况下直接用结果骨骼扭曲得不成样子。读取Mat文件的标准姿势是用scipy.io.loadmatimport scipy.io as sio import numpy as np mat_path data/h36m/S1/Directions_1/Directions_1.mat data sio.loadmat(mat_path) print(data.keys())不同来源的Mat文件内部结构其实不太一样有的直接有data_3d字段有的是以动作名命名的结构体。稳妥做法是先print(data.keys())看一级字段再print(data[field].dtype)看结构体的内部字段不要想当然地写死索引。我拿到过的一个版本结构大致是data_3d字段shape为(帧数, 关节点数, 3)顺序对应COCO架构的17个关键点。把3D坐标存成npy格式if data_3d in data: pose_3d data[data_3d] # (N, J, 3) np.save(S1_Directions_1_3d.npy, pose_3d)如果你打印后看到的不是data_3d而是A1_Directions_1这种结构体先别急里面通常有joints_3d、pose之类的子字段。用data[field][0, 0]这种方式一层层拆开看就行。这一步是纯探索性质的花几分钟搞清楚结构后面能省几小时。4.2 某类Mat文件打不开用h5py兜底loadmat有一个很烦躁的限制如果Mat文件是v7.3格式保存的它直接报错“please use hdf5 reader”。这个报错本身其实是在帮你指路遇到这种情况就换h5py读取。import h5py import numpy as np with h5py.File(mat_path, r) as f: data_3d f[data_3d][:] # h5py读出来的数据维度通常是转置的注意转回 (N, J, 3) if data_3d.ndim 4: data_3d data_3d.transpose(3, 2, 1, 0)v7.3格式用的是HDF5存储读出来的数组维度和loadmat不完全一样经常需要转置才能还原成正常的(帧数, 关节点数, 坐标)结构。这也是个高频坑我一度以为数据是坏的后来发现只是一次转置的差别。4.3 补充知识多视角2D关键点三角化有时候你从官方拿到的只有XML里的2D标注或者你用了自己的2D检测器得到关键点想在没有官方3D真值的情况下恢复3D坐标那就需要多视角几何三角化。只要有两个以上视角的2D关键点并且知道相机投影矩阵P就可以反算3D位置。基本原理是把每个视角的2D投影方程堆叠起来得到一个线性方程组用最小二乘或者SVD求解。代码可以参考下面这个最朴素的版本import numpy as np def triangulate(points, P): points: 多个视角的2D关键点坐标, shape (n_views, 2) P: 每个视角的相机投影矩阵, shape (n_views, 3, 4) 返回: 3D坐标, shape (3,) A [] for i, (pt, Pi) in enumerate(zip(points, P)): u, v pt A.append([u * Pi[2, 0] - Pi[0, 0], u * Pi[2, 1] - Pi[0, 1], u * Pi[2, 2] - Pi[0, 2], u * Pi[2, 3] - Pi[0, 3]]) A.append([v * Pi[2, 0] - Pi[1, 0], v * Pi[2, 1] - Pi[1, 1], v * Pi[2, 2] - Pi[1, 2], v * Pi[2, 3] - Pi[1, 3]]) _, _, Vt np.linalg.svd(np.array(A)) X Vt[-1] return X[:3] / X[3]视角越多三角化越稳但至少两个视角就能出一个结果。这个方法在复现论文时会经常用到尤其是你想验证“只用2D标注能不能恢复3D姿态”这类问题。5. 常见问题与排查技巧5.1 FTP连接失败或登录报错如果你连接FTP时报错先确认三件事是否用了FTP_TLS、是否调用了prot_p()、账号密码是否包含多余空格。我遇到过几次复制邮件里的密码时把首尾空格也带进去了表现为登录返回530错误。另外有些服务器会限制并发连接数如果脚本开了多线程容易被服务器断开建议下载阶段先用单线程跑通。如果FTP连接总是超时检查一下本机防火墙和代理设置。部分网络环境下FTP的21端口被限制这个属于网络环境问题一般换个网络环境或者联系学校IT处理。5.2 下载中断后怎么续传下载过程中网络断了很常见尤其是视频文件动辄几百MB。好在我们已经在代码里做了“本地文件大小对比”的判断重新运行脚本时会自动跳过已完成的文件只补下载残缺的那部分。需要注意的是如果FTP服务器不支持SIZE命令ftp.size()可能报错这时可以改成对比本地文件大小是否大于某个阈值或者干脆每次重新下载小文件视频类大文件才走续传逻辑。5.3 Mat文件结构对不上这句话我建议反复强调不要假设所有Mat文件结构一致。官方数据经过多次重新整理不同时期下载的文件内部字段可能不同。遇到这种情况用Python交互式打印data.keys()、data[field].dtype、data[field].shape一层层剥开看。花10分钟做探索性分析比网上搜各种奇怪教程靠谱得多。5.4 下载慢到怀疑人生怎么办Human3.6M数据量很大尤其是RGB视频全部下完需要较长时间。如果FTP服务器直连速度很慢可以试试分多个时间段下载每次跑一部分或者只挑选自己需要的动作和视角不要一次全下。另外下载时加上重试逻辑比如单个文件重试三次失败后跳过并记录日志最后统一补下失败列表。这个策略实测下来比一次性拉到底稳得多。根据我个人经验最实用的做法是给自己定一个“先跑通再扩容”的节奏只下载S1演员的Directions和Walking两个动作先用一小批数据完成下载、解析、可视化全流程确认3D坐标的单位、坐标系、关节顺序都没问题再决定要不要把整个数据集拉全。这样即使中途发现问题损失的时间也有限不会因为全量下载后发现某个环节理解错误而崩溃。本文还有配套的精品资源点击获取
返回列表