こんにちは. @non117 です. この記事はOUCC アドベントカレンダー 2014 7日目の記事です. 今日は私が研究で使ってるKinect v2について紹介しようと思います.
KinectとはXbox 360のために開発されたNUI(ナチュラルユーザインターフェイス)の一つで, ジェスチャーや音声認識によってゲームへコマンドを入力するデバイスです. Kinectは普通のRGBカメラと赤外線カメラ, マイクを積んでおり, 人間の位置, 動き, 声などを認識することができます.
もともとはゲームの入力デバイスだったのですが, 安価な深度センサとして注目されてしまったお陰でエンタメ系の人々やガチ研究者の目についてしまいました. その結果, 有志がKinectの解析を行ったりOSSのドライバ(今はなきOpenNI)を書いたりして, 今や安価なモーションキャプチャのデファクトスタンダードとなってしまいました.
MS様もそんな開発者を無視できなくなったのか, 公式にPC版Kinectを発売したり, 当初クソだった Kinect SDKをまともに使えるソフトウェアに改良するようになりました. そして2014年, ついにKinectのバージョン2が発売することになったのです.
Kinect v2@雲台
さて, 次にモーションキャプチャとしてのKinectがどう優れているのか, どうやってモーションキャプチャとして使うのかについて解説しようと思います.
Kinectがモーションキャプチャとして優れている点は精度がそこそこ出ること, 安価であること, 身体に__センサを取り付けることなく__人間の動作を記録できることです. 普通のモーションキャプチャでは人間が専用のスーツを着て, 複数台のカメラでスーツにくっついたマーカを撮影する手法が一般的です. しかし, このスーツを着るというのが実験の条件によっては大きな制約になる上に, この方式のモーションキャプチャは調達するのに数百万円かかることが普通です.
光学式モーションキャプチャの例. スーツがうっとうしい.
対して, Kinectはたかだか数万円のKinect本体が数台と, Kinectにつなぐ一般的なPCがあれば良いので, Kinect 4台でモーションキャプチャシステムを作ってもせいぜい50万円かそこらで調達できます. また, KinectはMicrosoft Researchの謎技術(機械学習)で人間の骨の動きを推定するため, 身体に何もつけることなくいつもどおりの服装で動作を記録できます.
このように, Kinectが安価なモーションキャプチャとして優れていることがわかりましたが, 勿論弱点もあります. Kinectは赤外線カメラによって人間の身体がどこにあるか, そしてどんな形をしているかを取得します. なので, カメラに対して正面を向いた状態が最も精度よく記録ができるのに対し, カメラに身体の横を向けた状態や, 胴体で遮蔽された腕などは使い物になるデータが撮れなくなります. この問題に対しては, Kinectを複数台使うことによって解決ができます. これは横を向いてしまうなら複数の方向から撮ってしまえば良いという乱暴ではありますが確実な解決法です. 複数台で撮ったデータをどうやってマージするのかという問題が依然としてありますが, 上手く座標変換してやることによって綺麗に骨格を統合できます.
Kinect v1 | Kinect v2 | |
---|---|---|
カラー | 640x480 | 1920x1080 |
赤外線 | 320x240 | 512x424 |
関節 | 20関節/人 | 25関節/人 |
水平視野角 | 57度 | 70度 |
垂直視野角 | 43度 | 60度 |
モーションキャプチャとして優れたKinectですが, v1の頃には視野角が狭くて人が画面の外に出てしまう問題がありました. また, 関節点の推定精度があまり良くなかったという問題もありましたが, v2になってからは光学特性の向上と, 機械学習の技術の進歩?により両方の問題が解決することになりました.
広い視野角
しかし, スペックが向上したことによってかなしい問題も起こります. まずカラー画像の解像度が4倍以上, 深度画像の解像度が2倍程度になったことにより, Kinectから転送されてくるデータ量がかなり多くなりました. なので, v2からはUSB 3.0が必須です. しかも何故かUSB 3.0のチップに相性があるようで, 私のAMD製CPUで来んだ自作マシンでは認識してくれませんでした. さらに, データ処理量が増えたことによりCPUなどの計算資源も多く使うようになりました. 人間1人を認識するだけなら大したことはありませんが, 3人くらいになるとPCのファンがかなりうるさい状態になります.
そして, モーションキャプチャとして使う場合の一番の問題がIOです. この用途では基本的にKinectで撮れた情報を全て画像などの形式で保存するため, 10MB/s Write以上の速度は必須と言って良いでしょう. RAM DISKを積む方法でも解決はできますが, 30分も記録を行うとデータ量が10GBは余裕で超えてるのであまり現実的ではありません. SSDか速めのHDDを積むのが現状の最適解になっています.
また, Kinect SDKの対応しているOSがWindows 8.xのみという問題もあります. 何故なのか理由はよくわかりませんが, せめてWindows 7くらいまでは対応して貰えませんかね…….
C#でKinectから人間の骨格情報を取ってくるサンプルコードを置いておきます.
using Microsoft.Kinect;
// 初期化処理の概略
private InitializeMethod()
{
KinectSensor kinectSensor = KinectSensor.GetDefault();
BodyFrameReader bodyFrameReader = kinectSensor.BodyFrameSource.OpenReader()
bodyFrameReader.FrameArrived += FrameArrived;
kinectSensor.Open();
}
// データが来たら...
private void FrameArrived(object sender, BodyIndexFrameArrivedEventArgs e)
{
bool processed = false;
using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame())
{
if (bodyFrame != null)
{
if (this.bodies == null)
{
// Bodyクラスが1人の人間の姿勢, 顔などの情報を持っている
this.bodies = new Body[bodyFrame.BodyCount];
}
bodyFrame.GetAndRefreshBodyData(this.bodies);
processed = true;
}
}
if (processed)
{
// do something.
}
}
Skeleton Trackingの一例
ね、簡単でしょう? +。:.゚٩(๑>◡<๑)۶:.。+゚
細かいことは公式ドキュメントを読めばだいたい解決します
今回はモーションキャプチャとしてのKinect v2について簡単に解説しました.
他にもKinectは深度センサで空間をスキャンしてポイントクラウドを構築する用途などにも使われており, たいへん有用でお求めやすくなっております. ぜひ購入して北米の家の広さを実感してみてください.