Unity3d 微软Kinect V2+;Unity 3D深度=扭曲

Unity3d 微软Kinect V2+;Unity 3D深度=扭曲,unity3d,kinect,kinect-sdk,Unity3d,Kinect,Kinect Sdk,我一直在Unity3D的一个场景中工作,在那里我有512 x 424的KinectV2深度信息,我正在将其实时转换为512 x 424的网格。因此,像素数据(深度)和顶点(网格)的比例为1:1 我的最终目标是使“Microsoft Kinect Studio v2.0”中的“Monitor 3D View”场景具有足够的深度 就点云而言,我已经基本上实现了。然而,在我的统一场景中有大量的扭曲。我想这可能是因为我的数学等等 然而,我注意到他们的开发工具包中提供的Unity Demo kinect也

我一直在Unity3D的一个场景中工作,在那里我有512 x 424的KinectV2深度信息,我正在将其实时转换为512 x 424的网格。因此,像素数据(深度)和顶点(网格)的比例为1:1

我的最终目标是使“Microsoft Kinect Studio v2.0”中的“Monitor 3D View”场景具有足够的深度

就点云而言,我已经基本上实现了。然而,在我的统一场景中有大量的扭曲。我想这可能是因为我的数学等等

然而,我注意到他们的开发工具包中提供的Unity Demo kinect也是如此

我只是想知道我是否遗漏了一些明显的东西?我的每个像素(或本例中的顶点)都以1×1的方式映射

我不确定这是否是因为我需要在渲染到场景之前处理DepthFrame中的数据?或者如果我错过了一些额外的步骤来获得我房间的真实再现?因为现在看起来有一个轻微的“球形”效果

这两张照片是我房间的自上而下的照片。绿线代表我的墙

左侧图像是Unity场景中的Kinect,右侧图像位于Microsoft Kinect Studio中。忽略色差,您可以看到左侧(统一)是扭曲的,而右侧是线性和完美的

我知道这很难理解,尤其是你不知道我坐的房间的布局。你能看到左边的翘曲吗?使用绿线作为参考-这些是实际房间中的直线,如右图所示

查看我的视频,了解更多信息:

代码C#

老实说,这很简单。我只是直接从Kinect SDK获取深度数据,并将其放置到Z轴上的点云网格中

//called on application start
void Start(){

    _Reader = _Sensor.DepthFrameSource.OpenReader();
    _Data = new ushort[_lengthInPixels];
    _Sensor.Open();
}

//called once per frame
void Update(){

    if(_Reader != null){

        var dep_frame = _Reader.AcquireLatestFrame();
        dep_frame.CopyFrameDataToArray(_Data);
        dep_frame.Dispose();
        dep_frame = null;

        UpdateScene();
    }
}

//update point cloud in scene
void UpdateScene(){

    for(int y = 0; y < height; y++){

        for(int x = 0; x < width; x++){

            int index = (y * width) + x;
            float depthAdjust = 0.1;
            Vector3 new_pos = new Vector3(points[index].x, points[index].y, _Data[index] * depthAdjust;
            points[index] = new_pos;
        }
    }
}
//在应用程序启动时调用
void Start(){
_Reader=_Sensor.DepthFrameSource.OpenReader();
_数据=新的ushort[_lengthInPixels];
_传感器。打开();
}
//每帧调用一次
无效更新(){
如果(_Reader!=null){
var dep_frame=_Reader.AcquireLatestFrame();
dep_frame.CopyFrameDataToArray(_数据);
dep_frame.Dispose();
dep_frame=null;
UpdateScene();
}
}
//在场景中更新点云
void UpdateScene(){
对于(int y=0;y
Kinect API可在此处找到:


非常感谢您的建议,谢谢!

谢谢爱德华·张,我知道我做错了什么

这取决于我没有正确地投影深度点,在这里我需要使用坐标映射器将深度帧映射到CameraSpace

目前,我的代码假定为正交深度,而不是使用透视深度摄影机。我只需要实现这一点:

//每帧调用一次
无效更新(){
如果(_Reader!=null){
var dep_frame=_Reader.AcquireLatestFrame();
dep_frame.CopyFrameDataToArray(_数据);
dep_frame.Dispose();
dep_frame=null;
CameraSpacePoint[]\u CameraSpace=新的CameraSpacePoint[\u Data.Length];
_Mapper.MapDepthFrameToCameraSpace(_Data,_CameraSpace);
UpdateScene();
}
}
//在场景中更新点云
void UpdateScene(){
对于(int y=0;y
查看您看到的症状以及围绕它的代码可能会很有帮助。您确实需要将帧数据处理成一个数组,并将其正确应用于正在显示的位图/图像。@Sean谢谢,我已经在我的OP中添加了一张照片。
//called once per frame
void Update(){

    if(_Reader != null){

        var dep_frame = _Reader.AcquireLatestFrame();
        dep_frame.CopyFrameDataToArray(_Data);
        dep_frame.Dispose();
        dep_frame = null;

        CameraSpacePoint[] _CameraSpace = new CameraSpacePoint[_Data.Length];
        _Mapper.MapDepthFrameToCameraSpace(_Data, _CameraSpace);

        UpdateScene();
    }
}

//update point cloud in scene
void UpdateScene(){

    for(int y = 0; y < height; y++){

        for(int x = 0; x < width; x++){

            int index = (y * width) + x;

            Vector3 new_pos = new Vector3(_CameraSpace[index].X, _CameraSpace[index].Y, _CameraSpace[index].Z;
            points[index] = new_pos;
        }
    }
}