OpenNI 2 的 Kinect 驅動模組加強版


在之前的 OpenNI 2.2.0.21 版裡面,OpenNI 算是終於把 Kinect 的 Image registration 功能加進來了~這點,對於要考慮使用不同裝置來開發的人,基本上應該已經算是比以前方便不少了;不過很遺憾,他還是不支援鏡像(mirror)的功能。除此之外,Kinect 感應器本身的馬達、加速度感應器、以及 Kinect for Windows 感應的「Near Mode」,也都還是不能使用的。

由於 Heresy 前一陣子在研究 OpenNI 2 的驅動程式模組(參考)、也寫了一個 WebCam4OpenNI2;後來想想,反正都大概知道該怎麼做了,那與其等別人寫,倒不如自己試著改看看吧~所以,就把這些功能都補上了。這部分的修改,目前已經在 OpenNI 那邊建立 pull request(#22)了,但是目前還沒被整進去;不過如果想看怎麼改的話,應該是可以直接在 GitHub 上看到。

而如果只是想下載來用的話,可以到

http://sdrv.ms/13sEELF

這邊下載;在 x64 下,就是 64 位元的 Kinect.dll,x86 下則是 32 位元的版本。要使用的話,只要把這個檔案下載後,取代掉原來的 Kinect.dll 就可以了。(\OpenNI2\Drivers\ 目錄下)

這個版本提供的功能,包括了:

  • 鏡像(mirror)
  • 感應器角度(KINECT_DEVICE_PROPERTY_CAMERA_ELEVATION
  • 感應器加速度感應器資料(KINECT_DEVICE_PROPERTY_ACCELEROMETER
  • 深度的 Near Mode(KINECT_DEPTH_PROPERTY_NEAR_MODE

要測試鏡像的功能的話,由於是 OpenNI 本身就定義好的介面,所以可以直接呼叫 VideoStreamsetMirrorEnabled() 來做控制;不想自己改程式的話,則可以用官方的 NiViewer 來試看看(按鍵盤的 m)。

至於其他的功能,則是定義在 Heresy 自己加入的 KinectProperty.h 這個檔案裡,可以透過 DeviceVideoStreamgetProperty()setProperty() 來做存取;下面是簡單的說明:

  • 感應器角度(KINECT_DEVICE_PROPERTY_CAMERA_ELEVATION

    用來讀取、設定 Kinect 的上下傾角用的,適用於 Device,資料型別是 long,可以讀取也可以寫入。下面是一個使用範例:

    long value;
    m_device.getProperty( KINECT_DEVICE_PROPERTY_CAMERA_ELEVATION, &value );
    m_device.setProperty( KINECT_DEVICE_PROPERTY_CAMERA_ELEVATION, value + 1 );

    m_device 是一個對應到 Kinect 的 openni::Device,透過 getProperty(),可以把目前的角度讀取出來、寫到 value 這個型別為 long 的變數裡;透過 setProperty(),則可以指定所需要的角度、來控制 Kinect 的馬達。 在上面的例子裡,就是去讀取現在的角度後、設定讓它抬高 1 度。

    內部實際是去呼叫 Kinect for Windows SDK,INuiSensorNuiCameraElevationGetAngle()NuiCameraElevationSetAngle() 這兩個函式;詳細可以參考 MSDN 的說明(連結一連結二)。

     

  • 感應器加速度感應器資料(KINECT_DEVICE_PROPERTY_ACCELEROMETER

    這是用來讀取 Kinect 內部的加速度感應器,用來判斷 Kinect 目前的方向的。一樣是適用於 Device,資料型別是 KVector4,裡面是四個 float,代表目前加速度的方向,如果 Kinect 是完全水平的話,他的值會是 ( 0, -1, 0, 0 )、代表指向下方。這個值只能讀取、不能設定;下面是一個簡單的讀取範例:

    KVector4 vec;
    m_device.getProperty( KINECT_DEVICE_PROPERTY_ACCELEROMETER, &vec );
    printf( "%f, %f, %f\n", vec.x, vec.y, vec.z );

    一樣,透過 DevicegetProperty() 可以把結果寫到 vec 這個 KVector4 的變數裡面。

    (注意:Heresy 沒有去處理 Kinect for Windows SDK 和 OpenNI 座標系統的問題)

    內部實際是去呼叫 Kinect for Windows SDK,INuiSensorNuiAccelerometerGetCurrentReading() 這個函式;詳細可以參考 MSDN 的說明(連結)。

     

  • 深度的 Near Mode(KINECT_DEPTH_PROPERTY_NEAR_MODE

    這是用來設定 Kinect for Windows SDK 的「Near Mode」的功能。適用於深度影像的 VideoStream,資料型別是 OniBool(OpenNI 定義的布林變數),可以讀取也可以設定。下面是簡單的使用範例:

    OniBool flag;
    m_depthStream.getProperty( KINECT_DEPTH_PROPERTY_NEAR_MODE, &flag );
    m_depthStream.setProperty( KINECT_DEPTH_PROPERTY_NEAR_MODE, !flag );

    這邊的 m_depthStream 是對應到 Kinect for Windows 感應器深度影像的 openni::VideoStream,透過 getProperty(),可以把資料寫到 flag 這個 OniBool 的變數裡,用來判斷目前是否有開啟 Near Mode;而透過 setProperty() 則可以設定是否要切換到 Near Mode。在上面的例子裡,就是會先讀取現在的模式、然後設定成另一個模式。

    內部實際是去呼叫 Kinect for Windows SDK,INuiSensorNuiImageStreamGetImageFrameFlags()NuiImageStreamSetImageFrameFlags() 這兩個函式;詳細可以參考 MSDN 的說明(連結一連結二);不過說實話,Heresy 不太確定這邊的寫法是否完全正確。

另外,在 SkyDrive 上的「SampleViewer」目錄裡的 Viewer.cpp 這個檔案,則是根據官方的「SampleViewer」這個範例(\Samples\SimpleViewer)做修改的;裡面會在每次更新畫面的時候,都讀取加速度感應器的資料並輸出,而如果按下鍵盤的「n」,則可以切換 near mode 的開關,按下鍵盤的「+」和「」,則可以每次一度、控制感應器的上下傾角(不過好像會造成一定程度的延遲)。

大致上就是這樣了。由於 Heresy 自己也算是剛寫完、並沒有做很嚴謹的測試,所以如果有人有發現問題的話,就麻煩回報一下吧~


OpenNI / Kinect 相關文章目錄

對「OpenNI 2 的 Kinect 驅動模組加強版」的想法

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.