教育システム情報学会関西支部若手研究者フォーラムkinect勉強会(hackathon)資料...
DESCRIPTION
2014.06.14に近畿大学理工学部にて開催された教育システム情報学会関西支部若手研究者フォーラムKinect勉強会(Hackathon)の資料です。TRANSCRIPT
Kinect勉強会資料
おち@おちラボ
2014.06.14 教育システム情報学会関西支部若手研究者フォーラム Kinect勉強会(Hackathon)資料
本日の勉強会の狙い
□Kinectプログラミングの基礎
□アプリケーションを作っていく上での肝
□簡単なプログラムを作ってみる(スケルトン利用)
プログラミングに必要なもの
Kinect 本体
□ Kinect for Windows 今年の夏まではこれ!
□ Kinect for XBOX360 ・XBOX用
・商用利用不可
・Nearモード非対応
Kinect のハードウェア
□ RGBカメラ
□ 赤外線カメラ
□ 赤外線LED
□マイクアレイ(4つ)
□加速度センサー
プログラミングに必要なもの
□SDK(必須)
・using Microsoft.Kinect.
□開発者ツールキット(あったほうがいい)・SDKとは別にダウンロード
・using Microsoft.Kinect.Toolkit;
・サンプルや拡張ライブラリがある
・動作確認にも使える
動作するPC
□Windows7以上
□Windows on 仮想マシン on Mac ・Vmware ・Pallarels ・bootCamp
□Mac、Linux (OpenNI+NITE利用)
Kinectプログラミング始めるにあたって
プログラミング言語はどうするか?
C++、C#、Scratch等、対応言語はいろいろ →とりあえずC#が無難
Kinect SDK 更新が多い。できるだけ最新版に。(後述)
→ 書籍では未対応な箇所が多い
グラフィック処理(視覚的な支援をするなら)
Windowsグラフィックスの知識が必要
(FormではなくWPFを推奨)
Kinectプログラミングの勉強はちょっと厄介
SDK1.6以降から変更点が多い
・利点:機能追加、パフォーマンス向上
・欠点:対応書籍が少ない
次世代Kinect (Kinect2)は1.6以降のスタイルを踏襲しつつ更に変更
→ 追従しないとダメです
とりあえず動かしてみよう
Developer tool Kit Browserを利用してみよう
・Developer Tool Kit についている
・動作確認にも使える
・これだけでも楽しめる
Kinectから何が入手できるのか(1)
□RGBカメラ映像
1. InfraredResolution640x480Fps302. RawYuvResolution640x480Fps153. RgbResolution1280x960Fps124. RgbResolution640x480Fps305. YuvResolution640x480Fps156. RawBayerResolution640x480Fps307. RawBayerResolution1280x960Fps12
Kinectから何が入手できるのか(2)
Depthカメラからの深度情報 ・いわゆるDepthイメージ ・各ピクセルに深度データ+ユーザID (13bit) (3bit)
● Unknown [ 0 ~ 400mm , 8000mm 〜]● TooNear [ 400 ~ 800mm ]● 400 ~ 3000 mm (Nearモード)● 800 ~ 4000 mm (Normalモード)● TooFar [ 4000 ~ 8000mm ]
認識のためのモード変更
Nearモードkinect.DepthStream.Range =DepthRange.Near;
Seatedモード
kinect.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;→ 上半身10箇所だけとれる
深度データの計測原理と制約
原理:Light Coding
□赤外線LEDでランダムドットパターンを照射
□赤外線カメラで受信
両者の位置にズレ ・・・影ができる
Kinect2 ・TOF方式による深度計速 ・赤外線LED+カメラの位置が同じ
影が解消!
Kinectから何が入手できるのか(3)
(Kinectを中心に)座標(X,Y,Z)角度(方向ベクトル)
http://msdn.microsoft.com/en-us/library/jj131025.aspx
Skeleton情報
Skeletonの座標系確認
出力単位はメートルです
X
Y
Z
単位の違いに注意
Depthカメラ
mm(ミリメートル)単位
Skeleton情報
m(メートル単位)
Kinectから何が入手できるか?(4)~骨格情報の信頼度~
□基本的に正面を向いていることを前提
・交差に弱い
・回転には未対応
□関節状態を利用する
JointTrackingState.Inferred ・・・推定状態
JointTrackingState.Tracked ・・・測定状態
→ 精度はさほど良くない
□独自に解釈し直す
複数ユーザへの対応
□最大6名まで認識可能(スケルトンは2つ) PlayerIndex
1~6
0の場合は存在しない
→ 認識できてしまうことが厄介!!
□意図しない複数ユーザへの対応をどうするか?
→ 複数ユーザへの対応をしないのであれば
しないための実装工夫が必要
実は、床面情報もわかるらしい
SkeletonFrameのFloorClipPlaneプロパティ
床のX,Y,Z方向 +床までの距離(D)
AR処理をする際は要利用検討
Kinectプログラミングの肝
□Skeletonの情報を利用するだけでは限界
(初心者には やりやすい)
□ Depthイメージを如何に利用するか?
→ 画像処理(CV)の知識が必要
□Skeletonの情報を独自に推定
ここからプログラミングの話へ
Kinectからのデータはどうやって入手するのか?
Kinectのクラスでイベントが用意されている
・SkeltonFrameReady ・DepthFrameReady ・ColorFrameReady
・AllFrameReady ・InteractionFrameReady
これらのイベントが 最大30fpsの間隔でやってくる
イベントの注意事項(1)
・SkeltonFrameReady +
・DepthFrameReady +
・ColorFrameReady
AllFrameReady≠
シングルスレッド
Color → Depth → Skelton
イベントの注意点(2)
Colorフレームは遅れてやってくる
例) フレーム番号(タイムスタンプ)の比較
img:2090 (10385649ms) dep:2101 (10385656ms) skl:2101 (10385656ms)
AllFrameReadyでも同様
AllFrameReadyを使うのが無難
● skltonとdepthを同時に扱いたい場合● skltonとdepthのイベント取得順序に
縛られたくない場合
ColorFrameの遅れは解消しない
イベントを制御することはできないか?
ニーズ
・他のイベントフレームワークと競合する
・自分のフレームワーク上でコントロールしたい
・別スレッドで処理したい
可能です → ポーリングメソッドが用意されている
(自分のアプリのループの中で)
OpenNextFrameメソッドを呼び出す難易度高
各Frame情報の破棄について
● かならず Dispose()する必要がある
● C#のusingステートメントで括れば Disposeする必要はありません
例)XXXFrameReadyイベント内でusing (ColorImageFrame colorFrame = args.OpenColorImageFrame(){
}
マルチスレッド化について
Color、Depth、Skeletonなどを全て扱っていると
処理が重くなる
マルチスレッド化がベター
→ イベント登録処理を別スレッドにする
Threadクラス、Backgroudworkerクラス
欠点
UIスレッドへの処理についてInvokerが必要
骨格情報の構造
SkeletonFrame Skeleton[ユーザID]
TrakingID
TrakingState
Position ・・・ 重心(脊椎: Spine)
ClippedEdge ・・・Kinectの視野外かどうか
Joints[JointType.ID] ・・・ Jointの配列
Joint ・・・ 各関節
Position(X,Y,Z), TrackingState
CopySkeletonDataTo
骨格情報のカスタマイズ
実は、 kinect.SkeletonStream.Enable();にTransformSmoothParametersを渡せば、
骨格上出力のカスタマイズができる
・補正の正確性
・ジッタを軽減する半径(範囲) ・生のデータから逸脱できる最大の半径
・フレーム間予測するフレーム数
・平滑化(スムージング)
骨格入手のユーザ指定
複数の人物からどれのスケルトンを入手するか?
→デフォルトではシステム任せ
任意のユーザIDを指定可能
SkeletonStream.AppChoosesSkeletons =trueSkeletonStream.ChooseSkeletons()メソッド
で、1名または2名のIDを指定可能
なんらかの方法でユーザの特定が必要
Kinectプログラミングのレベル
(初心者)
・SkeltonFrameの座標情報だけを利用
(中・上級者)
・SkeltonFrameの情報を修正する
・DepthFrameの情報を組み合わせる
・ColorImageの情報を組み合わせる (CV系の技術を組み合わせる)
Skeleton/ColorFrameに対するメモ書き
//byte配列に格納する
byte[] pixelData = new byte[colorFrame.PixelDataLength];colorFrame.CopyPixelDataTo(pixelData);//表示処理
this.rgbBitmap.WritePixels(this.colorImageBitmapRect, pixelData, this.colorImageStride, 0);
//スケルトンの情報をSkeleton配列に格納する
Skeleton[] skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];skeletonFrame.CopySkeletonDataTo(skeletonData);
DepthFrameに対するメモ書き
表示するときはShort型に変換する
//DepthFrame表示用処理
short[] DepthBitmapPixelDatadepthFrame.CopyPixelDataTo(DepthBitmapPixelData);this.depthBitmap.WritePixels(this.depthImageBitmapRect, DepthBitmapPixelData,
this.depthImageStride, 0);
深度データを取ってくるときは、 DepthImagePixel配列に変換する
//深度情報取得用
DepthImagePixel[] depthPixelData;depthFrame.CopyDepthImagePixelDataTo(depthPixelData);
short depth = depthPixcelData[i].Depth;short playerID = depthPixcelData[i].PlayerIndex;
座標変換系メソッド(v1.6から変更)
● MapColorFrameToDepthFrame● MapColorFrameToSkeletonFrame● MapDepthFrameToColorFrame● MapDepthFrameToSkeletonFrame● MapDepthPointToColorPoint● MapDepthPointToSkeletonPoint● MapSkeletonPointToColorPoint● MapSkeletonPointToDepthPoint
□Kinect.MapXXXX系は非推奨です。
□kinect.CoordinateMapper.MapXX系を 使いましょう。
本日のプログラミング演習
GitHubにサンプルを置いてます
https://github.com/ochilab/KinectSampleForLab
上記プログラムは作りかけなので冗長なところがあります
課題
・関節情報を入手して、ボール(円)を操作しよう
・ポーズやジェスチャーでボールを変化させよう
サンプルのグラフィック処理のアプローチ
● ImageコントロールにRGBカメラ映像表示● 透明化したCanvasに各種描画● 両者を重ねる(意外とパフォーマンスが良い)
つまり、Canvasを描画レイヤーにしている
WPFベースにしています
ジェスチャー認識へのヒント
○ジェスチャー → ポーズの組み合わせ
○ポーズ → 複数の関節の位置関係
(座標で考える、角度で考える)