【问题标题】:Hololens - Unity c# : projecting a point set from camera's plan to unity coordinate system?Hololens - Unity c#:将点集从相机计划投影到统一坐标系?
【发布时间】:2020-03-13 14:21:50
【问题描述】:

我目前正在为 Hololens 开发一个应用程序,该应用程序允许用户从不同的角度拍摄场景的多个帧(例如一个盒子)并将它们转换为代表对象的点集。获取每帧的深度位图效果很好,但是当我想将点集转换为 Unity 坐标系时,我的问题就来了……

每次用户拍摄时,我都会得到深度位图、框架坐标系、投影变换矩阵、摄像机视图变换矩阵以及从摄像机坐标系到统一坐标系的变换矩阵。

// Get the spatial coordinates system from the mediaFrameReferecence
var coordinateSystem = mediaFrameReference.CoordinateSystem;

// Get the projection Transform matrix
object n;
mediaFrameReference.Properties.TryGetValue(projectionTransformGuid, out n);

// ByteArrayMatrix(byte[]) is a method a developped which works fine
projectionTransformMatrix = ByteArrayToMatrix(n as byte[]);

/// HERE n is a byte[48] but I'm expecting byte[64] like m below

// Get the view transform then invert it
byte[] m = mediaFrameReference.Properties[viewTransformGuid] as byte[];
cameraViewTransformMatrix = ConvertByteArrayToMatrix4x4(m);

// Get the camera to world transfrom
cameraToWorldTransformMatrix = (System.Numerics.Matrix4x4)coordinateSystem.TryGetTransformTo(rootSpatialCoordinateSystem);

// ... Doing Some stuff ...

在获得这些之后,对于每个像素,我将我的点保存到一个 .obj 文件中,格式为:v x y z r g b 在下面的 SavePoint 方法中:

private static Vector2 PixelToWorldCoordonate(int u, int v)
{
    float x = a * (u - width / 2) + b * (v - height / 2);
    float y = c * (u - width / 2) + d * (v - height / 2);
    return new Vector2(x, y);
}

/// This method is to project a pixel to unity coordinate system
private String SavePoint((int x, int y, byte* inputRowBytes,
                          float depthScale, float minReliableDepth, float maxReliableDepth,
                          System.Numerics.Matrix4x4 cameraViewTransformMatrix, 
                          System.Numerics.Matrix4x4 cameraToWorldTransformMatrix, 
                          double r, double g, double b) 
{
    if (depth < 2)
    {
        string mes = "";
        Vector2 realPoint = PixelToWorldCoordonate(x, y);
        System.Numerics.Vector3 point3d = new System.Numerics.Vector3(realPoint.x, realPoint.y, 1.0f);
        point3d *= depth;
        System.Numerics.Vector3 position = System.Numerics.Vector3.Transform(point3d, cameraViewTransformMatrix);

        // Saving the point's position and color
        return "v " + position.X.ToString() + " " + position.Y.ToString() + " " + position.Z.ToString()
            + " " + r.ToString() + " " + g.ToString() + " " + b.ToString() + Environment.NewLine;
    }
}

使用我的实际代码,我得到了每个捕获的连贯点集,但这是问题所在: 当进行多次捕获时,点集似乎在不同的计划中(见下面的截图):

在这张图片中,红色部分是为第一次拍摄设置的点,绿色部分是在右侧移动 50 厘米后为第二次拍摄设置的点。圆圈区域是我在拍照时正在查看的对象。 我希望物体在我四处走动时保持在同一个位置,但毕竟我可能错了......

如果有人对我可能错过的东西有一点点想法

【问题讨论】:

  • 我们认为点云的反角表明视图可能是向后的,并且正在计算指向相机的点而不是相机指向的点。那么你能调试你的项目并验证这个想法吗?希望在那之后能看到更多的发现和细节。谢谢。
  • 感谢您的回答赫尔南多。我尝试了你的想法,但结果并不是很好。两个点云更接近,但总是有一点我无法解释的偏移量。也许我从错误的角度考虑问题。

标签: c# unity3d point-clouds hololens


【解决方案1】:

尝试在统一坐标系的原点添加一个世界锚点,并映射相对于框架参考的位置。

【讨论】:

    【解决方案2】:

    除了 Herdnando 已经说过的,问题可能是 cameraViewTransformMatrix 只在相机和点之间转换。所以当相机移动时,参考坐标系随之移动,点云不对齐。您还必须应用您的 cameraToWorldTransformMatrix 以将所有内容都放入您的根坐标系。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-12
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多