Skip to main content

概述

本篇实践介绍如何将 MediaPipe 格式的人手关键点转换为灵巧手关节命令。应用场景包括接入摄像头或手套追踪数据、准备遥操作目标和离线验证重定向结果。 对应的 Python 示例为 0.retarget_session.py,C 示例为 0_retarget_session.c。C 接口与 Python 一一对应。 接口清单、输入格式与平台限制见重定向,本页说明集成流程和运行时行为。

前置条件

硬件

无。本示例用合成关键点,不扫描也不连接设备。

软件

前序步骤

无。本示例是重定向链路的最小起点,跑通它再接真实设备。

数据流

单帧走完下面的链路。会话对象跨帧保留状态,创建一次后在循环里复用。 关键点可来自摄像头、Wuji Glove、录制回放或 VR 追踪。输入按 MediaPipe landmark 顺序排列,Python 形状为 (21, 3),C 使用长度为 63 的一维数组,按行主序排列 xyz。 会话按 HandModel 选择内置调参配置,跨帧保留 warm-start 与平滑状态。输出形状为 (20,),按固件关节顺序排列,每根手指包含 4 个关节角。 关键点的单位是米,关节命令的单位是弧度。输出固定是 float32,形状固定,不随在线关节数变化。输入传 float64 也接受,内部会转换。

集成步骤

按创建会话、逐帧求解、结束追踪的顺序接入。 下文 make_open_hand_keypoints 是Python 示例 中的合成关键点函数,接入应用时替换为自己的关键点来源。C 片段需包含 wuji_sdk.h、stdio.h 和 stdlib.h。

1. 创建会话

选择目标手型和手性。同一段追踪复用一个会话,以保留跨帧状态。

2. 逐帧求解

每帧传入 21 个 MediaPipe 关键点,坐标单位为米。Python 使用 (21, 3) 的 float32 数组,C 使用长度为 63 的 x、y、z 数组。返回 20 个关节角,单位为弧度,按固件关节顺序排列。
将后续帧继续传给 step。此页面只计算关节角,连接设备和发送控制命令由应用另行处理。

3. 重置并释放

追踪中断后调用 reset,再开始下一段追踪。C 程序结束时释放会话。

运行与输出

两侧输出同样的结构:先是关节命令的形状与数据类型,然后按手指分组打印 20 个关节角。
C 侧不打印形状行,直接从关节命令开始:
以上为实际运行结果,环境是 Wuji SDK v2026.8.31、Python 3.12、C SDK x86_64-linux-gnu、Linux x86_64,输入是示例内置的合成张开右手姿态。 同一组输入下,两个接口的 20 个关节角逐位相同,两侧共用同一套求解实现。换关键点或换手型,数值随之变化,形状与分组方式不变。

注意事项

会话是有状态的。同一段连续追踪里复用一个会话,跨段之间 reset,不要每帧新建。

扩展用法

换关键点来源

把示例里的 make_open_hand_keypoints() 换成真实来源。只要产出 (21, 3) 的米制关键点、landmark 顺序与 MediaPipe 一致,下游无需修改。Wuji Glove 的 hand_skeleton() 数据流就是这个格式,接法见重定向。

换手型与手性

目标是 Wuji Hand 时把 HandModel.WujiHand2 改为 HandModel.WujiHand。左手装配把 Handedness.Right 改为 Handedness.Left,同时确认关键点也来自左手。

接入实时回路

本示例只求解一帧。实时场景要在循环里按固定周期调用 step(),并处理取不到新帧的情况。完整回路见重定向。

输入有效性

求解前确认关键点不是退化值。全零数组、含 NaN 或 Inf 的数组都会让 step() 抛 invalid keypoints 异常,追踪丢失时用上一帧有效数据顶替,比直接送零值更安全。

追踪断续的处理

手离开视野、设备断连、回放切段,这几种情况恢复后都调用一次 reset()。不 reset 的表现是恢复后前几帧姿态从旧状态平滑过来,看起来像滞后。

相关内容