c# - Hololens - Unity c#:将点集从相机计划投影到统一坐标系?
问题描述
我目前正在为 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 厘米后为第二次拍摄设置的点。圆圈区域是我在拍照时正在查看的对象。我希望这个物体在我四处走动时会留在同一个地方,但毕竟我可能错了......
如果有人对我可能遗漏的东西有一点想法
解决方案
除了 Herdnando 已经说过的,问题可能是 cameraViewTransformMatrix 只在相机和点之间转换。所以当相机移动时,参考坐标系随之移动,点云不对齐。您还必须应用您的 cameraToWorldTransformMatrix 将所有内容都放入您的根坐标系。
推荐阅读
- excel - 如果 COL A 的特定行中的值存在于 COL D 中,则返回 TRUE 或 FALSE
- python-xarray - 带有 GFS 数据的metpy.calc.dewpoint_from_relative_humidity:ValueError:操作数无法与形状一起广播(31,)(34,)
- php - PHP 数组迭代以展平所有可能的结果
- azure - Azure API 管理“重写 url” - 如何删除 URL 前缀
- python - Python Seleinum 查找特定类的 div,如果另一个 div 位于其中,则查找第三个 div 并复制其中的文本
- reactjs - 如何修复 React 项目中的 Spinner 行为以等待 img 渲染
- javascript - JAVASCRIPT - 电报 | 如何为这个动作添加冷却时间?
- karate - Runner.runFeature 找不到功能文件路径 - karate 0.9.9.RC3-junit5
- java - GDAL和GeoTools有什么区别?
- python - 如何在 PySimpleGUI 中响应窗口调整大小