標籤:style blog http io 使用 ar strong for 資料
原文:http://www.cnblogs.com/yangecnu/p/3428647.html
Kinect for Windows SDK1.7中引入了Kinect Fusion功能。在1.8的SDK中對該功能進行了改進和強化,Kinect Fusion能夠使得我們使用Kinect for Windows 感應器來進行真實情境的三維幾何重建,目前已支援匯出.obj及.stl等三維資料格式。Kinect Fusion技術在支援GPU加速的機器上能夠對物體進行即時的三維建模。和傳統的三維建模方式相比,Kinect Fusion最大的優勢是快速便捷。
Kinect Fusion可以用於工業設計,3D列印,遊戲製作,醫學教育等領域。
是Kinect Fusion的工作流程。Kinect感應器擷取的深度影像資料在剛開始的時候有很多資料丟失,通過移動Kinect感應器對物體進行掃描,幾秒鐘過後就能夠建立足夠平滑的重建的靜態情境,產生點陣雲以及3D表面模型。
一
硬體要求
Kinect Fusion對電腦的硬體條件要求較高,Kinect Fusion能夠使用C++ AMP技術在DirectX11相容的GPU上處理資料,也可以在CPU上處理資料,可以在重建立方體構建的時候,通過設定重建的類型來確定。CPU處理模式適合離線處理,只有最新的相容DirectX 11的GPU才支援即時、互動性的重建。
基於GPU的重建的最低配置要求系統支援DirectX 11的顯卡,如果達不到要求,Kinect Fusion就運行不起來。目前NVIDIA GeForce GTX560,AMD Radeon 6950,同類型或者比該類型顯卡配置更高的硬體能夠實現即時互動三維重建。
官方推薦配置是,台式機CPU主頻3GH或以上,多核處理器,擁有2G記憶體的獨立顯卡。當然也可以使用配置有支援DirectX11 技術的顯卡的筆記本, 但是運行速度比同類型的台式機會慢的多。通常支援每秒處理30幀映像就可以實現非常流暢的追蹤和建模。
二
Kinect Fusion
的工作原理
Kinect Fusion通過對從多個角度擷取到的深度影像資料進行融合,來重建物體的單幀光滑表面模型。當感應器移動的時候,照相機的位置以及姿勢資訊被記錄下來,這些資訊包括位置和朝向。由於我們知道了每一幀映像的姿勢以及幀與幀之間的關聯,多幀從不同角度採集的資料能夠融合成單幀重建好的定點立方體。我們可以想象下在空間中的一個巨大的虛擬立方體,裡面是我們現實世界的情境,當我們移動感應器的時候,深度資料資訊被不斷加入。
是從Kinect Fusion的處理流程。
- 第一步是深度影像資料的轉換。SDK將Kinect中擷取的原始深度幀資料轉換為以米為單位的浮點數據,緊接著對該資料進行最佳化,通過擷取網路攝影機的座標資訊,將這些浮點數據轉換為和Kinect網路攝影機朝向一致的點雲資料。這些點的表面情況通過使用AlignPointClouds函數擷取。
- 第二步是計算全域的網路攝影機的姿勢資訊,包括網路攝影機的位置和朝向,通過使用互動型的配准演算法在網路攝影機移動時不斷擷取其姿勢,這樣系統始終知道當前網路攝影機相對於起始幀時網路攝影機的相對姿勢。Kinect Fusion中有兩種配准演算法。第一種叫NuiFusionAlignPointClouds,他用來將從重建對象計算得來的點雲與從Kinect深度影像資料中擷取的點雲進行配准。或者單獨的使用比如對同一情境的不同視場角的資料進行配准;第二種叫AlignDepthToReconstruction,該演算法在對重建立方體進行處理時能夠獲得更高精度的追蹤結果。但是對於情境內移動的物體該演算法可能不夠健壯。如果情境中的追蹤被中斷,那麼需要將網路攝影機的位置和上一次的網路攝影機位置對齊才能繼續進行追蹤。
- 第三步是將從已知姿勢網路攝影機產生的深度影像資料融合為代表網路攝影機視野範圍內的景物的立方體。這種對深度資料的融合是逐幀,連續進行的,同時通過平滑演算法進行了去噪,也處理了某些情境內的動態變化,比如情境內添加或者移除了小的物體等。隨著感應器的移動從不同的視場角度觀察物體表面。原始影像中沒有表現出來的任何隔斷或者空也會被填充,隨著網路攝影機更接近物體,通過使用新的更高精度的資料,物體表面會被持續最佳化
- 最後,從感應器視點位置對重建立方體進行光線投射,重建的點陣雲能夠產生渲染了的三維重建立方體。
Kinect Fusion對物體的追蹤僅僅使用Kinect 感應器產生的深度資料流。這種追蹤主要依賴深度影像資料中不同位置深度資料有足夠的深度差異。因此它能夠將看到的資料融合起來以及計算感應器的不同位置差異。如果將Kinect對準一個平整的牆面或者又很少起伏變化的物體,那麼追蹤可能不會成功。情境中物體分散時效果最好,所以在使用Kinect Fusion對情境進行追蹤時如果出現追蹤失敗的情況,不防試著對情境內的物體進行追蹤。
Kinect Fusion中的追蹤有兩種演算法,他們分別通過AlignDepthFloatToReconstruction和 AlignPointClouds 函數實現,他們都可以用於網路攝影機位置的追蹤,但是,如果我們使用AlignDepthFloatToReconstruction 函數來建立一個重建立方體,可能會有更好的追蹤精度。相比,AlignPointClouds 方法可以用於單獨的,不需要重建立方體就可以將兩個點雲進行對齊。
三
相關
API
前面講解了Kinect Fusion的工作原理,通過SDK中的相關API,我們可以使用Kinect Fusion來對真是情境進行三維重建,是Kinect Fusion相關的處理流程:
首先,需要進行初始化,在初始化階段,Kinect Fusion會確定建模過程中的全局座標系,並會構造一個帶掃描的真實情境的靜態虛擬立方體,在建模過程中,我們只關心在該虛擬立方體中的真實情境。
緊接著第一步是對每一幀深度影像資料進行如所示的處理。下面就簡單介紹下中涉及Kinect Fusion的相關函數。
DepthToDepthFloatFrame 函數
該函數的簽名如下:
public void DepthToDepthFloatFrame(DepthImagePixel[] depthImageData, FusionFloatImageFrame depthFloatFrame,float minDepthClip, float maxDepthClip, bool mirrorDepth)
該方法將無符號短型深度影像資料框架格式轉換為浮點型深度影像資料楨格式,它代表物體距離Kinect感應器的距離,處理好的資料存放區在預分配的depthFloatFrame中,參數中depthImageData 和 depthFloatFrame 的大小必須一致,該函數在GPU上運行。
depthImageData 是從Kinect感應器擷取的深度影像未經處理資料。minDepthClip 表示最小深度閾值,小於該值得都會設定為0,maxDepthClip 為最大深度閾值,大於該值得都被設定為1000,最後一個布爾型的mirrorDepth表示是否對深度資料進行鏡像處理。
最小最大深度閾值可以用來對輸入的資料進行處理,比如說可以排除某些特殊的物體,將這些物體排除在三維重建之外。
ProcessFrame 函數
接下來可以調用ProcessFrame函數,該函數在內部其實是先後調用了AlignDepthFloatToReconstruction 和 IntegrateFrame 這兩個函數,這裡先介紹ProcessFrame函數。
public bool ProcessFrame(FusionFloatImageFrame depthFloatFrame, int maxAlignIterationCount, int maxIntegrationWeight,Matrix4 worldToCameraTransform)
該函數用來對每一幀經過DepthToDepthFloatFrame處理後的深度影像資料進行進一步處理。如果在AlignDepthFloatToReconstruction階段追蹤產生錯誤,那麼接下來的IntegrateFrame階段就不會進行處理,相機的姿勢也保持不變。該函數支援的最大映像解析度為640*480。
maxAlignIterationCount參數為配准過程中的迭代次數,該參數用來表示對齊相機追蹤演算法的迭代次數,最小值為1,值越小的計算速度更快,但是設定過小會導致配准過程不收斂,從而得不到正確的轉換。
maxIntegrationWeight 參數用來控制深度影像融合的平滑參數,值過小會使得的映像具有更多的噪點,但是物體的移動顯示的更快,消失的也更快,因此比較適合動態情境建模。大的值使得物體融合的更慢,但是會保有更多的細節,噪點更少。
WorldToCameralTransoform,參數為最新的相機位置。
如果該方法返回true,則表示處理成功,如果返回false,則表示演算法在對深度影像資料對齊的時候遇到問題,不能夠計算出正確的變換。
我們一般的可以分別調用AlignDepthFloatToReconstruction 和 IntegrateFrame 這兩個函數,從而可以對更多的細節進行控制,但是,ProcessFrame速度可能更快,該方法處理成功之後,如果需要輸出重構映像,則只需要調用CalculatePointCloud方法,然後調用FusionDepthProcessor.ShadePointCloud即可。
AlignDepthFloatToReconstruction 函數
public bool AlignDepthFloatToReconstruction(FusionFloatImageFrame depthFloatFrame,int maxAlignIterationCount,FusionFloatImageFrame deltaFromReferenceFrame, out float alignmentEnergy, Matrix4 worldToCameraTransform)
該方法用來將深度影像資料楨匹配到重構立方體空間,並由此計算出當前深度資料幀的網路攝影機的空間相對位置。相機追蹤演算法需要重構立方體,如果追蹤成功,會更新相機的內部位置。該方法支援的最大解析度為 640*480。
maxAlignIterationCount 參數和ProcessFrame方法中的參數含義相同。
deltaFromReferenceFrame 表示配准誤差資料楨, 是一個預先分配的浮點影像幀,通常儲存每一個觀測到的像素與之前的參考影像幀的對齊程度。通常可以用來產生彩色渲染或者用來作為其他視覺處理演算法的參數,比如對象分割演算法的參數。這些殘差值被歸一化到-1 ~1 的範圍內,代表每一個像素的配准誤差程度。如果合法的深度值存在,但是沒有重構立方體,那麼該值就為0 表示完美的對齊到重構立方體上了。如果深度值不合法,就為返回1。如果不需要這個返回資訊,直接傳入null即可。
alignmentEnergy 表示配准精確程度 ,0表示完美匹配
worldToCameraTransform 表示此刻計算得到的相機位置,通常該變數通過調用FusionDepthProcessor.AlignPointClouds 或者 AlignDepthFloatToReconstruction這兩個方法獲得。
該函數如果返回true則表示對齊成功,返回false表示則表示演算法在對深度影像資料對齊的時候遇到問題,不能夠計算出正確的變換。
IntegrateFrame 函數
public void IntegrateFrame(FusionFloatImageFrame depthFloatFrame,int maxIntegrationWeight, Matrix4 worldToCameraTransform)
用於融合深度資料楨到重構情境中maxIntegrationWeight,控制融合的平滑程度 。
worldToCameraTransform 表示此時深度資料幀的相機位置,他可以由配准API計算返回。
CalculatePointCloud 函數
public void CalculatePointCloud(FusionPointCloudImageFrame pointCloudFrame,Matrix4 worldToCameraTransform)
通過光線跟蹤演算法計算出某視點下的點雲資料。
這些點雲資訊可以被用作 FusionDepthProcessor.AlignPointClouds或者FusionDepthProcessor.ShadePointCloud函數的參數。從而來產生可視化的映像輸出。
pointCloudFrame參數是一個固定的映像大小,比如說,你可以表單大小範圍內的點雲資料,然後放置一個image控制項,通過調用FusionDepthProcessor.ShadePointCloud來填充這個image控制項,但是需要注意的是,映像越大,計算所耗費的資源就越多。
pointCloudFrame 參數是一個預先分配的點雲資料楨,他會被通過對重建立方體進行光線投射得到的點雲資料進行填充,通常通過調用FusionDepthProcessor.AlignPointClouds 或者FusionDepthProcessor.ShadePointCloud.函數產生。
worldToCameraTransform參數表示相機視點的位置,用來表示光線投射的位置。
CalculateMesh 函數
public Mesh CalculateMesh(int voxelStep)
用於返回重構情境的幾何網路模型。該函數從重建立方體輸出一個多邊形立體表面模型。voxelStep 描述了採樣步長,採樣步長設定的越小,返回的模型就越精緻。
四 結語
理解了這幾個函數,那麼就應該差不多能夠使用Kinect Fusion提供的功能了,最好的學習方式就是直接查看Kinect Developer Toolkit中提供的樣本程式的代碼,相信理解了上面的函數,看起來應該不會太吃力。
由於本人筆記本配置達不到要求,所以沒有辦法示範,不過相信通過上面的介紹,對您瞭解和使用Kinect Fusion應該會有所協助
Kinect for Windows SDK開發入門(十九):Kinect Fusion