Convert 3D world (arcore anchor/pose) to its corresponding 2D screen coordinates

浪尽此生 提交于 2019-12-20 09:45:58

问题


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


回答1:


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;

}

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);



回答2:


arSceneView.getScene().getCamera().worldToScreenPoint(); worked for me as described here.



来源:https://stackoverflow.com/questions/49026297/convert-3d-world-arcore-anchor-pose-to-its-corresponding-2d-screen-coordinates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!