Hololens - Unity c#: проекция точки, установленной из плана камеры, в систему координат единицы? - PullRequest
0 голосов
/ 13 марта 2020

В настоящее время я работаю над приложением для 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;
    }
}

С моим реальным кодом я получаю наборы связных точек для каждого захвата отдельно от других, но вот проблема: При съемке нескольких снимков наборы точек выглядят в разных планах (см. Скриншот ниже):

points set in meshlab

На этом изображении красная часть это точка, установленная для первого захвата, и зеленая для второго захвата после перемещения на 50 см вправо. Обведенные области - это объект, который я глядя на при съемке. Я надеялся, что объект останется на том же месте, когда я буду двигаться вокруг , но я могу все-таки ошибаться ...

Если у кого-то есть хотя бы малейшее представление о том, чего мне не хватает

Ответы [ 2 ]

0 голосов
/ 04 мая 2020

Помимо того, что Герднандо уже сказал, проблема может заключаться в том, что cameraViewTransformMatrix преобразует только между камерой и точкой. Поэтому, когда камера перемещается, система координат перемещается вместе с ней, а облака точек не выравниваются. Вы также должны применить свой cameraToWorldTransformMatrix, чтобы получить все в вашу root систему координат.

0 голосов
/ 13 апреля 2020

Попробуйте добавить привязку мира в начало координатной системы единицы и отобразить положение относительно привязки кадра.

...