ofの流れで今回はofxFaceTrackerというアドオンの紹介と、とても面白い応用例をPi2で実行させてみます。ところでofxFaceTrackerをご存知ですか?画像の顔を立体として認識することができるofの中でもメジャーなアドオンの一つです。
Openframeworksの世界で、日本で有名な多摩美術大学の田所先生もofxFaceTrackerを取り上げていて、今回実行するプログラムのソースリストを公開しています。日本でもこのような方がいらっしゃることをとても誇りに思います。
YouTubeではofxFaceTrackerを使った画像をよく見かけるのですが、どのようにソフトを作ればいいのかほとんど公開されていません。田所先生はこのアドオンを利用して俳優や絵画の顔写真を自分の顔に置き換えて表示させるサンプルのソースリストを作りました。これがとても面白い!!
ただし、Pi2ではソースの内容を一部変更しなければならないことや、関連アドオンのインストールに成功しなければ動いてくれません。今回はこの辺りをメモします。
Pi2でofのプロジェクトを作成する
今までの例では、アドオンをExampleから直接ビルドしていましたが、ofのPI版での標準的なプロジェクトの作成方法を説明します。
まずどこに新規プロジェクトを作成するかですが、自分のofフォルダ/apps/myApps の中にあるemptyExampleフォルダを同じ階層にコピーするだけです。
自分のofフォルダ以下(of以下4階層目)この階層に合わせればフォルダ名称に関係なくビルド可能です。
このフォルダには srcフォルダとmakeファイル、プロジェクトによってはbinフォルダが入っています。
src以下には、通常3つのファイルすなわちmain.cpp、 ofApp.h、 ofApp.cpp (プログラム本体 ofAppがtestAppと変更されている場合あり)が最低必要です。
bin以下には、プログラム中で使われるデータが入っています。さらにビルドした実行可能ファイルが保存されます。
標準では作成したプロジェクトフォルダ直下で make とキーボードから打ち込めばビルド開始されます。(X Window Systemのファイルマネージャーで該当フォルダを開き「ツール->現在のフォルダを端末で開く」を選択して表示された端末から make する)
アドオンを使う場合はこのフォルダに addons.make というファイルを作りますが、今回の場合は
ofxCv
ofxOpenCv
ofxFaceTracker
と記入して保存します。addons.makeのファイル内容はインストールしたアドオンのExampleの中身を見れば確認できます。 ofxCvアドオンを使う場合は、ofxOpenCvを必ず記入します。
ofxCVアドオンの実行には、Pi2でインストールするには標準アドオンであるofxOpenCvの変更が必要なので、次に説明します。
ofxFaceTrackerをインストールする
ofのホームページからofxFaceTrackerをダウンロード。
kylemcdonald/ofxFaceTracker · GitHub
このアドンにに入っているexampleをビルドするときは、ダウンロード先のこのコメントに英語で書いてあるように、付属のフォルダ(model)をコピーしないと正常にビルドできません。
ofxCVをインストールする
ofのホームページからダウンロード。kylemcdonald/ofxCv · GitHub
※2015/11/20 現在Pi2 に、Raspbian最新版、Openframeworks0.9.0 へのバージョンアップ、ofxCVの最新版をインストールすれば、次の操作は必要ありません。
ofxFaceTrackerに必要なofの標準アドオンofxOpenCvは、Pi2ではビルドエラーとなるので、http://files.fieldofview.com/temp/ofxopencv_armv7_libs.tar.gz
をダウンロード。そして 自分のofフォルダ/addons/ofxOpenCVの同じ位置に拡張子がaのファイルを全部重ね書きします。
サンプルをインストールして、ソースを一部変更する
田所先生のサンプルはここからインストールできます。
tado/openFrameworks_examples_v0073 · GitHub
の71番が該当サンプルです。srcとbin/data以下を自分のプロジェクトに追加し、上記のaddons.makeを作成します。(bin/dataとは、新しくbinフォルダを作成してbin/data以下をコピー)このサンプルは少し古いのでsrc以下のファイルはtestApp.cpp、testApp.h、main.cppとなっていますので、コピーする前に、emptyExampleにもともと入っているofApp.h、ofApp.cpp、main.cppを消しておきます。
ただしこのままでは正常に動かないので、
ofxFaceTrackerをiOSで使用する方法 - Use At Your Own Risk
を応用したらなんとか動きました。ただしこれはios用なのでさらに少し変えます。
-
main.cppの変更
ofのバージョンが古いので以下の2行をコメントアウトする
-----------------------------------------------------
#include "testApp.h"
//#include "ofAppGlutWindow.h"
int main() {
//ofAppGlutWindow window;
ofSetupOpenGL(320, 240, OF_WINDOW);
ofRunApp(new testApp());
}
-----------------------------------------------------
-
testApp.hの変更
#include "ofxOpenCv.h" を追加
-----------------------------------------------------
#pragma once
#include "ofMain.h"
#include "ofxOpenCv.h"
#include "ofxCv.h"
#include "ofxFaceTracker.h"
class testApp : public ofBaseApp {
public:
void setup();
void update();
void draw();
void keyPressed(int key);
ofVideoGrabber cam;
ofxFaceTracker tracker;
ofxFaceTracker imgTracker;
ofImage faceImage;
ofEasyCam easyCam;
};
-----------------------------------------------------
-
test.cppの変更
スピードを上げるために画面の大きさを半分にしました。
サンプルは、bin以下にテスト画像が含まれていますので、ファイル名は変更可能。
このままでは、カメラ画像が顔認識するまでフレームレイトが極端に遅くなるのでtracker.setRescale(0.5); (田所先生の他の記事にヒントが書いてありました)
を追加。ここの数値を変えると認識スピードが変わります。ただしあまり小さくすると認識率が悪くなります。
さらにdraw()の中身を以下の様に一部追加してください。
-----------------------------------------------------
11行目 cam.initGrabber(320, 240);
14行目 faceImage.allocate(320, 240, OF_IMAGE_COLOR);
faceImage.loadImage("kenshiro.jpg");
.......
.......
void testApp::update() {
//カメラ更新
cam.update();
if(cam.isFrameNew()) {
//フェイストラッカーの更新
//imgTracker.update(toCv(faceImage));
tracker.setRescale(0.5);
tracker.update(toCv(cam));
}
}
void testApp::draw() の中身を一部追加、変更
.......
.......
ofMesh imgMesh = imgTracker.getObjectMesh();
/* texCoordを正規化 */
for(int i=0; i< objectMesh .getTexCoords().size(); i++) {
ofVec2f &texCoord = imgMesh .getTexCoords()[i];
texCoord.x /=faceImage.getWidth();
texCoord.y /=faceImage.getHeight();
}
//静止画のメッシュの頂点情報を、カメラから生成したメッシュのものに変換
//つまり現在の顔の表情を、静止画のメッシュに適用
for (int i = 0; i < objectMesh.getNumVertices(); i++) {
imgMesh.setVertex(i, objectMesh.getVertex(i));
}
//画面の3Dのパースをなしに
ofSetupScreenOrtho(320, 240, OF_ORIENTATION_DEFAULT, true, -1000, 1000);
.......
.......
-----------------------------------------------------
※2015/11/20 現在Pi2 に、Raspbian最新版、Openframeworks0.9.0 へのバージョンアップ、ofxCVの最新版をインストールした場合上記 ofSetupScreenOrtho の行でコンパイルエラーとなるので、一応コメントアウトしてください。
以上の変更で、多少のワーニングが出ますが、とりあえずビルドはできます。
ビルド成功するまで2日ぐらいかかってしまいました。
実行してみる
周辺が明るくないとカメラ画像の顔を認識しにくい欠点がありますが、サンプル動画を貼り付けておきます。どうでしょうか?
pi3でも実行してみました。私の顔の向きや口の動き等バッチリ追従しているのが確認できると思います、640X320でもまずまずのスピード!!(2016/5/30)
今回のサンプルソフトは、iPhone6でも実行できましたので次の機会に説明しますが、CPUのスピードがPi2より早いので、かなりスムーズです。
Pi2に関してはこの辺でネタ切れ。次からはIntel Edisonネタです。こちらの方もかなり面白いことを沢山実験していますので、色々応用できますぞ!!
次回は Edison+Henry基板でSimpleCVを使って動画配信する でーす。
intel Edisonで色のついたボールを認識してその動画をリアルタイムで確認できる上に、WebでEdisonを操作できるなんて信じられます?。できました!!!