2012年7月26日 星期四

KinectSDK初探

使用作業系統 Windows 7
下載Kinect for Windows SDK 1.5 (update 2012.5.21)

Kinect Developer Toolkit

Audio
NearMode
Color
  RGB
  YUV
Depth
  Near Range
  有重影現象
Skeleton
  Default
  Seated
  Chooser:
     Default
     Closest1Player
     Closest2Player
     Sticky1Player
     Sticky2Player
     MostActive1Player
     MostActive2Player
Face Tracking
Tilt Angle (-27/+27)
Console

首先先試最簡單的Color Stream
開啟了 ColorBasics-WPF 專案
它Reference了 Microsoft.Kinect
最重要的是
private KinectSensor sensor;
一個KinectSensor物件

UI介面也很簡單 就是一個Image接收Color Stream傳來的資料, 和一個可以儲存目前畫面的button
sensor的ColorFrameReady event有一個Handler, 隨時更新Color的資料給Image
結果如下:

其實就是像一個WebCam的功能一樣


  • DepthBasics-WPF
這個專案和剛才的ColorBasics很像, 只是有一些不一樣,
this.sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
一開始會Enable DepthStream, 並指定格式
同樣的也為DepthFrameReady event加了一個Handler
this.sensor.DepthFrameReady += this.SensorDepthFrameReady;

結果如下:
 

DepthStream有兩種Range, 所以在介面上按下Near Mode選項, 這麼做

  if (this.checkBoxNearMode.IsChecked.GetValueOrDefault())
  {
    this.sensor.DepthStream.Range = DepthRange.Near;
  }
  else
  {
    this.sensor.DepthStream.Range = DepthRange.Default;
  }
從文件裏得知:

Default range from [800mm - 4000mm] inclusive.


Near range from [400mm - 3000mm] inclusive.

打開Near Mode的結果:

初步觀察:


  1. depth進來的數值為-1~4095 相當於 2的14次方如果我們把它除以16分佈到藍色和綠色的話, 可以得到這樣的影像:





  1. 場景中黑色物體 (如頭髮, 隔間牆的下擺) 因為會吸光 所以容易造成誤判
  2. 因為距離應該是用反射方式獲得, 所以每個東西會有類似影子的死角, 也就是如果有物件前後重疊時, 後面那個東西的偵測範圍會被前面的東西多擋到一些, 如圖中人的旁邊多了一片黑色的區域, 這個區域的大小會依據前後物件的距離成正比. 也就是如果兩個物件貼近時, 黑色區域會縮小甚至消失, 如果距離很大(例如人和牆的距離), 黑色區域也會變大.

  • D3D範例
在D3D中開啟Stream的方法和WPF中不太一樣
WPF:
newSensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);

D3D:
 hr = m_pNuiSensor->NuiImageStreamOpen 

D3D正在用一套奇怪的Nui(Natural User Interface)程式庫, 感覺跟Kinect又有一點不直覺

static const int _MaxPlayerIndices = 8;
在ProcessDepth中
int player = depth & NUI_IMAGE_PLAYER_INDEX_MASK;
Kinect引擎自動將取到的玩家分開給深度值, 然後再用Shader去畫出不同顏色的玩家
static const float4 playerColorCoefficients[8] = 
{
    float4(1.0,  1.0,  1.0,  1.0), 
    float4(1.4,  0.8,  0.8,  1.0),
    float4(0.8,  1.4,  0.8,  1.0),
    float4(0.8,  0.8,  1.4,  1.0),
    float4(0.6,  1.2,  1.2,  1.0),
    float4(1.2,  0.6,  1.2,  1.0),
    float4(1.2,  1.2,  0.6,  1.0),
    float4(1.3,  0.9,  0.8,  1.0)
};
(注意這裏的Color Format有點奇怪, 是BGRA, 也就是藍色為先, 所以以玩家1來說是偏紫色)

這裏學到了兩個東西
m_hNextDepthFrameEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
它讓我們在 RenderFrame的時候 去等
    if ( WAIT_OBJECT_0 == WaitForSingleObject(m_hNextDepthFrameEvent, 0) )
    {
        ProcessDepth();
    }
另一個東西是ID3DBlob* pBlob
它是DX10之後用來compile和create pixel shader和 vertex shader

低階的D3D程式細節很多, 有很長一段時間沒有接觸, 在此先針對Kinect的部份了解
  • 臉部辨視:
先看一下執行結果:

程式一開始並沒有自動出現人臉辨視, 推斷原因為距離Camera太近導致. 將身體往後靠之後即出現辨視後的人臉, 就算移回原先的距離也能持續偵測得到, 可以斷定深度偵測只用在一開始的追綜.
人臉辨視呈現的打光偏暗, 面向會隨著擺動, 嘴巴如果張開, 臉部模型也會跟著變化
程式解析:
本專案連結了另外兩個Reference, 一個是位於
D:\KinectSDK\Microsoft.Kinect.Toolkit\
產生 D:\KinectSDK\Microsoft.Kinect.Toolkit\obj\Debug\Microsoft.Kinect.Toolkit.dll
另一個是
D:\KinectSDK\Microsoft.Kinect.Toolkit.FaceTracking\
產生D:\KinectSDK\Microsoft.Kinect.Toolkit.FaceTracking\obj\Win32\Debug\Microsoft.Kinect.Toolkit.FaceTracking.dll

這個WPF用了練家子的一連串Data Binding和Event Handling來初始化物件, 不費點功夫還搞不清楚它的來龍去脈
一開始在MainWindow的constructor
  var kinectSensorBinding = new Binding("Kinect") { Source = this.sensorChooser};
  this.faceTrackingVisualizer.SetBinding(TexturedFaceMeshViewer.KinectProperty, kinectSensorBinding);
  this.sensorChooser.KinectChanged += this.SensorChooserOnKinectChanged;

newSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
newSensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
newSensor.DepthStream.Range = DepthRange.Near;
newSensor.SkeletonStream.EnableTrackingInNearRange = true;
newSensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;
newSensor.SkeletonStream.Enable();

其中DepthStream和SkeletonStream都要設成Near模式(如果只設一個會怎麼樣?)

在Microsoft.Kinect.Toolkit.FaceTracking的Utils.cs中 Feature Point有71個(0~108跳號)
比如:
        TopSkull                        = 0,
        TopRightForehead                = 1,
        MiddleTopDipUpperLip            = 7,
        AboveChin                       = 9,
        BottomOfChin                    = 10,
        RightOfRightEyebrow             = 15,
        MiddleTopOfRightEyebrow         = 16,
        LeftOfRightEyebrow              = 17,
        MiddleBottomOfRightEyebrow      = 18,
        AboveMidUpperRightEyelid        = 19,
        OuterCornerOfRightEye           = 20,
...

它在WPF程式中是以WPF的3D呈現臉部模型, 打光等設定也是在WPF中, 我把方向光和環境光的顏色改一下變成這樣:

1 則留言:

  1. Do you have all names the points? I search and i don
    t find.

    回覆刪除