昨日、openFrameworksでLeapMotionを使ってみたので、その備忘録メモ。自分の環境はMacなので、Macで進めます。

LeapMotionをアクティベート

LeapMotionを箱から取り出すと、上にURL “LeapMotionセットアップ”の書いてあるシールが張ってあります。そのURLにアクセスして、Mac Downloadをクリックします。

LeapMotionのアクティベート

そうすると、こんな感じでダウンロードが勝手にはじまります。ちょっと時間かかるので、導入のムービーでも見ときましょう。

インストール

あとはこのdmgの中のpkgファイルを開くと、インストールが始まります。

インストールが完了したら動くかどうか確認してみましょう。アプリケーションフォルダの中にLeap Motion Orientationというアプリケーションがインストールされていると思うので、それを起動します。

Leap Motion Orientationがインストールされている

LeapMotionを接続してくださいと言われるので、LeapMotionを付属のケーブルで接続します。

LeapMotionを接続するように促される

接続したあと、何個か説明が出てきたあと綺麗な流線のグラフィックが現れます。このときLeapMotionの上部に手をかざすとその流線が変化します。

デモンストレーションが実行される

これが動けばLeapMotionのセットアップは終了です。

ofxLeapMotionを使ってみる

何はともあれ、githubからopenFrameworksのLeapMotion用のaddonであるofxLeapMotionをダウンロードしましょう。

https://github.com/ofTheo/ofxLeapMotion

[code lang=cpp]
#pragma once

#include "ofMain.h"
#include "ofxLeapMotion.h"

class testApp : public ofBaseApp{

public:
void setup();
void update();
void draw();

void keyPressed (int key);
void keyReleased(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);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
void exit();

ofxLeapMotion leap;
vector <ofxLeapMotionSimpleHand> hands;

vector <ofPoint> fingerPos; // 指の位置を格納する配列
vector<ofPoint> handPos; // 手のひらの位置を格納する配列
};
[/code]

[code lang=cpp]
#include "testApp.h"

//————————————————————–
void testApp::setup(){
ofSetFullscreen(true);
ofSetFrameRate(60);
ofSetVerticalSync(true);
ofBackground(0);

ofSetRectMode(OF_RECTMODE_CENTER);

leap.open(); //LeapMotionを開く
}

//————————————————————–
void testApp::update(){
hands = leap.getSimpleHands(); //手の形を取得

if( leap.isFrameNew() && hands.size() ){ //LeapMotionが新しい情報を取得して、手がひとつ以上あったとき
//配列を空に
fingerPos.clear();
handPos.clear();

// leap.setMappingX(a,b,c,d)は[a-b]のx座標を[c-d]に線形変換する関数
// leapから出力される値は[c-d]になる
leap.setMappingX(-230, 230, 0, ofGetWidth());
leap.setMappingY(90, 490, ofGetHeight(), 0);
leap.setMappingZ(-150, 150, -200, 200);

for(int i = 0; i < hands.size(); ++i){
handPos.push_back(hands[i].handPos); // 手の位置を取得
for(int j = 0; j < hands[i].fingers.size(); ++j){
fingerPos.push_back(hands[i].fingers[j].pos); // 指の位置を取得
}
}
}
leap.markFrameAsOld(); //これを忘れないように。
}

//————————————————————–
void testApp::draw(){
for (int i=0; i<fingerPos.size(); ++i) {
ofRect(fingerPos[i].x, fingerPos[i].y, 20,20); // 指の位置に小さい四角形を描画
}

for(int i=0; i<handPos.size(); ++i){
ofRect(handPos[i].x, handPos[i].y, 50, 50); // 手のひらの位置に大きい四角形を描画
}
}

//————————————————————–
void testApp::exit(){
leap.close();
}
[/code]

実行するとこんな感じで、ちゃんと指先と手のひらが認識されてます。
手と指先の位置

まとめ

KinectみたいにSDKインストールしたりなんだかんだで面倒なのかなーと思ってたら意外とあっさりでした。ただ、指先の細かい動きはさすがに取れないっぽいです。でも、手のひらの位置とかだけなら、かなり精度はいいので、今後何かアップデートとかで精度がよくなるかもしれません。

ジェスチャーを取ることもできるようなので、もうちょっと調べてみたいと思います。