对于手部渲染问题排查和解决
发现连续手手势csv在回放时 3d 手部显示很奇怪,问题首先定位两个方向:
- 采集App 的采集问题
- 前端渲染问题
- 后端解析问题
其实可能性1的概率并不大,因为关节角度每一列本身在整段记录中的变化范围都是合理的,所以问题大概率发生在 CSV→解析→特征/姿态→Three.js 渲染这条链。

让claude有侧重点的去查之后,claude 返回是 前端rig 渲染问题,我们让claude 去修复,中途还因为缺乏权限问题,我无法到本地demo前端界面进行验证,让它给管理员重置密码,然后我上去校验。
然而并没有改好,依旧不理想。claude仅仅是使用了自己造的数据进行了smoke 测试和截图,我上传我采集到的真实数据时,原形毕露。
我原样反馈了我发现的情况,让claude 使用我提供的数据进行测试验证(我给出了emg2pose的数据,我采集的数据,neruopose 的wrist 数据)。给出新的根因报告,明确“用户实测失败”的原因。再给修复方案,不接受仅靠 clamp/AA 缩放/灯光材质把视觉压正常。
然后claude这次去查的很彻底,但是结果也很打击:
没有权威 emg2pose FK 约定时,当前三份只有角度的数据要么无法修到可用,要么必须允许受约束推导。
说白了,就是这三种数据差异过大,不同的关节角度语义没对齐,它无论如何去挑都没办法。
我想到了映射层,我先让 Claude 暂停继续调 UI,先读源码推翻/重建数据契约。尤其是三类数据来源不同,强行用一套 joint_angles 映射解释所有文件,很可能永远调不稳。我先拉一个空目录,将规则、数据文件拷贝进去,让claude 重新制定方案。
1.建立独立小项目,不读取主项目文档作为事实,只以样本文件和提取脚本结果为准。
2. 支持 CSV 和 HDF5 样本,先用脚本提取为统一 JSON,再由前端读取。
3. 前端用 Three.js 做可交互 viewer:选择样本、播放、拖动时间轴、切换 rig/convention preset。
4. 必须覆盖三个验收样本:
- EMG_1781418395207.csv
- 2022-11-18-1668758400-843cb-cv-emg-pose-demonstration@2-recording-6_right.hdf5
- wrist_user_006_dataset_001.hdf5
5. 对比多种 FE/AA 映射、骨架几何和 wrist-only 路径,记录每个方案的效果。
6. 不追求炫技,不引入重依赖;目标是验证姿态约定和可移植实现。Claude 很快就做出了demo,20min左右,我检查发现效果还是很差:

看来,单单从数据内容层面是无法还原各个数据的实际意义,应该去推导这些数据背后的意义。
例如我的采集数据的数据源是Mediapipe ,使用的21个landmark然后推算出的关节角度。而emg2pose 和 neruopose 是使用的自定义的关节角度映射。
我在提出反馈之后,claude又回去读了采集端app 的代码:
claude 推荐 改采集app输出,改为使用 mediapipe 默认输出格式landmark,很适合前端界面显示。(的确)。但是我也指出了csv的输出数据不单纯是考虑可视化,而是要作为训练数据和其他hdf5数据达到一个统一的效果。允许改,但是要从设计角度考虑:对比另外两种hdf5数据(尤其是emg2pose 送入模型的数据类型(好像是关节角弧度)),单纯改landmark会失去作为训练数据的价值,如果emg2pose的数据存储的关节信息是是关节角弧度,那么要求最终采集送入模型的数据csv数据那也是同样的信息价值。
所以我们开始设计。
数据层面推理
我将不同数据源相关文件拷贝进了这个demo实验目录,做数据层面的分析,得出结果:
现在有三种数据:
- emg2pose 的 HDF5
- 它的标签是
joint_angles[20] - 这些角度不是普通几何角,而是 UmeTrack 手模型里的关节参数
- 适合训练,也能通过官方 FK 推出手部关键点
- 它的标签是
- generic-neuromotor-interface 的 HDF5
- 它主要是
wrist_angles - 是腕部任务,不是完整手指任务
- 它主要是
- 我们采集 App 的 CSV
- 现在写的是 MediaPipe 算出来的几何角
- 虽然列名也像
INDEX_MCP_FE,但含义和 emg2pose 的joint_angles不是一回事 - 所以不能直接和 emg2pose HDF5 混在一起训练
我提议:不要把目标定成“CSV 修修补补”。目标应该改成:采集 App 输出一种新的统一数据格式,最好 HDF5,里面同时保存原始证据和训练标签。但是更进一步,**我们将这一层数据转换,放到我们的数据管理平台来做更适合,将mediapipe的原始结果直接写入采集文件!**考虑放弃计算旧几何角,而是直接写mediapipe坐标数据。还能提高采集性能!
我们在浏览器上模拟跑了一遍集成,效果不错!
这是针对emg2pose的训练数据的效果:

针对自己采集的数据、Mediapipe算出的21个关节点:

针对emg2pose 和 mediapipe 的数据的区别是,mediapipe在大鱼际多一个坐标点,所以为了兼容,我们在传emg2pose的关节坐标的时候,不计算但是保留。
对比图:
这是emg2pose的顶视图:

这是mediapipe的顶视图(大拇指多一个端点):

我们优化采集设备,
然后我们用新采集的landmark 做可视化测试:

目前原始 landmark 数据已经可用,真实手的骨架和 mesh 可视化也已经达标;但从这些 landmark 反解出来的 IK joint_angles 作为训练标签时,质量一般,所以不能无脑当“全帧高质量标签”用,必须带 ik_residual_mm 和 joint_angles_valid,训练时按质量过滤。
我发现当前真机 landmark 约 16fps,需检查是否由相机配置、MediaPipe 推理、线程阻塞、写盘/zip、UI 渲染导致。如果能低风险提高到 30fps,可以考虑下一轮迭代修复。帧率从 15fps 提到 30fps 的好处是:
- 动作更连续,训练时序更密;
- 快速动作时更少丢帧;
- 可做更稳定的时间对齐;
- 若低 fps 是因为推理卡顿/运动模糊导致,确实可能降低一部分 IK 残差。
但它不一定能显著降低 单帧 IK residual。因为这次 13mm median 的主要来源大概率是:
- MediaPipe
worldLandmarks的深度估计噪声; - 单目相机对手掌深度/拇指位置不稳定;
- UmeTrack 手模型和 MediaPipe 21 点定义并非完全同源;
- 拇指本来就是 IK 最弱点。
所以提高 fps 是值得做的工程优化,但不是“解决 IK 标签质量”的唯一钥匙。
总结而言:对比旧的“安卓端计算关节角度”相比:总体是明显提升。
旧方式它算出来的角度看起来每帧都有,但语义不对。它是 MediaPipe 几何夹角,FE/AA/拇指定义都和 emg2pose 的 UmeTrack 轴角不是一回事。尤其拇指和 MCP_AA 偏差很大,混进训练会污染标签。
新方式至少保留了原始真源:landmarks 落盘后,以后 IK 算法改进可以重新转换,不需要重采。