news 2026/9/16 21:47:03

FiftyOne 关键点推理实战:从 YOLO Pose 到自定义姿态模型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FiftyOne 关键点推理实战:从 YOLO Pose 到自定义姿态模型

FiftyOne 关键点推理实战:从 YOLO Pose 到自定义姿态模型

【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyone

本文以 FiftyOne 官方用户指南 keypoints.rst 为骨架,系统讲解如何在 FiftyOne 中完成姿态(pose)与关键点(landmark)推理:包括将 Ultralytics YOLO pose 模型直接传入apply_model()进行开箱即用的关键点标注、使用to_keypoints()手动转换预测结果,以及为完全自定义的 Torch 模型装配KeypointDetectorOutputProcessor输出处理器。读完本文,你将掌握在 FiftyOne 数据集中生成、渲染、过滤关键点标签的完整方案。

核心概念:FiftyOne 的 Keypoints 标签类型

在 FiftyOne 中,姿态与关键点模型为每个样本标注的是一个Keypoints 字段,它通过将模型传入apply_model()生成。这一标签类型由两个核心类构成(源码位于 fiftyone/core/labels.py):

  • Keypoint:描述图像中的一组关键点,核心字段包括:
    • points(x, y)关键点坐标列表,取值归一化在[0, 1] × [0, 1]区间内;
    • confidence:每个关键点的置信度列表,取值[0, 1]
    • label:关键点组对应的类别标签;
    • index:关键点组的索引,可用于关联跟踪 ID。
  • Keypoints:单个样本中Keypoint实例的列表容器,字段名为keypoints

从源码可以看出(fiftyone/core/labels.py),Keypoint还内置了apply_confidence_threshold()方法,可将置信度低于阈值的点替换为NaN,配合视图级方法filter_keypoints()即可实现非破坏性的关键点过滤。

方式一:Ultralytics YOLO Pose 模型直接推理

FiftyOne 与 Ultralytics 的集成(见 ultralytics.rst)允许把 YOLO pose 模型直接传给apply_model(),无需任何包装代码。这是官方文档推荐的首选路径。

环境准备

首先安装依赖(集成自 OSS 0.22.0 / Enterprise 1.4.0 起可用):

pip install "ultralytics>=8.1.0" "torch>=1.8"

加载模型并推理

以 YOLOv8 pose 系列为例,模型权重命名规律为yolov8+ 规模后缀(n/s/m/l/x)+-pose.pt

import fiftyone as fo import fiftyone.zoo as foz from ultralytics import YOLO # 加载示例数据集 dataset = foz.load_zoo_dataset("quickstart", max_samples=25) dataset.select_fields().keep_fields() # YOLOv8 pose 模型:n/s/m/l/x 五种规模 model = YOLO("yolov8s-pose.pt") # model = YOLO("yolov8m-pose.pt") # model = YOLO("yolov8l-pose.pt") # model = YOLO("yolov8x-pose.pt") # 直接推理,无需包装 dataset.apply_model(model, label_field="keypoints") # 配置 COCO-pose 骨架,让 App 能渲染关键点连线 dataset.default_skeleton = fo.KeypointSkeleton( labels=[ "nose", "left eye", "right eye", "left ear", "right ear", "left shoulder", "right shoulder", "left elbow", "right elbow", "left wrist", "right wrist", "left hip", "right hip", "left knee", "right knee", "left ankle", "right ankle", ], edges=[ [11, 5, 3, 1, 0, 2, 4, 6, 12], [9, 7, 5, 6, 8, 10], [15, 13, 11, 12, 14, 16], ], ) session = fo.launch_app(dataset)

这段代码中值得注意的关键点:

  1. 零包装集成apply_model()内部通过 FiftyOne 的 Ultralytics 适配层自动将 YOLO 原始输出解析为Keypoints标签,调用链最终落到 fiftyone/utils/ultralytics.py 的to_keypoints()/_to_keypoints()实现。
  2. 骨架(skeleton)渲染dataset.default_skeleton是数据集级属性(定义于 fiftyone/core/odm/dataset.py),edges是整数索引列表,定义节点间连线;labels为每个节点的名称。上述配置对应标准 COCO-17 姿态骨架,App 会据此绘制姿态连线。

方式二:to_keypoints()手动转换

当需要精细控制推理循环(如逐样本处理、自定义后处理)时,可以使用to_keypoints()手动将 Ultralytics 预测结果转换为 FiftyOne 格式:

import fiftyone.utils.ultralytics as fou for sample in dataset.iter_samples(progress=True): result = model(sample.filepath)[0] sample["keypoints"] = fou.to_keypoints(result) sample.save()

从源码实现看(fiftyone/utils/ultralytics.py),_to_keypoints()的处理逻辑包含以下要点:

  • result.keypointsNone(模型未检测到实例),返回空的fol.Keypoints()
  • 坐标取自result.keypoints.xyn(已归一化的(x, y)坐标),并通过result.keypoints.conf提取逐点置信度;
  • 每个关键点实例的labelresult.names[cls]解析得到,index则来自跟踪 ID 提取;
  • 支持两个可选参数:confidence_thresh会将低于阈值的点置为NaNclasses可按类别名过滤关键点。

to_keypoints()也接受批量结果(传入Results列表即返回Keypoints列表),可配合fiftyone.core.utils.iter_batches实现批量推理:

from fiftyone.core.utils import iter_batches filepaths = dataset.values("filepath") batch_size = 16 predictions = [] for paths in iter_batches(filepaths, batch_size): results = model(paths) predictions.extend(fou.to_keypoints(results)) dataset.set_values("keypoints", predictions)

Ultralytics 关键点推理的实际渲染效果可参考下图:

方式三:自定义 Torch 模型 +KeypointDetectorOutputProcessor

对于完全自定义的模型,官方文档给出的方案是:用TorchImageModel包装模型,并配置对应的输出处理器,使其能直接配合apply_model()使用。完整流程参见 自定义模型推理指南。

FiftyOne 在 fiftyone/utils/torch.py 中提供了两类关键点输出处理器:

KeypointOutputProcessor(纯关键点模型)

面向输出为关键点张量的模型。其__call__()接收批预测output = List[Dict[Tensor]],要求 dict 中包含:

  • keypointsFloatTensor[N, K, ...]):每个实例的关键点,格式[x, y, ...]
  • keypoint_scoresTensor[N]):每个关键点的分数。

解析时会将坐标除以frame_size归一化到[0, 1],置信度经sigmoid后存入Keypoint.confidence,低于confidence_thresh的点置为(nan, nan)(fiftyone/utils/torch.py)。

KeypointDetectorOutputProcessor(检测 + 关键点联合模型)

面向同时输出检测框与关键点的模型(如自底向上的姿态检测器),其构造要求传入classes类别列表,否则会抛出ValueError。其输入 dict 需包含:

  • boxesFloatTensor[N, 4]):绝对坐标[x1, y1, x2, y2]的检测框;
  • labelsInt64Tensor[N]):类别索引;
  • scoresTensor[N]):每个检测的置信度;
  • keypointsFloatTensor[N, K, ...]):格式[x, y, v, ...],其中v为可见性标志;
  • keypoints_scores:逐点分数。

处理逻辑(fiftyone/utils/torch.py)会同时产出两组标签并返回{"detections": ..., "keypoints": ...}

  • 对每个检测框生成fol.Detection(框坐标归一化、类别经classes[lbl]解析、附检测置信度);
  • 对每个实例生成fol.Keypoint(坐标归一化;置信度低于阈值或可见性标志v == 0的点均置为(nan, nan))。

这一设计意味着一个模型可以同时为Detections字段和Keypoints字段产出标签,便于在 App 中同时查看检测框与姿态。

注册自定义模型

自定义模型通常通过 Model Zoo 的 manifest 或fo.load_model()注册,配置文件基于TorchImageModelConfig,在output_processor_cls中指定上述处理器类。注册后即可与内置模型一样调用:

dataset.apply_model(model, label_field="keypoints")

KeypointSkeleton 详解:让姿态"画"出来

关键点推理的落地离不开骨架可视化。KeypointSkeleton(fiftyone/core/odm/dataset.py)是嵌入在数据集元数据中的文档类,包含两个字段:

  • labels:可选,每个节点的名称字符串列表;
  • edges:必填,整数索引列表的列表,定义节点连通性。

官方源码示例展示了其语义:edges=[[0, 1, 2, 3], [4, 5, 6]]表示左手 ↔ 左肩 ↔ 右肩 ↔ 右手左眼 ↔ 右眼 ↔ 嘴两组连线。需要说明的是,骨架仅适用于points数量固定、且语义顺序一致的关键点字段——例如 COCO-17 姿态的 17 个固定语义点。

设置方式有两种:

# 数据集级默认骨架:App 自动渲染所有关键点字段 dataset.default_skeleton = fo.KeypointSkeleton(labels=[...], edges=[...]) # 或者构建独立骨架对象用于展示 skeleton = fo.KeypointSkeleton( labels=["left hand", "left shoulder", "right shoulder", "right hand", "left eye", "right eye", "mouth"], edges=[[0, 1, 2, 3], [4, 5, 6]], )

推理结果的查看与过滤

推理完成后,你可以用 FiftyOne 原生 API 进一步分析关键点结果:

# 低置信度关键点就地过滤 for sample in dataset.iter_samples(progress=True): kpts = sample["keypoints"] for kp in kpts.keypoints: kp.apply_confidence_threshold(0.5) sample.save() # 或使用视图级 API,非破坏性地创建过滤视图 view = dataset.filter_keypoints("keypoints", confidence_thresh=0.5)

关键点坐标是归一化的(x, y)值,若需换算回像素坐标,可利用Keypoint.to_shapely(frame_size=(w, h))(fiftyone/core/labels.py)得到绝对坐标的 ShapelyMultiPoint,便于几何运算或与检测框做空间关联分析。

小结

本文围绕 FiftyOne 的关键点推理链路,给出了三条由浅入深的路径:开箱即用的 Ultralytics YOLO pose 直接推理、灵活可控to_keypoints()手动转换,以及完全定制TorchImageModel+KeypointDetectorOutputProcessor自定义方案。配套的数据结构(Keypoint/Keypoints/KeypointSkeleton)与过滤工具(apply_confidence_threshold/filter_keypoints)共同构成了从推理、渲染到分析的完整闭环,可无缝迁移到姿态估计、动作识别、手势跟踪等各类关键点应用场景。

【免费下载链接】fiftyoneRefine high-quality datasets and visual AI models项目地址: https://gitcode.com/GitHub_Trending/fi/fiftyone

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 21:46:57

CW32L012外挂串行Flash下载方案详解:Bootloader与OTA升级实践

手上最近在调一个低功耗传感器节点的量产项目,主控用的是CW32L012,ARM Cortex-M0内核,主打低功耗和低成本。做到第二版固件的时候,功能越加越多,协议栈、参数配置、升级策略全塞进去,片内Flash开始吃紧&…

作者头像 李华
网站建设 2026/9/16 21:46:07

2027软考高项培训机构怎么选?六大避坑指南帮你锁定靠谱机构

2027软考高项培训机构怎么选?六大避坑指南帮你锁定靠谱机构——从讲师资质到退费承诺,一文讲透高项培训的选择逻辑一、高项培训市场现状:选择越多,陷阱越多软考高项(信息系统项目管理师)作为国家计算机技术…

作者头像 李华
网站建设 2026/9/16 21:46:03

Intel Mac 装单 Win10:Boot Camp、驱动与 T2 避坑

在二手市场淘一台 Intel 版 MacBook Pro,或者手里正好有一台用了五六年的 iMac,然后把整块硬盘抹掉、只装一个干净的 Win10 单系统——这件事在开发者圈子里一直有人干,原因也很实在:Mac 的屏幕、触控板、做工和续航底子好&#x…

作者头像 李华
网站建设 2026/9/16 21:45:37

Cursor 跑 ReAct 多步编码任务:Key 走 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/16 21:44:33

shadcn-svelte Table 组件详解:从基础响应式表格到 Data Table 实战

shadcn-svelte Table 组件详解:从基础响应式表格到 Data Table 实战 【免费下载链接】shadcn-svelte shadcn/ui, but for Svelte. ✨ 项目地址: https://gitcode.com/GitHub_Trending/sh/shadcn-svelte shadcn-svelte 是 shadcn/ui 在 Svelte 生态的官方移植…

作者头像 李华