(轉載請註明出處)
使用SDK: Kinect for Windows SDK v2.0 public preview
CSND部落格出現了已經發布了,修改了一個字就變成“待審核”狀態導致慢更了,
不過反正幾乎沒人看也就影響為0啦。
這次說的是Kinect的玩家索引(BodyIndex)。
Kinect用一個位元組表示當前深度座標的玩家編號。目前最大支援6人,已經是非常不錯了,這個“6”是一個宏定義
#define BODY_COUNT 6
支援6人索引及6人骨骼跟蹤,1代支援6人索引但是只支援2人骨骼跟蹤,可見USB3.0的功勞。
獲得的位元組流中,0x00表示0號玩家,0x01表示1號,直到0x05這6名玩家索引,沒有玩家則是用 0xFF表示。請注意,
玩家索引是隨機分配的,不是只有一位玩家就編號是0x00。不過經測試,貌似一位玩家用0x00表示的幾率要大些。
這次可視化演算法就簡單了,6名玩家使用3位元位即可表示,剛好RGB三種3顏色,所以就用下面代碼:
for (UINT i = 0; i < nBufferSize; ++i){ pBGRXBuffer[i].rgbBlue = pBuffer[i] & 0x01 ? 0x00 : 0xFF; pBGRXBuffer[i].rgbGreen = pBuffer[i] & 0x02 ? 0x00 : 0xFF; pBGRXBuffer[i].rgbRed = pBuffer[i] & 0x04 ? 0x00 : 0xFF; pBGRXBuffer[i].rgbReserved = 0xFF; }
這樣,0x00號就是白色,0xFF就是黑色,方便觀看。請注意,Kinect的核心演算法基於深度映像,
所以獲得的玩家索引的大小也是與深度映像大小一致,同上節,方法名差不多,“DepthFame”改為"BodyIndexFrame"就差不多了。
效果如下:
可以看到在近距離,深度映像解析度大於手指,沒準微軟在以後近景模式中會提供官方的十指跟蹤。
當然大家自己可以利用OpenCV基於深度映像實現手指位置的跟蹤。
看一下這個映像,如果與彩色映像像相結合,就可以把人物將彩色映像中“分離”出來,這個有點像電影電視
中的“色鍵”,在背景使用綠色或者藍色映像,後期處理把這些背景色移除。在這就成為綠屏技術吧。
演算法大致如下:
這個點索引為0xFF就把像素置為空白(0x00000000),否則置為在這個點彩色幀相應位置。
那麼怎麼擷取“這個點彩色幀相應位置”呢。Kinect SDK提供了一個座標映射對象。是的,居然是對象,
而不是一個函數搞定的事
還有就是只要是關於深度資料的座標映射,是要提供來源資料(即深度資料)的。
原來不是一個簡單的f(x)啊。
座標映射提供非常多的映射方法,像深度座標映射彩色座標,彩色座標映射深度座標,詳細的情查看官方文檔。
還有一點需要注意,就是可能會出現座標映射改變的情況,比如彩色幀大小從1080P變成720P。
不過現在還不能,於是ICoordinateMappingChangedEventArgs裡邊也是幾乎啥也沒有。也就是目前還不用管
所現在我們需要同時開啟彩色資料流,深度資料流已經玩家索引資料流。同步這個流不是一個簡單的事。
畢竟我們不知道什麼流先到,什麼流後到。於SDK提供一個“複源幀”對象,將多個資料流封到一起,用起來非常方便。
使用IKinectSensor::OpenMultiSourceFrameReader(DWORD, IMultiSourceFrameReader **)開啟複源幀,比如:
hr = m_pKinect->OpenMultiSourceFrameReader( FrameSourceTypes::FrameSourceTypes_Color | FrameSourceTypes::FrameSourceTypes_BodyIndex | FrameSourceTypes::FrameSourceTypes_Depth, &m_pMultiSourceFrameReader );
開啟彩色資料流+深度資料流+玩家索引流,使用方法和單源幀差不多,不過使用時要擷取你需要的單源幀引用,
比如IMultiSourceFrame::get_ColorFrameReference,IMultiSourceFrame::get_DepthFrameReference等等。詳細的可以看範例。
效果如下:
哎,一個人截圖簡直不方便,就這樣變學姐了。
還有就是提供的範例中,一個方案套件含了這兩個工程,需要調試某工程需要右鍵工程--設定啟動項
範例下載地址:點擊這裡