BlankTar

about | blog | works | photo

画像処理のハローワールド的存在(?)である笑い男をopenFrameworksofxCvでやってみました。
pythonとかWebとかでも笑い男書いたし、何かもう笑い男ばっかりやっている気がします。

openFrameworksのofxCvで作った笑い男。

さて、ソースコード。

#include <ofMain.h>
#include <ofxCv.h>


class ofApp : public ofBaseApp {
private:
	ofVideoGrabber cam;
	ofxCv::ObjectFinder finder;
	ofImage laughingMan;

public:
	void setup() override {
		cam.setup(640, 480);

		finder.setup("haarcascade_frontalface_default.xml");
		finder.setPreset(ofxCv::ObjectFinder::Fast);

		laughingMan.loadImage("laughing_man.png");
	}

	void update() override {
		cam.update();

		if(cam.isFrameNew()){
			finder.update(cam);
		}
	}

	void draw() override {
		cam.draw(0, 0);

		for(int i=0; i<finder.size(); i++){
			ofRectangle rect = finder.getObjectSmoothed(i);
			laughingMan.draw(rect);
		}
	}
};


int main() {
	ofSetupOpenGL(640, 480, OF_WINDOW);

	ofRunApp(new ofApp());
}

ofxCv::ObjectFinderで顔を検出して、見付かった矩形領域に画像を重ねているだけです。実にシンプル。
OpenCVに同梱されているhaarcascade_frontalface_default.xmlbin/dada以下にコピーして、それからbin/data/laughing_man.pngなる画像を用意してからコンパイルしてください。

検出の精度を決めるsetPresetの引数にはFastの他にAccurateSensitiveなんてのがあるようです。ここを変えると精度やら速度やらが変わるはず。
Sensitiveにすると面白いほど誤検出します。Accurateはそこそこ。Fastが一番バランスが良い、ような気がします。

getObjectSmoothedなるメソッドで発見した顔の座標を取得していますが、getObjectというメソッドを使うことも出来ます。
細かい意味は分かっていないのですが、getObjectを使うと座標が安定しないのに対して、getObjectSmoothedは平準化してくれているっぽい。
getObjectSmoothedの代わりにgetObjectを使うと、笑い男がの位置ががくがくと飛ぶようになります。

実に手軽に笑い男が出来てとても良い感じですね。
アルファチャンネルとか自分で考えなくて良いのが素晴しい。

笑い男の画像: 笑い男パーツ: マイペースなブログ

openFrameworksとOpenCVを組み合せると何か色々出来そうな気がするので、挑戦してみました。
標準で同梱されているofxOpenCvってやつを試したのですが、何か使いづらいので、ofxCvに鞍替え。
まとまったドキュメントが見合たらないのがかなしいのですが、インターフェースは生のOpenCVと似ているのでC/C++向けのOpenCV経験者なら迷うことは無いと思います。

で。openFrameworksの機能でwebカメラの映像を取得して、ofxCvの機能で加工してみたいと思います。
やりたいのはこんな感じのことです。
生の画像とぼかした画像、グレースケール、あと輪郭の画像をまとめたやつ。
左上が生の映像、右上がガウシアンブラーをかけたやつ、左下がグレースケール、右下がCanny法で作った輪郭の映像です。

ソースコードはこんな感じ。

#include <ofMain.h>
#include <ofxCv.h>


class ofApp : public ofBaseApp {
private:
	ofVideoGrabber cam;
	ofImage blur, gray, edge;

public:
	void setup() override {
		cam.setup(320, 240);
	}

	void update() override {
		cam.update();

		if(cam.isFrameNew()){
			ofxCv::GaussianBlur(cam, blur, 16);
			ofxCv::convertColor(cam, gray, CV_RGB2GRAY);
			ofxCv::Canny(gray, edge, 50, 150);

			gray.update();
			edge.update();
			blur.update();
		}
	}

	void draw() override {
		cam.draw(0, 0);
		blur.draw(320, 0);

		gray.draw(0, 240);
		edge.draw(320, 240);
	}
};


int main() {
	ofSetupOpenGL(640, 480, OF_WINDOW);

	ofRunApp(new ofApp());
}

ofVideoGrabberってクラスでwebカメラの映像を取得しています。
こいつは動画ファイルを読み込む事も出来るらしいので、リアルタイムの映像でなくてもいけます。

ofxCvの関数はofxCvってそのまんまの名前空間の中に入っています。分かりやすい。
OpenCVの関数はそのままの名前、ほぼそのままの呼び出し方で使えます。cvtColorconvertColorになっていたり、微妙に違うこともあるみたいです?

処理した後の画像はupdate()メソッドを呼び出してやらないと、draw()してもきちんと表示されないので注意が必要です。

だいたいそんなもんで。説明するまでもない感じが素敵ですね。

先ほどopenFrameworksをgentooにセットアップしました。
併せてQt Creatorもセットアップしたのですが、なんだかよく分かりません。そもそも私にはIDEというやつがよく分かりません。

というわけで、エディタとmakeコマンドだけで開発するための設定を行ないました。

設定する

.bashrcを開いて、いくつか環境変数の設定を行ないます。

export OF_ROOT=/path/to/openFrameworks/
export PG_OF_PATH=$OF_ROOT

OF_ROOTはMakefileの中で参照しているので必要なもの、PG_OF_PATHはプロジェクトジェネレーターが使う変数です。
どっちも同じ内容で、openFrameworksをインストールしたパスを設定します。

次に、コマンドライン用のプロジェクトジェネレーターをコンパイルします。
openFrameworksのインストールディレクトリに行って、以下のコマンドを実行してください。

$ cd apps/projectGenerator/commandLine/
$ make

これで完了です。
bin/projectGeneratorという名前で実行ファイルが生成されていますので、パスの通った場所にコピーするか、パスを通してください。

プロジェクトを作る

プロジェクトジェネレーターをコンパイルしたら、あとはそいつを実行するだけでプロジェクトを作れます。

$ projectGenerator /path/to/project

こんな感じ。
/path/to/projectのところは何でも構いません。相対パスも行けます。
ちなみに引数無しで実行するとヘルプが出ます。色々オプションがあるようです。

開発する

ジェネレーターで作ったディレクトリに移動すると、必要なものは全て揃った状態になっています。素敵。
エディタでsrc/以下にあるソースコードを修正して、makeでコンパイルしてください。bin/以下に実行ファイルが出来ます。

プロジェクト名.qbsのような名前のファイルがあって、その中にソースコードの一覧が記述されています。
このファイルはqbsというQt用のビルドツールのための設定ファイルらしいのですが、makeでコンパイルするなら必要無いようです。
なので、ソースコード一覧を修正する必要はありません。

とはいえ必要無いものがあるのもきもちわるいので、確実に不要と言えるなら消してしまっても良いかもしれません。
消しても何の問題もなくコンパイル出来ました。

[ << ] [ 8 ] [ 10 ] [ 12 ] [ >> ]