C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

Freenect.hs - haskell の OpenKinect/libfreenect wrapper の使い方メモ

メモ

contexts

なにはともあれ context を初期化せにゃー使えんのよ。ってわけで基本:

do context <- newContext
   initialize context
   -- hogehoge
   -- fugafuga
   shutdown   context

コレは以下の様にイージーモードで使える様にもしてあるのでどうぞ:

withContext $ context -> do
  -- hogehoge
  -- fugafuga

Freenectライブラリーのアレコレは context 無いと使えないからこの中でアレコレしてね。

devices

Kinectのサブデバイス(camera, motor, audio)を選びんしゃい。

selectSubdevices context [Camera, Motor, Audio]

サブデバイスを選んだなら、デバイスID(0, 1, ..)を添えて制御を開始しましょうね:

withDevice context 0 $ device -> do
  -- mokemoke
  -- hoyohoyo

ちなみに、何台のKinectが接続されているかは、

deviceCount <- countDevices context

で分かるのよ・w・

深度モードの設定は:

setDepthMode device Medium ElevenBit

とかしたってね。この設定は次のコールバックよりも先に設定せなダメよ。

(ウサ註1:撮像面の分解能=[Low|Medium|High]=[QVGA|VGA|SXGA]にソースを見るに対応している気がする)
(ウサ註2:ピクセル辺りの深度分解能=[ElevenBit|TenBit|ElevenBitPacked|TenBitPacked]にソースを見るに対応している気がする)

深度群を得るコールバックは:

setDepthCallback device $ \payload timestamp -> do
  -- nekoneko
  -- nyannyan

とか定義したらいいよ。

(ウサ註3:DepthのpayloadはWord16

setDepthCallback
  :: Device
  -> ( Data.Vector.Storable.Vector GHC.Word.Word16 -- payload
    -> GHC.Word.Word32                             -- timestamp
    -> IO () )
  -> IO () )

深度群を実際に得始めるには:

startDepth device

とする。

ビデオモードの設定は:

setVideoMode device Medium RGB

(ウサ註4:ピクセルフォーマット=[RGB|Bayer|EightBitIR|TenBitIR|TenBitPackedIR|YUVRGB|YUVRaw])

ビデオを得るコールバックは:

setVideoCallback device $ \payload timestamp -> do
  -- koyoimochaga
  -- umaidegozaru

とか定義する。

(ウサ註5:VideoのpayloadはWord8

setVideoCallback
  :: Device
  -> ( Data.Vector.Storable.Vector GHC.Word.Word8  -- payload
    -> GHC.Word.Word32                             -- timestamp
    -> IO () )
  -> IO () )

ビデオを実際に得始めるには:

startVideo device

とする。

events

仕上げとして processEvents でデータを受信する必要がある。

processEvents context

実際のところは、

forever $ do
  processEvents context

とかして連続取得する。サンプルコードでは、`import Control.Monad.Fix`してfixを使い、

fix $ \repeat -> do
  processEvents context
  isDone <- readIORef done
  if isDone
    then return ()
    else repeat

とかしてる。

(ウサ註6:シングルスレッドかつビジーループで強引に取得してるんだろうか・・・そのうち実装除いておく必要がありそうだ。)

今回の記事について

書いてる途中でHDDが飛びまして。作業しながら書いていた記事は後半消え去ってしまいました。HDDのデータはバックアップから戻せるのでどうという事は無いのですが、ブラウザーで編集中のデータは消え去りまして。それから他にも今日はまあ色々とありまして、なんだかもう気力無いのでこげな感じで記事しめて寝るマス(´・ω・`)