В настоящее время я работаю над приложением для 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 см вправо. Обведенные области - это объект, который я глядя на при съемке. Я надеялся, что объект останется на том же месте, когда я буду двигаться вокруг , но я могу все-таки ошибаться ...
Если у кого-то есть хотя бы малейшее представление о том, чего мне не хватает