針對微軟正式版 Kinect for Windows SDK 的 kinect-mssdk-openni-bridge

| | 2 Comments| 12:14
Categories:

目前要在 Windows 上進行 Kinect 的應用程式開發,主要應該是有兩個選擇,一個是微軟官方的 Kinect for Windows SDK,另一個則是開放平台的 OpenNI。基本上,由於考慮到跨平台的問題、以及對於微軟的開發環境的一些疑慮,Heresy 自己是都使用 OpenNI 啦~對於微軟的 Kinect for Windows SDK,Heresy 基本上也只有大概看過而已,沒有真的在寫他的程式。

而由於兩者的驅動程式是不同的,所以一般來說,在同一台電腦上,是沒有辦法很方便地同時使用這兩種開發環境的。不過,也由於 OpenNI 的開放性,所以實際上在 Kinect for Windows SDK 的 Beta 版出來的時候,就已經有網友針對他作封包,寫出可以在 OpenNI 下使用的模組了~而這個模組,就是 Heresy 之前在《讓 OpenNI 可以透過微軟 Kinect SDK 讀取 Kinect 的資料!》一文中介紹過的「kinect-mssdk-openni-bridge」(官網)。

當時,這個「kinect-mssdk-openni-bridge」(以下簡稱為「Bridge」)是針對 Kinect for Windows SDK Beta 1 寫的,後來在新的 Beta 2、以及正式版推出出的時候,也都有更新;不過,對於 Kinect for Windows SDK 正式版的改寫,實際上算是晚了不少,一直到四月才有正式支援(的樣子)

但是,最近作者似乎更新的相當勤勞!從四月初開始支援 Kinect for Windows SDK 1.0 開始,到現在已經改版好幾次、更新到 1.0.0.4 了~他不但針對正式版的 SDK 做了改寫,而且還支援 Kinect 的馬達控制、聲音擷取(包括聲音來源偵測、回音消除等功能)、以及新的 Kinect for Windows 硬體的「Near Mode」!

也因為這些功能的引進,目前來看他的功能可以說是相當地完整!在 Heresy 來看,如果是打算在可以安裝 Kinect for Windows SDK 的環境(Windows 7 / 8)下、進行 OpenNI Kinect 的程式開發的話,搞不好使用這個「kinect-mssdk-openni-bridge」已經算是比 avin2 的「SensorKinect」更好的選擇了~

至於要怎麼使用呢?建議可以參考官方的「README_en.TXT」這個文件(連結),裡面有相當完整地說明。Heresy 自己沒有真的去玩,不過還是大概來列一下他的幾點比較重要的說明:

  1. User Generator 的設定

    首先,在 User Generator 的部分,主要是透過 production node 的名稱(name)來做使用上的控制。如果要在 OpenNI 內建立這個 bridge 提供的 user generator 的話,需要在建立時、透過 query 來加上名稱的指定。如果是使用 XML 來進行初始化(請參考《使用 XML 設定檔來初始化 OpenNI》)的話,他的寫法會是:

    <OpenNI>
    ...
    <ProductionNodes>
    ...
    <Node type="User" name="User1">
    <Query>
    <Name>KinectSDKUserSkeletonGenerator</Name>
    </Query>

    </Node>
    ...
    </ProductionNodes>
    </OpenNI>

    重點就是要加上 <Query>、並且指定 <Name> 為「KinectSDKUserSkeletonGenerator」了~

    而如果是要寫在程式裡的話,則是使用 xn::Query 來做控制:

    xn::Query mQuery;
    mQuery.SetName( "MSRKinectUserSkeletonGenerator" );

    xn::UserGenerator mUserGenerator;
    mUserGenerator.Create( mContext, &mQuery );

    另外要注意的是,這個 User Generator 是採用不需要標準校正姿勢的架構(請參考《不用校正姿勢的 NITE 1.5》),如果程式的人體骨架追蹤使採用早期、需要使用「Psi」 標準校正姿勢的架構來寫的話(請參考《透過 OpenNI / NITE 分析人體骨架》),那則需要把上面所使用的「KinectSDKUserSkeletonGenerator」這個名稱,改成「KinectSDKUserSkeletonGeneratorWithPsiPoseEmulation」來模擬 Psi 姿勢偵測的事件。

  2. Depth Generator

    深度感應器的建立方法,應該是沒有什麼特別的,和之前一樣使用就可以了;不過雖然深度感應器支援 QVGA(320×240)和 VGA(640×480)兩種解析度(MapOutputMode),但是就算設定為 VGA 模式,在有使用上面的 User generator 的情況下,解析度會被強制設定為 QVGA、然後模擬成 VGA,這是使用上可能要注意的。

    另外,新版的 Bridge 也支援了 Kinect for Windows Hardware 的「Near mode」,要使用的話是透過 Depth Generator 的「nearMode」這個屬性(Property)來做設定;以 XML 來說,要啟用 Near mode 的寫法是:

    <Node type="Depth" name="Depth1">
    <Configuration>
    <Property type="int" name="nearMode" value="1"/>
    </Configuration>
    </Node>

    而對應到程式裡面,應該就是像下面這樣了:

    xn::DepthGenerator xDepthGen;
    xDepthGen.Create( mContext );
    xDepthGen.SetIntProperty( "nearMode", 1 );

    最後,Bridge 所提供的 depth generator 還可以設定讓深度值太近、太遠、以及未知的這三種狀況,回傳不同的值(OpenNI 預設這三種狀態都是無法偵測、都是回傳「0」);要控制這項功能的開啟與否的話,則是針對「distinctOverflowDepthValues」這個屬性來做控制,基本上方方法和上面的「nearMode」相同。

  3. Image Generator

    Bridge 所提供的 Image Generator 似乎只有提供 VGA(640×480) 和 1280×1024 @15FPS 這兩種解析度,似乎不支援 QVGA,這點是在使用時要注意的。

  4. 使用 Kinect 的馬達

    Kinect 的馬達角度的控制,主要是透過 Image Generator、Depth Generator 或 User Generator 的「cameraElevationAngle」這個屬性來做控制的。他的設定方法,基本上就是下面這樣的形式:

    XnUInt64 angle = 10;
    xDepthGen.GetIntProperty( "cameraElevationAngle", angle );
    xDepthGen.SetIntProperty( "cameraElevationAngle", angle );

    另外,如果要進一步控制的話,也可以透過「nuiSensorPointer」這個屬性,來取得 Kinect for Windows SDK 裡的「INuiSensor」的物件指標、透過強制轉型的方法來進行操作;下面就是使用的範例:(個人是覺得這樣的用法還滿危險的…)

    XnUInt64 i;
    xDepthGen.GetIntProperty("nuiSensorPointer", i);
    INuiSensor* pSensor = (INuiSensor*)i;
    pSensor->NuiXxx(...);

    這邊要注意的是,馬達的控制功能功能只有在開始產生資料(StartGeneratingAll())後才可以使用。

    最後,這個版本的 Bridge 在 User Generator 的部分還提供了可以針對使用者自動調整馬達角度的功能!要開啟這項功能,則是要把 User Generator 的名稱,從本來的「KinectSDKUserSkeletonGenerator」改成「KinectSDKUserSkeletonGeneratorWithAutoElevation」。

  5. 聲音的取得

    Audio Generator 的部分,其實 Heresy 自己在 OpenNI 也都沒有用過,所以其實也不是很熟。而在這邊,Bridge 所提供的 Audio Generator 除了可以取得原始聲音資料外,應該是也把 Kinect for Windows SDK 針對聲音做處理的各項功能以屬性的方式移植過來了~ 下面就是他的 XML 設定的說明:

    <Node type="Audio" name="Audio1">
    <Configuration>
    <!-- Beam forming mode
    0: Adaptive (Controlled by Kinect-specific DSP)
    1: Automatic (Controlled by DMO)
    2: Manual (Controlled by the application via the beamAngle property
    explained later) -->

    <Property type="int" name="beamAngleMode" value="0"/>
    <!-- Automatic gain control: 0(off), 1(on) -->
    <Property type="int" name="automaticGainControl" value="0"/>
    <!-- Echo cancellation (AEC) and suppression of residual signal (AES)
    0: None
    1: AEC
    2: AEC and AES once
    3: AEC and AES twice -->

    <Property type="int" name="echoCancellationMode" value="2"/>
    <!-- Center clipping (a technique to remove the residual signal after AEC) and
    Noise filling (a technique to make the sound natural by using a small
    amount of noise instead of silence after removing the residual signal)
    0: None
    1: Center clipping
    2: Center clipping and Noise filling -->

    <Property type="int" name="centerClippingMode" value="0"/>
    <!-- Noise suppression: 0(off), 1(on) -->
    <Property type="int" name="noiseSuppression" value="1"/>
    <!-- Audio buffer size in milliseconds. The audio data is
    lost unlsee the application polls the audio data
    within this interval. Set before StartGenerating. -->

    <Property type="int" name="bufferSizeInMs" value="1000"/>
    </Configuration>
    </Node>

    而在程式中要取得相關的數值的話,基本上就是:

    double beamAngle, sourceAngle, sourceAngleConfidence;
    audioGenerator.GetRealProperty("beamAngle", beamAngle);
    // read-only or read-write when beamAngleMode is manual
    audioGenerator.GetRealProperty("sourceAngle", sourceAngle);
    // read-only
    audioGenerator.GetRealProperty("sourceAngleConfidence", sourceAngleConfidence);
    // read-only


這篇大概就是這樣了。不過也提醒一下,實際上 Heresy 並沒有真的去用過,只是照著文件來寫的。而如果有使用上的問題,建議也可以直接到作者在官方論壇所發的《KinectSDK 1.0 OpenNI/NITE at the same time (Part 2)》這串討論來看看、提問。

而在 Heresy 來看,他比較可惜的一點,就是他不支援 64 位元版、只支援 32 位元版了…所以就算是 64 位元的電腦,還是只能使用 32 位元的 OpenNI。

2 thoughts on “針對微軟正式版 Kinect for Windows SDK 的 kinect-mssdk-openni-bridge”

  1. 试了一下
    「kinect-mssdk-openni-bridge」,发现原来的OpenNI自带的
    viewPoint.SetViewPoint(image); 没法使用,
    调试是不出错,但是深度图片和彩色图片之间有视差,图像不匹配。

    你有没有这种情况

  2. to Lnya
    抱歉,Heresy 沒有實際在使用這個 bridge,所以不確定
    建議您直接到官方論壇問看看作者

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *