2016-05-12 147 views
2

我一直在Unity3D的場景中工作,在那裏我有512 x 424的KinectV2深度信息,我正在將它實時轉換爲也是512的網格x 424.因此,像素數據(深度)和頂點(網格)的比例爲1:1。微軟Kinect V2 + Unity 3D深度=翹曲

我的最終目標是在'Microsoft Kinect Studio v2.0'中找到深度爲'Monitor 3D View'的場景。

我已經在點雲方面做了很多工作。但是,我的Unity場景中有大量的翹曲。我雖然可能是我的數學等

但是,我注意到它的發展套件中提供的Unity Demo kinect的情況相同。

我只是想知道如果我在這裏失去了明顯的東西?我的每個像素(或本例中的頂點)都以1乘1的方式映射出來。

我不確定是否因爲我需要在將DepthFrame渲染到場景之前處理數據?或者如果還有一些額外的步驟,我錯過了我的房間的真實代表?因爲它看起來像現在添加了一個輕微的「球形」效果。

enter image description here

這兩個圖像是我的房間的頂部向下射擊。綠線代表我的牆壁。

左圖爲Unity場景中的Kinect,右圖爲Microsoft Kinect Studio。忽略色差,你可以看到左邊(Unity)被扭曲,而右邊是線性和完美的。

我知道這很難做出來,尤其是你不知道我坐在房間的佈局:/側視圖。你能看到左邊的翹曲嗎?使用綠線作爲參考 - 這些在實際房間內是筆直的,如右圖所示。

enter image description here

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

代碼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; 
     } 
    } 
} 

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

希望任何指教,謝謝!

+0

這將是有益的,看看有什麼症狀,你的眼看,也許它周圍集中的代碼。 您確實需要將幀數據處理成數組,並將其正確應用於所顯示的位圖/圖像。 – Sean

+0

@謝恩謝謝,我給OP添加了一張照片。 –

回答

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