今見てくれてる人の数

ホンキートンク・スーダラブルース

ゆるコラム、oF、邦ロックや歌謡曲、小説の感想。ドラクエ、JavaScript、ドラゴンボール超など。湘南あたりを転がってる石コロのゆるゆる生きてく超雑多な軌跡です。

【openFrameworks 冒険記14】ofxOpenCv で映像から目を検出して、画像をはめる

こんにちは、ちゃんいーです。

f:id:sudara_bluse:20171120125115p:plain

www.sudara-bluse.tokyo

前回、ofxOpenCvでカスケード分類器というのを使って正面顔を検出しました。

今回は目標の笑顔検知だ!と意気揚々と、こちらからhaarcascade_smile.xml(スマイル)をダウンロードして  finder.setup("haarcascade_smile.xml");   実行!

github.com

 

誤検知?の嵐....

openCVの神よ、、、なぜだ!?

部屋に笑顔の幽霊が溢れているのか???w

 

f:id:sudara_bluse:20171120115430p:plain

 

2017/11/22 追記

笑顔検知はofxFaceTrackerで後日リベンジすることにしました。

 

うーん精度が悪いのでしょか、僕のプログラムが悪いのでしょか。

謎なので一旦見送って、目に画像をはめるというのをやって見ようと思いました。

 

↓Haar-like特徴分類器一覧。

qiita.com

 

ofxOpenCv で映像から目を検出して、画像をはめる 

完成動画はこちら

 

 

ちらほら誤検知もありますがちゃんと目を検知してます。

ただ謎なのが、 haarcascade_righteye_2splits.xml

右目のみ検知のはずだったのですが、両目検知されてます笑

精度の問題か?これで良いのかな?ひとまずいいか。
後日確認しよう

 

実装方法(前回との差分)

f:id:sudara_bluse:20171120124142p:plain

 

ofApp.hで

ofImage eye; 目の画像を定義

 

ofApp.cppで

setup()

finder.setup("haarcascade_righteye_2splits.xml");  // 右目検知の検分機セット

eye.load("eye.png"); 目の画像を読み込み。

 

draw()

eye.draw(faceBox.x, faceBox.y +5);

で目の画像を描画(+5は座標に+5して位置を調整しています。)

 

 

コード

ofApp.h
#pragma once

#include "ofMain.h"
#include "ofxOpenCv.h"

class ofApp : 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 mouseEntered(int x, int y);
        void mouseExited(int x, int y);
        void windowResized(int w, int h);
        void dragEvent(ofDragInfo dragInfo);
        void gotMessage(ofMessage msg);

    // カメラ
    ofVideoGrabber cam;

    // カメラ入力画像
    ofxCvColorImage colorImg;
    // カメラ入力グレースケールの画像
    ofxCvGrayscaleImage grayImg;

    // サイズ定義
    const int W =  640;
    const int H = 480;

    // 顔検出器
    ofxCvHaarFinder finder;

    // 目の画像
    ofImage eye;

};

ofApp.cpp
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

    // 背景を黒に
    ofBackground(0, 0, 0);
    // カメラからの取り込み
    cam.initGrabber(W, H);
    // それぞれを処理するメモリ領域を確保   allocate(割り当てる)
    colorImg.allocate(W, H);
    grayImg.allocate(W, H);

    // 顔検出 検分器の読み込み;
    finder.setup("haarcascade_righteye_2splits.xml");  // 右目検知の検分機
    finder.findHaarObjects(grayImg);

    eye.load("eye.png");


}

//--------------------------------------------------------------
void ofApp::update(){

    // カメラの更新
    cam.update();

    // 一個一個のピクセルデータをカラーイメージにほりこんでる
    colorImg.setFromPixels(cam.getPixels().getData(), W, H);

    // グレースケールイメージにカラーデータを入れる
    grayImg = colorImg;

    // グレースケールかrオブジェクトを検知
    finder.findHaarObjects(grayImg);

}

//--------------------------------------------------------------
void ofApp::draw(){

    // 映像出力
    ofSetColor(255,255,255);
    colorImg.draw(0, 0, W, H);

    // 検出した目それぞれにアクセス
    for(int i = 0; i < finder.blobs.size(); i++) {
        //  目を検知
        ofRectangle eyeBox = finder.blobs[i].boundingRect;
        eye.draw(eyeBox.x, eyeBox.y +5);
    }


}

 

うーん笑顔検知はどうなるのやら。難航中。

原因を特定したい!

ofxBox2Dもやるかもです。