将 3D 世界(arcore 锚点/姿势)转换为其对应的 2D 屏幕坐标 [英] Convert 3D world (arcore anchor/pose) to its corresponding 2D screen coordinates

查看:29
本文介绍了将 3D 世界(arcore 锚点/姿势)转换为其对应的 2D 屏幕坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力实现这种转变.给定arcore中的anchor Pose,如何获取其在屏幕中对应的2D坐标?

I'm struggling to get this transformation. Given an anchor Pose in arcore how can I obtain its corresponding 2D coordinates in the screen?

推荐答案

最后,经过几天的调查并从不同的资源中获取信息后,我能够使这个工作正常进行.以下是将世界坐标(arcore 中的姿势)转换为 2D 屏幕坐标的代码片段(基于 arcore 示例 java 应用程序):

Finally, after some days of investigation and getting the information from different resources I was able to get this working. Following is a code snippet (based on the arcore sample java app) to convert from World coordinates (Pose in arcore) to 2D screen coordinates:

首先我们需要计算从世界-->屏幕变换的矩阵:

First we need to calculate the matrix to transform from world --> screen:

  public float[] calculateWorld2CameraMatrix(float[] modelmtx, float[] viewmtx, float[] prjmtx) {

    float scaleFactor = 1.0f;
    float[] scaleMatrix = new float[16];
    float[] modelXscale = new float[16];
    float[] viewXmodelXscale = new float[16];
    float[] world2screenMatrix = new float[16];

    Matrix.setIdentityM(scaleMatrix, 0);
    scaleMatrix[0] = scaleFactor;
    scaleMatrix[5] = scaleFactor;
    scaleMatrix[10] = scaleFactor;

    Matrix.multiplyMM(modelXscale, 0, modelmtx, 0, scaleMatrix, 0);
    Matrix.multiplyMM(viewXmodelXscale, 0, viewmtx, 0, modelXscale, 0);
    Matrix.multiplyMM(world2screenMatrix, 0, prjmtx, 0, viewXmodelXscale, 0);

    return world2screenMatrix;

}

一旦有了这个矩阵,我们就可以将点从 3D 世界投影到 2D,但是在此投影期间,我们必须将 NDC 坐标转换为屏幕.以下是执行此转换的方法:

Once we have this matrix, then we can project points from 3D world to 2D, but during this projection we have to convert from NDC coordinates to screen. Following is the method that performs this conversion:

  double[] world2Screen(int screenWidth, int screenHeight, float[] world2cameraMatrix)
  {
    float[] origin = {0f, 0f, 0f, 1f};
    float[] ndcCoord = new float[4];
    Matrix.multiplyMV(ndcCoord, 0,  world2cameraMatrix, 0,  origin, 0);

    ndcCoord[0] = ndcCoord[0]/ndcCoord[3];
    ndcCoord[1] = ndcCoord[1]/ndcCoord[3];

    double[] pos_2d = new double[]{0,0};
    pos_2d[0] = screenWidth  * ((ndcCoord[0] + 1.0)/2.0);
    pos_2d[1] = screenHeight * (( 1.0 - ndcCoord[1])/2.0);

    return pos_2d;
  }

最后一个简单的用法示例:

Finally, a simple example of usage:

        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int height = displayMetrics.heightPixels;
        int width = displayMetrics.widthPixels;

        // Get projection matrix.
        float[] projmtx = new float[16];
        camera.getProjectionMatrix(projmtx, 0, 0.1f, 100.0f);

        // Get camera matrix and draw.
        float[] viewmtx = new float[16];
        camera.getViewMatrix(viewmtx, 0);

        float[] anchorMatrix = new float[16];
        anchor.getPose().toMatrix(anchorMatrix, 0);
        float[] world2screenMatrix =    
        virtualObject.calculateWorld2CameraMatrix(anchorMatrix, viewmtx, projmtx);
        double[] anchor_2d =  world2Screen(width, height, world2screenMatrix);

这篇关于将 3D 世界(arcore 锚点/姿势)转换为其对应的 2D 屏幕坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆