You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARCore:如何获取Pose相对于另一Pose的位置与姿态

问题根源

你代码里的Pose变换顺序完全搞反了,而且直接用相机坐标系下的Pose做基准是错误的——相机Pose每帧都在变,以此为基准必然会导致头部旋转时出现位置偏移。ARCore的Pose.compose()是右乘逻辑,你的写法相当于把变换方向搞反了,根本得不到正确的相对姿态。

正确实现方式

方式一:基于世界坐标系的Pose转换

先把面部相对于相机的Pose转成世界坐标系下的Pose,再以初始状态的世界Pose为基准计算相对变换:

// 全局变量
Pose neutralWorldPose = null;
Session arSession; // 你的ARCore Session实例

// 每帧处理面部Pose时的代码
Pose faceCameraPose = face.getCenterPose();
// 将相机坐标系下的面部Pose转换为世界坐标系Pose
Pose faceWorldPose = arSession.getCamera().getDisplayOrientedPose().compose(faceCameraPose);

// 首次检测到面部时,记录此时的世界Pose作为原点基准
if (neutralWorldPose == null) {
    neutralWorldPose = faceWorldPose;
}

// 计算当前面部相对于原点基准的Pose
Pose relativePose = neutralWorldPose.inverse().compose(faceWorldPose);
  • 核心逻辑:
    • getDisplayOrientedPose()拿到相机在世界坐标系中的姿态
    • 通过相机世界姿态叠加面部相对相机的姿态,得到面部的世界姿态
    • 用基准姿态的逆姿态左乘当前世界姿态,就能得到当前姿态相对于基准的正确变换(ARCore中A.inverse().compose(B)就是求B相对于A的Pose)

方式二:用Anchor固定原点(更稳定)

如果需要长时间跟踪,建议用Anchor绑定初始面部的世界位置,ARCore会自动维护这个锚点的稳定性,抵消相机漂移的影响:

// 全局变量
Anchor neutralAnchor = null;
Session arSession;

// 每帧处理代码
Pose faceCameraPose = face.getCenterPose();
Pose faceWorldPose = arSession.getCamera().getDisplayOrientedPose().compose(faceCameraPose);

// 首次检测时创建锚点
if (neutralAnchor == null) {
    neutralAnchor = arSession.createAnchor(faceWorldPose);
}

// 获取锚点的当前世界姿态,计算相对变换
Pose anchorWorldPose = neutralAnchor.getPose();
Pose relativePose = anchorWorldPose.inverse().compose(faceWorldPose);
重要提醒
  • 绝对不要用相机坐标系下的Pose作为基准,相机的移动会让基准不断偏移,必然出现位置跳变。
  • ARCore Pose的变换顺序不能乱:A.compose(B)是先执行B的变换,再执行A的变换;求相对姿态必须用基准.inverse().compose(目标)的格式。

内容的提问来源于stack exchange,提问作者John Goering

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:10:49