LoginSignup
12
14

More than 5 years have passed since last update.

CV系のライブラリだと、OpenCVが圧倒的にシェア率が高く、使いやすいが、最近「CCV」というライブラリを使う機会があったので、紹介したいと思います。

CCVとは

C/C++用のコンピュータービジョン系のライブラリです。
http://libccv.org/

OpenCVが1999年から使われ始めたのに対し、CCVは2010年に誕生したそうです。

特徴として、
- マルチプラットフォームで動く。
- 最先端の画像認識アルゴリズムが使われている。
- インタフェースがクリーンで分かりやすい。
みたいな感じです。

  • Track Learn Detect(物体の追跡認識)
  • Stroke Width Transform(画像からの文字抽出)
  • Conv Net(畳み込みニューラルネットワーク)
  • Integral Channel Features(輝度、色、スペクトラムなど多くの情報から認識を行うアルゴリズム)

など、まあまあ近年の論文で発表されて、中にはOpenCVにはデフォルトでは実装されていないアルゴリズムが、きれいな関数で実装されています。
僕は使ってないのでわからないのですが、HTTP用のREST-ful APIも用意されているみたいで、サービスでの応用もやりやすそうです。(ライセンスがBSDなのでご注意ください。)

学習モデルは、使用するときに必ずSQLite形式のデータベースファイルの読み込み処理が必要になります。
上で挙げた機能や、顔認識、ImageNetやAlexNet用のモデルはSampleからダウンロードできます。
自分でモデルを実装したい場合は、ここを参考にしてください。
ここでは、デフォルトで提供されているモデルを使って、応用の仕方を説明していきます。

みんな大好きopenFrameworksで使ってみる

なんとKyle Mcdonaldさんが、oFのAddonを作ってくれていました。
https://github.com/kylemcdonald/ofxCcv

今回はopenFrameworksでこのアドオンを使って、手軽に試してみます。

歩行者認識(Integral Channel Featuresを使った実装方法)

classifyPedestrians()を使用します。
認識するためのコードは以下のたったこれだけです。

main.cpp
#include "ofMain.h"
#include "ofxCcv.h"

class ofApp : public ofBaseApp {
public:
    ofxCcv ccv;
    vector<ofRectangle> results;
    ofVideoPlayer player;

    void setup() {
        ccv.setupPedestrians("pedestrian.icf");
        player.load("movie.mp4");
        player.play();
    }
    void update() {
        player.update();
        if(player.isFrameNew()) {
            results = ccv.classifyPedestrians(player);
        }
    }
    void draw() {
        player.draw(0, 0);
        ofSetWindowTitle(ofToString(ofGetFrameRate()));
        ofPushStyle();
        ofNoFill();
        ofSetLineWidth(2);
        for(int i = 0; i < results.size(); i++) {
            ofDrawRectangle(results[i].x,results[i].y,results[i].getWidth(),results[i].getHeight());
            ofDrawBitmapStringHighlight(ofToString(i), results[i].getPosition() + ofPoint(-5,-5));
        }
        ofPopStyle();
    }
};

int main() {
    ofSetupOpenGL(1200, 800, OF_WINDOW);
    ofRunApp(new ofApp());

}

すると、
スクリーンショット 2016-12-22 12.18.01.png
ちゃんと取れてますね。めちゃ手軽です。
pedestrian.icfはモデルデータです。ofxCcvのサンプルの中に落ちています。
ただし、本格的に使う場合は、ccv.classifyPedestrians()はスレッドを分けて使う必要がありそうです。(実行するときにフレームが1~2まで落ちてしまう。)

顔認識

classifyFace()を使用します。
これもコードが以下のようにとても少なくすみます。

main.cpp
#include "ofMain.h"
#include "ofxCcv.h"

class ofApp : public ofBaseApp {
public:
    ofxCcv ccv;

    vector<ofRectangle> results;
    ofImage image;

    void setup() {
        ccv.setupFace("face.sqlite3");
        image.load("image.jpg");
    }
    void update() {
        if(ofGetKeyPressed()) {
            results = ccv.classifyFace(image);
        }
    }
    void draw() {
        image.draw(0, 0);

        ofPushStyle();
        ofNoFill();
        ofSetLineWidth(2);
        ofPushStyle();
        ofSetColor(0, 0, 255);
        for(int i = 0; i < results.size(); i++) {
            ofDrawRectangle(results[i]);
            ofDrawBitmapStringHighlight(ofToString(i), results[i].getPosition() + ofPoint(-5,-5));
        }
        ofPopStyle();
        ofPopStyle();

        ofDrawBitmapStringHighlight("press any key to detect", 10,20);
    }
};

int main() {
    ofSetupOpenGL(1140, 641, OF_WINDOW);
    ofRunApp(new ofApp());

}

スクリーンショット 2016-12-22 14.01.27.png
後ろの人は鼻と口が隠れているので取れていないですが、他の人はちゃんと取れています。

畳みこみニューラルネット

これは、少々コードが多くなるので、処理の根幹の部分だけ書きます。
ofxCcvの中に、example-viewerというプロジェクトがあり、そのコードで説明していきます。

ofxCcv ccv;  //ofxCcvのインスタンス

ccv.setup("image-net-2012.sqlite3");
/*
CNNのモデルの読み込み
*/

ccv.encode(image, ccv.numLayers());
/*
画像を入力し、認識情報を更新する。
- image: ofPixels(入力画像)
*/

ccv.getFeatureMaps(layer_num)
/*
指定した番号のレイヤー情報を、FeatureMapとして取得する。
- layer_num: int(レイヤーの番号)
*/

// Feature Map
class FeatureMap {
public:
    vector<float> acts;
    int rows;
    int cols;
    float max;
    void getImage(ofImage & img, bool autoBrighten=true);
};

スクリーンショット 2016-12-22 16.03.58.png

こういう感じで、ネットワーク内での畳みこみ画像を取得し、表示することもできます。
自分でモデルを作るのはかなりしんどいですが、IamgeNetなどの既存のモデルを動かすだけなら、実質
ccv.encode(image, ccv.numLayers())
だけで動きます。

その他

ml4a-ofxというプロジェクトがあり、ofxCcvのサンプルが使いやすいようにまとめられています。

雑感

既存の認識処理モデルを動かすのは、とてもシンプルに実装できて好きでした。
CaffeやTensorflowで作ったモデルを.sqlite3に直して、Ccvで実行するみたいなことができるといいなと思いました。
時間のあるときに、文字抽出とhttpAPIのインターフェースをofxCcvに実装しようと思います

12
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
14