ARCore 坐标系相关梳理

ARCore 坐标系相关梳理

ARCore 坐标系指的是ARCore根据图像帧返回的位姿的定义系统,根据[官网](Pose | ARCore | Google Developers)介绍:随着 ARCore 对环境的理解发生变化,它会调整其世界模型以保持事物的一致性。发生这种情况时,摄像机和锚点的数字位置(坐标)会发生显着变化,以保持它们所代表的物理位置的适当相对位置。这些变化意味着每一帧都应该被认为是在一个完全独特的世界坐标空间中。锚点和相机的数字坐标不应在检索它们的渲染帧之外使用。如果需要考虑超出单个渲染帧范围的位置,则应创建锚点或使用相对于附近现有锚点的位置。那ARCore的坐标系从何而来呢?如何保证其绝对性呢?

另外ARCore本身返回的位姿是基于其坐标系的,但是AR应用的往往有不同的渲染引擎,如OpenGL SE、Unity、WebGL等,不同的渲染引擎使用的坐标系不一定一样,如OpenGL SE是右手坐标系、Unity则是左手。AR应用的核心有两个点,一个是把相机的视频流以背景方式渲染3D场景中,一个是虚拟相机的位姿和ARCore返回的位姿绑定,也就是ARCore的位姿要转换到不同的渲染引擎坐标空间中,它们又是如何转换的呢?

绝对的地理坐标系

20181228144548697.png

在一定范围下,只考虑物体的经度、纬度,我们可以把各个物体视为近似在同一水平面上。我们以当前手机的位置为原点O,过O作地球球面的切面M,过O做经过O点经线的切线O->N,这个切线指向正北方向,过O做切面M的垂线O->M,该垂线指向地心。

首先我们以O为坐标系的原点,定义右手坐标系。以O->N的相反方向N->O作为X轴,X轴指向南,以O->M的相反方向M->O作为Z轴,Z轴反向指向地心,那么根据右手坐标系的定义,Y轴就指向东。

这还不是我们最终的世界坐标系,因为我们的手机的方向并不总是指向正北也就是我们上面定义的坐标系中的O->N方向,他有自己的方位角Azimuth angle(可以通过传感器获取),即手机与正北方向的夹角。所以,我们需要对XY轴的方向根据手机的状态进行调整,根据方位角,以Z轴为旋转轴进行旋转,使得旋转后的X轴指向与手机朝向相反。

20181228121233292.png

ARCore 世界坐标系

image-20211108164639923.png

在地理坐标系下,可以根据地磁场构建一个相对于地球的绝对的坐标系统,因此对于ARCore来说以此为基础也可以构建自己的一个绝对世界坐标系ARCore的世界坐标系是以Y轴做了重力对齐,相当于地理坐标系的Z轴,反方向永远垂直指向地心。X轴正方向由西指向东,Z轴正方向由北指向南。地理坐标和ARCore 世界坐标系的转换可以根据IMU传感器数据来转换,具体转换过程还未深入,有待研究。

ARCore 产生的基础位姿应该是基于世界坐标系的,这里说基础位姿是因为ARCore 应用接口里类似getDisplayOrientedPosegetAndroidSensorPose

的方法获取摄像头空间坐标系的位姿和安卓传感器坐标系下的位姿,这些位姿应该是基于基础位姿转换而来的,下面有具体代码参考。

渲染引擎一般坐标系

ARCore本身不做渲染,所以需要借助渲染引擎渲染AR应用。我们的手机屏幕是二维的,但是我们展示的是三维AR世界,当我们在构建一个AR场景时,是以一个三维世界既是世界坐标来构建,而转化为屏幕坐标展示在我们眼前,则需要经历多道矩阵变化,这就是渲染引擎做的事情。

1781480222-5981cf8339460_fix732.png
  • 世界坐标系:

    在渲染引擎中,世界坐标系是以屏幕中心为原点(0, 0, 0),且是始终不变的。长度单位这样来定:窗口范围按此单位恰好是(-1,-1,-1)到(1,1,1)。面对屏幕,右手坐标系,你的右边是X正轴,上面是Y正轴,屏幕指向你的为Z正轴,左手坐标系X轴相反。

    lhrrhr.png
  • 屏幕坐标系:

    渲染引擎的重要功能之一就是将三维的世界坐标经过变换、投影等计算,最终算出它在显示设备上对应的位置,这个位置就称为设备坐标。在屏幕、打印机等设备上的坐标是二维坐标。

  • 视点坐标系:

    是以视点(照相机)为原点,以视线的方向渲染引擎会将世界坐标先变换到视点坐标,然后进行裁剪,只有在视线范围(视见体)之内的场景才会进入下一阶段的计算。

OpenGL SE 坐标系

OpenGL SE坐标系是右手坐标系,根据上面的介绍可知,其坐标系原点在手机屏幕中间,当面对屏幕的时候,右手边为X正轴,指向自己方向为Z轴正轴,上面是Y轴正轴,其坐标系与安卓传感器坐标系重合。因此ARCore提供了获取安卓传感器坐标系下的位姿方法。

d937c9e9-05fd-46e3-b72d-eb353b79bfbd.png

ARCore 提供了getAndroidSensorPose方法来获取传感器坐标系下的位姿,其参考代码如下:

      Frame frame = mArFragment.getArSceneView().getArFrame();
        Camera camera = frame.getCamera();
        Pose T_gc = frame.getAndroidSensorPose();

Unity 坐标系

Unity 是左手坐标系,ARCore位姿需要转换到Unity坐标系下。在Unity的ARCore SDK是通过getDisplayOrientedPose获得位姿,获得位姿后通过转换函数转换为Unity 位姿,示例代码如下:

    public static void ApiPoseToUnityPose(ApiPoseData apiPose, out Pose unityPose)
    {
        Matrix4x4 glWorld_T_glLocal =
            Matrix4x4.TRS(
            new Vector3(apiPose.X, apiPose.Y, apiPose.Z),
            new Quaternion(apiPose.Qx, apiPose.Qy, apiPose.Qz, apiPose.Qw), Vector3.one);
        Matrix4x4 unityWorld_T_unityLocal =
            _unityWorldToGLWorld * glWorld_T_glLocal * _unityWorldToGLWorldInverse;

        Vector3 position = unityWorld_T_unityLocal.GetColumn(3);
        Quaternion rotation = Quaternion.LookRotation(unityWorld_T_unityLocal.GetColumn(2),
                                                      unityWorld_T_unityLocal.GetColumn(1));

        unityPose = new Pose(position, rotation);
    }

查看ARCore文档可以发现,获取位姿还有一个方法GetPose,和getDisplayOrientedPose的区别如下:

getPose:

Returns the pose of the physical camera in world space for the latest frame. This is an OpenGL camera pose with +X pointing right, +Y pointing right up, and -Z pointing in the direction the camera is looking, with "right" and "up" being relative to the image readout in the usual left-to-right, top-to-bottom order. Specifically, this is the camera pose at the center of exposure of the center row of the image.

返回世界空间中物理相机的姿势,以获得最新帧。这是一个 OpenGL 相机姿势,右指 X,+Y 指向右上,-Z 指向相机的方向,"右"和"向上"相对于通常从左到右、从上到下顺序的图像读出。具体来说,这是相机在图像中心行中央曝光的姿势。

getDisplayOrientedPose:

Returns the virtual camera pose in world space for rendering AR content onto the latest frame. This is an OpenGL camera pose with +X pointing right, +Y pointing up, and -Z pointing in the direction the camera is looking, with "right" and "up" being relative to current logical display orientation.

返回虚拟相机在世界空间中的姿势,将 AR 内容渲染到最新帧中。这是一个 OpenGL 相机姿势,右指 X,+Y 指向和 -Z 指向相机的方向,"右"和"向上"相对于当前的逻辑显示方向。

大概的意思是getPose是以物理相机为参考的,物理相机旋转后其坐标系会旋转,getDisplayOrientedPose是根据渲染画面为参考的,设备旋转的时候如果解锁画面跟随旋转的话,渲染画面也会旋转,所以坐标系是不变的。大概示意图如下:

rt.png

参考文档

ARcore坐标系与地理坐标系转换

ThreeJS中的点击与交互——Raycaster的用法 - SegmentFault 思否

PyojinKim/ARCore-Data-Logger: Android app to save ARCore results (Visual-Inertial Odometry) to a series of text files for offline use. (github.com)

fixing-device-coordinate-system-regardless-of-device-orientation

An Intro to 3D Coordinate Frames for Augmented Reality

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354