(轉載請註明出處)
使用SDK: Kinect for Windows SDK v2.0 public preview
這次就說深度幀的擷取與紅外幀的擷取
Kinect的紅外雷射裝置能夠擷取空間的深度與紅外映像,因為有上次的例子,這次將非常簡單。
深度值,Kinect用一個16位不帶正負號的整數表示深度幀上一個“深素”(深度元素,由映像元素引申),單位是毫米。
目前有效距離是(500, 4500)即半米到四米半。那麼怎麼可視化它呢,網上有許多深度值可視化的演算法,
這裡,我們就想一個簡單的吧:
距離0: 距離0代表深度值無效,我們給它塗上紅色
距離[1, 500), 距離不可靠,我們按照距離,塗上深淺不一的綠色。
具體大致是1塗上RGB(0,129, 0),2塗上(0, 130, 0),一直塗到(0, 255, 0),然後回到起點(0, 128, 0)...反覆,
虛擬碼大致是:
RGB(0, (get_depth() mod 128)+128, 0)
當然,位元運算理論速度快些,所以可以改成
RGB(0, (get_depth() & 0x7F)+128, 0)
距離[4500, +∞),按照上面的演算法,塗上[128, 255]的藍色,即:
RGB(0, 0, (get_depth() mod 128)+128)
距離[500, 4500),按照上面的演算法,塗上[0, 255]的灰色,即:
RGB(get_depth() & 0xFF, get_depth() & 0xFF, get_depth() & 0xFF)
差不多就是這樣:
auto pRGBXBuffer = m_ImagaRenderer.GetBuffer(); // 處理演算法 // 0著紅色 (0, min)著128~255漸進綠色 大於max的著128~255藍色 之間的著0~255灰色 // 不同深度漸進過度 for (UINT i = 0; i < nBufferSize; ++i){ if (!pBuffer[i]){ pRGBXBuffer[i].rgbRed = 0xFF; pRGBXBuffer[i].rgbGreen = 0; pRGBXBuffer[i].rgbBlue = 0; pRGBXBuffer[i].rgbReserved = 0xFF; } else if (pBuffer[i] < depth_min_reliable_distance){ pRGBXBuffer[i].rgbRed = 0; pRGBXBuffer[i].rgbGreen = pBuffer[i] & 0x7F + 0x80; pRGBXBuffer[i].rgbBlue = 0; pRGBXBuffer[i].rgbReserved = 0xFF; } else if (pBuffer[i] > depth_max_reliable_distance){ pRGBXBuffer[i].rgbBlue = pBuffer[i] & 0x7F + 0x80; pRGBXBuffer[i].rgbGreen = 0; pRGBXBuffer[i].rgbRed = 0; pRGBXBuffer[i].rgbReserved = 0xFF; } else{ pRGBXBuffer[i].rgbBlue = pBuffer[i] & 0xFF; pRGBXBuffer[i].rgbGreen = pRGBXBuffer[i].rgbBlue; pRGBXBuffer[i].rgbRed = pRGBXBuffer[i].rgbBlue; pRGBXBuffer[i].rgbReserved = 0xFF; } }
至於 擷取深度的代碼怎麼寫。其實....您可以把上節中的所有帶有"ColorFrame"的替換成"DepthFrame"即可,
還有一些細微的差別(比如要擷取有效距離啊等等,都是依葫蘆畫瓢),微軟偷懶,咱也偷懶
大家可以結合範例看看
效果:
"少俠。我見你印堂發黑,看來有血光之災啊。"
"廢話,沒見到我身邊一片紅麼。"
從映像看出,居然沒有綠色,微軟偷懶麼。
居然沒有藍色。微。。。額,這是我寢室太小了
還有值得注意的是在物體周圍是紅色的,說明雷射的入射角太大,
幾乎沒有光線再反射回來,於是就是無效的
下載地址:點擊這裡
第二部分,紅外資料的擷取。
從Kinect獲得的紅外紅外資料也是一個16位不帶正負號的整數,這個整數直接代表了這個點的灰階值。
如果和一代一樣的話,這16位只有高10位是有效,10位灰階,只有進階顯示器才能顯示,
我們這一般的顯示只能顯示256級即8位灰階,所以我們應該捨棄其中2位。
請問是捨棄高2位還是低2位呢。請想想。
自然是高2位。。。不能捨棄啦,畢竟比起扔掉1萬塊相比,我還是願意扔掉1塊錢。
嗯,同上,微軟把介面設計的差不多,把上面項目的代碼中”DepthFrame“改成"InfraredFrame"估計差不多了,
詳細的請看附帶的範例,讓我們看看效果吧:
範例下載地址:點擊這裡
從上看出,因為距離比較遠(2米開外),導致本人幾乎看不到了。為了應付這種情況,微軟提供了一組
以ILongExposureInfrared開頭的對象,有興趣的朋友可以去看看,這裡就不多說了。