ofxCvで笑い男をやってみた
画像処理のハローワールド的存在(?)である笑い男をopenFrameworksのofxCvでやってみました。 pythonとかWebとかでも笑い男書いたし、何かもう笑い男ばっかりやっている気がします。
さて、ソースコード。
#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.xmlをbin/dada以下にコピーして、それからbin/data/laughing_man.pngなる画像を用意してからコンパイルしてください。
検出の精度を決めるsetPreset
の引数にはFast
の他にAccurate
やSensitive
なんてのがあるようです。ここを変えると精度やら速度やらが変わるはず。
Sensitiveにすると面白いほど誤検出します。Accurateはそこそこ。Fastが一番バランスが良い、ような気がします。
getObjectSmoothed
なるメソッドで発見した顔の座標を取得していますが、getObject
というメソッドを使うことも出来ます。
細かい意味は分かっていないのですが、getObjectを使うと座標が安定しないのに対して、getObjectSmoothedは平準化してくれているっぽい。
getObjectSmoothedの代わりにgetObjectを使うと、笑い男がの位置ががくがくと飛ぶようになります。
実に手軽に笑い男が出来てとても良い感じですね。 アルファチャンネルとか自分で考えなくて良いのが素晴しい。
笑い男の画像: 笑い男パーツ: マイペースなブログ