Ultralytics Hand Keypoints 手部关键点数据集:21 点手部姿态估计的 YOLO 训练实战
本文围绕 Ultralytics 官方提供的 Hand Keypoints 数据集展开:该数据集包含 26,768 张手部图像,每张图的手部均以 21 个关键点标注(由 Google MediaPipe 自动生成,保证标注精度与一致性),并可直接对接 YOLO26-pose 系列模型完成训练、验证与部署。读完本文,你将掌握该数据集的目录结构与 YAML 配置含义、21 个手部关键点的命名体系、flip_idx 翻转映射在数据增强中的底层作用,以及用 Python / CLI 两种姿势训练手部姿态估计模型的完整流程。
数据集总览
Ultralytics Hand Keypoints 数据集的核心规格如下:
| 项目 | 说明 |
|---|---|
| 图像总数 | 26,768 张(18,776 张 train / 7,992 张 val) |
| 类别数 | 1 类(hand) |
| 关键点 | 每只手 21 个,每个点为 (x, y, visibility) 三元组 |
| 标注来源 | Google MediaPipe Hand Landmarker,确保高准确度与一致性 |
| 下载体积 | 约 369 MB |
| 适用任务 | Pose 姿态估计(手势识别、无触摸交互等) |
该数据集的图像来自公开的手部与手势数据集(11k Hands、2000 Hand Gestures、Gesture Recognition 等,按各自平台许可收集使用),整体以 Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License(CC-BY-NC-SA-4.0)分发。若需要超出通用手部 landmark 的自定义手势词表,官方建议通过 Ultralytics Platform 在浏览器中完成自有数据集的标注与训练。
数据集配套的文档页面位于 hand-keypoints.md,同目录下的 coco8-pose.md、dog-pose.md、tiger-pose.md 等是其他姿态数据集的对照参考。
21 个手部关键点的定义
Hand Keypoints 数据集沿用 MediaPipe 手部 landmark 布局,每只手标注 21 个点,可归纳为:
- 手腕(wrist)1 个点;
- 拇指(thumb)4 个点;
- 食指(index)4 个点;
- 中指(middle)4 个点;
- 无名指(ring)4 个点;
- 小指(pinky)4 个点。
数据集配置文件 hand-keypoints.yaml 中通过 kpt_names 字段给出了每个索引的解剖学名称,这是理解标注数据时最重要的对照表:
| 索引 | 名称 | 含义 |
|---|---|---|
| 0 | wrist | 手腕 |
| 1-4 | thumb_cmc / thumb_mcp / thumb_ip / thumb_tip | 拇指:掌骨指节、近节指节、指节、指尖 |
| 5-8 | index_mcp / index_pip / index_dip / index_tip | 食指各关节 |
| 9-12 | middle_mcp / middle_pip / middle_dip / middle_tip | 中指各关节 |
| 13-16 | ring_mcp / ring_pip / ring_dip / ring_tip | 无名指各关节 |
| 17-20 | pinky_mcp / pinky_pip / pinky_dip / pinky_tip | 小指各关节 |
YAML 中该字段的实际写法(见 hand-keypoints.yaml 第 24-47 行)是按类组织的一级字典:
# Classes
names:
0: hand
# Keypoint names per class
kpt_names:
0:
- wrist
- thumb_cmc
- thumb_mcp
- thumb_ip
- thumb_tip
- index_mcp
# ...(middle、ring、pinky 共 21 项)
- pinky_tip
从源码结构看,kpt_names 并非可有可无的注释:姿态训练器在 train.py 中会显式读取该字段并挂到模型对象上:
kpt_names = self.data.get("kpt_names")
if not kpt_names:
...
kpt_names = {i: names for i in range(self.model.nc)}
self.model.kpt_names = kpt_names
随后 exporter.py 在导出模型时把 kpt_names 写入导出产物的 metadata,因此推理端(如端侧推理框架)可以按名称而非裸索引渲染骨架点,这对“手腕”“指尖”这类语义化关键点尤其重要。
数据集目录结构与完整 YAML
数据集下载后的目录约定为:根目录下包含 images/train 与 images/val 两个子目录(分别对应 18,776 张训练图与 7,992 张验证图)。完整配置文件如下(原文照录自 ultralytics/cfg/datasets/hand-keypoints.yaml):
# Hand Keypoints dataset by Ultralytics
# parent
# ├── ultralytics
# └── datasets
# └── hand-keypoints ← downloads here (369 MB)
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: hand-keypoints # dataset root dir
train: images/train # train images (relative to 'path') 18776 images
val: images/val # val images (relative to 'path') 7992 images
# Keypoints
kpt_shape: [21, 3] # number of keypoints, number of dims (2 for x,y or 3 for x,y,visible)
flip_idx: [0, 1, 2, 4, 3, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 15, 16, 17, 18, 19, 20]
# Classes
names:
0: hand
# Keypoint names per class
kpt_names:
0:
- wrist
- thumb_cmc
- thumb_mcp
- thumb_ip
- thumb_tip
- index_mcp
- index_pip
- index_dip
- index_tip
- middle_mcp
- middle_pip
- middle_dip
- middle_tip
- ring_mcp
- ring_pip
- ring_dip
- ring_tip
- pinky_mcp
- pinky_pip
- pinky_dip
- pinky_tip
# Download script/URL (optional)
download: ...hand-keypoints.zip # 指向 ultralytics/assets 仓库的 release 资源,约 369 MB
各字段逐项解释:
path:数据集根目录。写hand-keypoints时,Ultralytics 会按内置路径列表寻找或自动下载到datasets/hand-keypoints。train/val:相对于path的图像目录;也支持指向*.txt文件列表或多目录列表的写法。kpt_shape: [21, 3]:21 个关键点,每个点 3 维(x, y, visible;若只存x, y则为 2 维)。这个值必须与标注文件一致,否则训练加载会失败。flip_idx:水平翻转时关键点的重排映射。手部左右翻转后,左右手的关节位置互换:食指(5-8)与拇指(1-4)对调位置,中指(9-12)与无名指(13-16)对调位置。对照上面的索引表可以逐项验证flip_idx的映射逻辑。names:类别名,仅hand一类。kpt_names:关键点语义名称,用于模型属性与导出 metadata。download:自动下载地址。首次使用yolo train data=hand-keypoints.yaml时,框架会据此自动下载约 369 MB 的压缩数据集并解压,无需手动搬运。
源码视角:flip_idx 如何驱动姿态数据增强
flip_idx 是本数据集与 COCO-pose 等数据集共有的关键字段,它的正确性直接决定水平/垂直翻转增强是否可用。构建 YOLOv8 系列数据增强管线时(augment.py):
flip_idx = dataset.data.get("flip_idx", []) # for keypoints augmentation
if self.data.get("kpt_shape", [0, 0])[0] == 0:
hyp.fliplr = 0.0
if isinstance(hyp.mosaic, float):
hyp.mosaic = hyp.mosaic > 0.0 # True and MOSAIC > 0.0
if flip_idx:
if len(flip_idx) != kpt_shape[0]:
raise ValueError(...)
if hyp.fliplr > 0.0 or hyp.flipud > 0.0:
if not flip_idx:
# both fliplr and flipud require flip_idx
hyp.fliplr = hyp.flipud = 0.0
LOGGER.warning("No 'flip_idx' array defined in data.yaml, disabling 'fliplr' and 'flipud' augmentations.")
(上述为 augment.py 中相关逻辑的概括)要点有三:
- 若数据是 pose 任务但未提供
flip_idx,框架会自动禁用fliplr与flipud增强并打警告,而不是用错误映射去翻转关键点; - 若提供但长度不等于
kpt_shape[0](本数据集为 21),会直接抛出ValueError; - 翻转真正生效时,RandomFlip 用
flip_idx对关键点做列重排:
if params["flip_idx"] is not None and instances.keypoints is not None:
instances.keypoints = np.ascontiguousarray(instances.keypoints[:, params["flip_idx"], :])
也就是说,图像被水平镜像的同时,第 1-4 号点(拇指)与第 5-8 号点(食指)的坐标位置按 flip_idx 对调,保证“镜像后的手”仍然满足解剖学语义。此外在 Albumentations 增强路径中(augment.py)也有同样的关键点重排处理。
训练 YOLO26-pose 模型
文档给出的标准训练方式(100 个 epoch、640 输入尺寸),Python 与 CLI 两种等价写法:
from ultralytics import YOLO
# Load a model
model = YOLO("yolo26n-pose.pt") # load a pretrained model (recommended for training)
# Train the model
results = model.train(data="hand-keypoints.yaml", epochs=100, imgsz=640)
# Start training from a pretrained *.pt model
yolo pose train data=hand-keypoints.yaml model=yolo26n-pose.pt epochs=100 imgsz=640
完整的训练参数列表见 Training 模式文档,姿态任务的整体说明(含验证、预测、导出)见 Pose 任务文档,标注格式细节见 YOLO Pose 数据集格式指南。
需要注意的关键点:
- 模型结构上的关键点数量是解耦的。预训练的
yolo26n-pose.pt是在 COCO 人体 17 关键点(kpt_shape: [17, 3],见 yolo26-pose.yaml)上训练的,而本数据集是 21 关键点。加载后直接train时,框架会依据数据 YAML 重建 pose head 以适配新的kpt_shape,backbone 权重得以迁移。若想从零开始,也可用model=yolo26n-pose.yaml构建新结构(YOLO26 的 n/s/m/l/x 各档参数与 GFLOPs 见 yolo26-pose.yaml 中的 scales 注释)。 - YOLO26 的 pose 头是
Pose26:模型 YAML 最后一行为[[16, 19, 22], 1, Pose26, [nc, kpt_shape]],即 P3/P4/P5 三个尺度上各预测一份关键点。Pose26在 head.py 中实现,它在经典Pose头(nk = kpt_shape[0] * kpt_shape[1]个回归值,kpts_decode中用 sigmoid 输出可见性、用 stride 放缩坐标)基础上引入了 RealNVP 归一化流用于关键点分布建模。这意味着无论 17 点还是 21 点,head 都是按kpt_shape动态实例化的,手部 21 点任务不需要改任何网络代码。 - 常用训练参数:
data指定数据集 YAML(本数据集可只写hand-keypoints.yaml,框架会内置解析);epochs=100;imgsz=640即输入图像边长(训练时会被保持宽高比地 letterbox 到 640)。其余如batch、device、patience、fliplr等详见 default.yaml 与训练文档。
Mosaic 增强与手部数据集
原文档特别展示了该数据集训练过程中的 Mosaic 批次示例:多张手部图像被拼接成单张训练图。Mosaic 是 Ultralytics 训练中默认开启的增强(对应 hyp.mosaic 概率),它把最多 4 张图拼接为一张,使同一 batch 内出现更多样的手部尺寸、朝向与遮挡关系,从而提升模型对不同尺度与上下文的泛化能力。配合前文所述的 flip_idx 翻转,Hand Keypoints 这种 18,776 张的训练集在增强下等效规模进一步放大。
典型应用场景
Hand Keypoints 数据集支撑的手部关键点能力可落地于:
- 手势识别:人机交互与无触摸控制界面;
- AR/VR 交互:对虚拟物体的精确操控;
- 机器人操作:机械手的细粒度运动控制;
- 医疗:手部运动分析辅助诊断;
- 动画:手部动作捕捉;
- 生物特征认证:基于手部几何结构的安全系统。
验证、常见问题与引用
训练完成后,model 对象会保留训练时的 data 等属性,可直接调用验证,例如对最佳权重执行 model.val()(详见 Pose 任务文档 的 Val 小节)。原文档 FAQ 覆盖的问题与答案可归纳为:
- 如何训练:加载
yolo26n-pose.pt并调用model.train(data="hand-keypoints.yaml", epochs=100, imgsz=640); - 数据集价值:26,768 张标注图 + MediaPipe 生成的 21 点标注,为手部姿态估计提供了规模与精度保障;
- 结构:train 18,776 张 / val 7,992 张,保证训练与验证流程完整;
- YAML 使用:把
hand-keypoints.yaml作为data参数传入训练脚本或 CLI 即可,框架自动完成下载与解析。
引用与致谢
若在你的研究或开发中使用了 Hand Keypoints 数据集,请按 hand-keypoints.md 的 Citations and Acknowledgments 一节致谢:图像来源包括 11k Hands、2000 Hand Gestures、Gesture Recognition 三个公开数据集(按各自许可使用),数据集整体以 CC-BY-NC-SA-4.0 分发,并应注明数据集创建者 Rion Dsilva 的贡献。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00