首页 文章

Microsoft Kinect V2 Unity 3D Depth = Warping

提问于
浏览
2

我一直在Unity3D的一个场景上工作,我在那里得到了512 x 424的KinectV2深度信息,我将它实时转换为也是512 x 424的Mesh . 因此,它的比例为1:1像素数据(深度)和顶点(网格) .

我的最终目标是使用“深度”在“Microsoft Kinect Studio v2.0”中找到“监视3D视图”场景 .

我已经在点 Cloud 方面做了很多工作 . 但是,我的Unity场景中存在大量的扭曲 . 我虽然可能是我的数学等等 .

但是我注意到它们的开发工具包中提供的Unity Demo kinect的情况相同 .

我只是想知道我是否遗漏了一些明显的东西?我的每个像素(或在这种情况下为顶点)都以1×1的方式映射出来 .

我不确定它是否因为我需要在将其渲染到场景之前处理来自DepthFrame的数据?或者,如果有一些额外的步骤,我错过了获得我的房间的真实代表?因为它看起来像现在添加了一些轻微的“球形”效果 .

enter image description here

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

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

我知道这很难搞清楚,特别是你不知道我坐的房间的布局:/侧视图 . 你能看到左边的翘曲吗?使用绿线作为参考 - 这些在实际房间中是直的,如右图所示 .

enter image description here

看看我的视频,以获得更好的主意:https://www.youtube.com/watch?v=Zh2pAVQpkBM&feature=youtu.be

Code C#

说实话很简单 . 我只是直接从Kinect SDK获取深度数据,并将其放置在Z轴上的点 Cloud 网格中 .

//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;
        }
    }
}

Kinect API可以在这里找到:https://msdn.microsoft.com/en-us/library/windowspreview.kinect.depthframe.aspx

非常感谢任何建议,谢谢!

1 回答

  • 2

    感谢Edward Zhang,我弄清楚我做错了什么 .

    我不能正确地投射我的深度点,我需要使用CoordinateMapper将我的DepthFrame映射到CameraSpace .

    目前,我的代码采用正交深度而不是使用透视深度相机 . 我只需要实现这个:

    https://msdn.microsoft.com/en-us/library/windowspreview.kinect.coordinatemapper.aspx

    //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;
            }
        }
    }
    

相关问题