Kinectとは?
昨年、マイクロソフトから発売された「Xbox 360」用に開発された「Kinect」というゲーム用コントローラが、いまアツい視線を浴びています。Kinectの特徴は、デバイスを手にもったり体に装置を装着することなしに、ジェスチャーや音声認識をすることがでるという点で、それをゲームのコントローラーとして利用しようとしているわけです。
ジェスチャーの認識機能の基本的なしくみは、Kinect前部にとりつけられたレンズのひとつから、レーザーのパターンを広範囲に照射して、そのパターンの粗さや幾何学的な歪み具合から、対象物の3D構造を認識しているようです。暗視モードでKinectを使用している部屋を撮影すると無数の赤外線レーザのパターンが照射されているのがわかります。
Kinect Hackというムーブメント
ここまでは一般的なゲームコントローラーの話題だったのですが、なぜKinectがここまで注目されているのかというと、本来は XBox 360 専用だったKinectセンサーなのですが、一般的なUSB接続を使用しているため、PCやMacなどに普通に接続することが可能です。発売から数日で世界中のハッカー達が集中的に解析して、KinectセンサーとXBox本体との通信の仕組みを、PCやMacで使用できるように移植したオープンソースのドライバを開発してしまったのです。このことが「Kinect Hack」という新たなムーブメントを生みだし、発売から数日で様々な環境で簡単に使用できるようになってしまいました。僕が現時点で把握している範囲では以下のものがあるようです。
- openFrameworks – Theo Watsonさん開発の ofxKinect アドオン
- processing – Daniel Shiffman氏による外部ライブラリ
- Max/MSP Jitter – Jean-Marc Pelletier氏作成のexternalオブジェクトjit.freenect.grab
- QuartzComposer – Kosada Incorporated によるKinectTools
- Cinder – Robert Hodgin aka Flight404氏によるCinder-Kinect
- ActionScript (Flash) – Juan Carlos del Valle氏によるAS3による実装
- vvvv – 詳細不明ですが、近日中にvux氏がプラグインをリリース予定らしい
OpenNI – 純正のKinectドライバのオープン化
Kinect Hackの盛り上りに答えるように、2010年12月にはKinectの3Dセンシング技術を開発していたPrimeSense社が自らKinectで使用されているジェスチャー認識のライブラリをオープンソースで公開しました。PrimeSense社では、自然なインタラクション(Natural Interaction)を実現するオープンな環境ということで、OpenNIという組織を立ち上げてドライバや様々なリソースを提供しています。OpenNIのドライバのジェスチャ認識の精度は驚異的なもので、このライブラリはKinect Hackと同様、今後様々な環境に移植され応用されていくことでしょう。
Kinect Hackを使った作品いろいろ
ジェスチャー認識のデバイスとして
では、このKinect Hackの成果として、どのような作品が生まれてきたのか、いくつか実例を見てみましょう。まず始めに紹介するのは、KinectをopenFrameworksのアドオンとして開発したTheo Watsonさんの作品。カメラの前で手を動かすとその腕の動きから骨組みを解析して、鶏のパペットをインタラクティブに操作することが可能です。
Interactive Puppet Prototype with Xbox Kinect from Theo Watson on Vimeo.
ジェスチャー解析を応用することで、様々な楽しい体験が可能となります。Chris O’Sheaさんは、Kinectを使用して「エアギター」を演奏できるというアプリケーションのプロトタイプを公開しています。
Air Guitar prototype with Kinect from Chris O'Shea on Vimeo.
「面白カメラ」としてのKinect
ジェスチャー認識としてKinectを活用する他にも、様々な面白い応用が考えられます。カメラからの距離を図ることができるという3Dスキャナーとして。さらには3Dスキャナーの付属した「面白カメラ」としてKinectを使用するという発想で、様々な興味深い作品が生まれています。KinectをCinderに移植したFlight404ことRobert Hodginさんは、Kinectを特殊なカメラとして使用した興味深い作品をいくつか公開しています。例えば、複数の時間がずれながら共存することで、人物が増殖するように、時間の経過を一度に見ることのできるような作品。
Temporal echo from flight404 on Vimeo.
さらには、複雑なマッピング処理を施すことで、人物の動きが不思議な質感をもって再現される作品。
Self Occlusion from flight404 on Vimeo.
深津貴之(fladdict)さんは、openFrameworksとKinectの組み合せで、人物を透明化してしまう「光学迷彩」の実験を行っています。
Kinect Hackを実践してみる
作品を見るだけでなく、実際にKinect Hackを実践してみましょう!最近はすっかりopenFrameworksべったりの僕としては、やはりofxKinectを使ってみようということで、ここ数日いろいろ試しています。まず先程紹介した、TheoさんのGitのリポジトリから最新のofxKinectをダウンロードして、openFrameworksのappsフォルダ内にコピーすると、すぐにサンプルが実行できると思います。
Theoさん作のofxKinectは、さすが良くできていて、クラスのメソッドを通じてKinectで検出した様々な情報にすぐにアクセスできるようになっています。例えば、
- float getDistanceAt(int x, int y); – 指定した座標(x, y)の距離を計測してfloat型で返す
- ofColor getCalibratedColorAt(int x, int y); – 指定した座標(x, y)のカメラで撮影した色を取得する
早速、プログラムしてみました。アドオンやプロジェクトファイルなど一式パッケージングしたものはこちらからダウンロードできます。
ofKinectStudy.zip (Zip, 115.4KB)
testApp.h
#ifndef _TEST_APP
#define _TEST_APP
#include “ofMain.h”
#include “ofxOpenCv.h”
#include “ofxKinect.h”
class testApp : public ofBaseApp
{
public:
void setup();
};
void update();
void draw();
void exit();
void keyPressed (int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
ofxKinect kinect;
float rotX, rotY;
#endif
testApp.cpp
#include “testApp.h”
void testApp::setup()
{
ofSetFrameRate(60);
}
ofBackground(0,0,0);
ofSetCircleResolution(12);
rotX = 0;
rotY = 0;
kinect.init();
kinect.setVerbose(true);
kinect.open();
void testApp::update()
{
kinect.update();
}
void testApp::draw()
{
int step = 4;
int calibrateX = 0;
int calibrateY = 10;
unsigned char * calibratedPixels = kinect.getCalibratedRGBPixels();
ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
ofRotateX(rotX);
ofRotateY(rotY);
ofTranslate(kinect.width/2, kinect.height/2, 1000);
for (int j = 0; j < kinect.height; j+=step) {for (int i = 0; i < kinect.width; i+=step) {
float distance = kinect.getDistanceAt(i, j);
int colorPos = kinect.width * j * 3 + i * 3;
ofSetColor(calibratedPixels[colorPos], calibratedPixels[colorPos+1], calibratedPixels[colorPos+2]);
ofPushMatrix();
ofTranslate(i – kinect.width, j – kinect.height, distance * -10.0);
ofRotateX(-rotX);
ofRotateY(-rotY);
ofCircle(0, 0, step*0.4);
ofPopMatrix();}
}
}
void testApp::exit()
{
kinect.close();
}
void testApp::keyPressed (int key){}
void testApp::mouseMoved(int x, int y){}
void testApp::mouseDragged(int x, int y, int button)
{
rotX = float(y) / ofGetHeight() * 360 – 180;
}
rotY = float(x) / ofGetWidth() * 360 – 180;
void testApp::mousePressed(int x, int y, int button){}
void testApp::mouseReleased(int x, int y, int button){}
void testApp::windowResized(int w, int h){}
実験の結果、こんな映像ができました。楽しいです。処理もすごくスムーズです。
ofxKinect study #05 from Atsushi Tadokoro on Vimeo.
今後も続々とKinect Hackの成果でてきそうです。最後に、いくつか参考になりそうなサイトをあげておきます。
というわけで、ぜひ皆さんもこのKinect Hackのビッグウェーブに乗りましょう!!
※これは入れておいたほうがよい、という追加情報があればhello at cbc-net.comまで!
Text by Atsushi Tadokoro
http://yoppa.org/
http://twitter.com/tadokoro