Files
opendance-web/tasks/006-keypoint-preprocess.md
T

2.6 KiB
Raw Blame History

T-WEB-006 BVH/FBX → 关键点序列预处理

  • 状态:done
  • 依赖:T-WEB-004

目标

把上传的 3D 动作数据转换为与 Android 端输出同构的 MediaPipe 33 点关键点序列, 使 Windows 端 DTW 引擎只有一条输入通路。

load

DSH.md
contracts/model-formats.md       # 锚点:§2 动作格式、§2.1 预处理产物、§2.2 关节名映射
contracts/skeleton-topology.md   # 锚点:§1 33 点、§3 父节点表、§5 关节角
web-server/src/preprocess/*

端点

方法 路径 说明
POST /api/motions/:id/preprocess 执行预处理,返回更新后的 Motion
GET /api/motions/:id/keypoints 下载 NDJSON 关键点序列

实现分层

文件 职责
bvh-parser.ts 纯 TS BVH 词法/语法解析 + 逐帧前向运动学(FK)
math3d.ts 向量/矩阵工具、旋转合成、关节角余弦
joint-map.ts BVH 关节名 → MediaPipe 点索引的默认映射表
retarget.ts 单帧解算 35 项(33 点 + neck/pelvis 虚拟关节)→ 骨盆归零 → 自适应缩放 → 投影
keypoint-codec.ts 239 字节二进制帧编解码、NDJSON 序列化/解析、关键点 JSON 校验
assimp.ts 可选外部 Assimp 调用(FBX/glTF → BVH)
preprocess.service.ts 编排、落盘、状态与错误记录

拓扑与缩放(契约冻结)

  • 33 点顺序与父节点表来自 contracts/skeleton-topology.md,虚拟关节 neck=33、pelvis=34 只参与关节角计算,不进入输出序列。
  • 投影:x_img = 0.5 + x·s,y_img = 0.5 − y·s,z_img = −z·s, s = 0.35 / max(|x|,|y|,|z|)(按整段动作自适应,保证不出画)。
  • 置信度分层:直接映射 1.0、按层级推算 0.5、无法推算 0.0。

格式支持

格式 处理
.bvh 内置解析器,无外部依赖
.json 直通校验与规范化(须符合 mediapipe33@0.1.0)
.fbx .gltf .glb 调用可选 Assimp 转 BVH;未安装 Assimp 时写入可读错误并置 preprocessState=failed

验收

npm run test          # 25 例:解析 / FK / 重定向 / 编解码 / 拓扑 / 契约版本
npm run test:smoke    # 冒烟 [3] 段落

覆盖:60 帧样例经预处理后 60 帧 × 33 点 × 9 关节角、坐标落在 MediaPipe 归一化范围、置信度分层、时间戳按帧率推进、序列随时间变化、 NDJSON 往返、解码器拒绝错误长度与 magic。

样例数据由 test/fixtures/generate-sample-bvh.mjs 生成(60 帧挥手 + 深蹲, 21 关节 / 63 通道),可复现。