【发布时间】: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