動画からネコを抽出するためには
前回まででネコを撮影するスマホのアプリの基本コンセプト設計と、その中の画像処理部分を担うOpenCVをAndroidスマホアプリに使用して人の顔を抽出して枠を表示するところまでは来ました。


いよいよ、ネコを認識するためのカスタマイズとなります。
OpenCVの画像認識のシステムをごく簡単に説明すると、「認識させたい物の特徴はこんな感じだよ」というのを教えてあげると、その特徴を用いて合致した物を認識します。なので、人の顔を認識したければ人の顔の特徴、ネコの顔を認識したければネコの顔の特徴を教えてあげれば良いわけです。ちなみに、この特徴と呼んでる物は一般的には分類器と言います。
ところで、このネコの顔の特徴を教えてあげるにはネコの顔の分類器を作成するんですが、まぁこれがめんどくさい。ネコの分類器を作成するには、「これはネコの顔だよ」というサンプル画像と「これはネコの顔ではないよ」というサンプル画像をそれぞれ数千枚レベルで準備してあげないといけない。しかも、ネコの顔の方のサンプルは画像の中のネコの顔の位置を数えてメモらないといけないんですよ。
ネコの顔ではありませんが仕事で一度分類器を作成した事がありますけれども、控えめに言って地獄の作業です。正直ちょっとネコが嫌いになってしまうんじゃないかってくらいネコの画像と向き合わないといけない。
嫌だ、やりたくない、分類器作成作業やったらネコちょっと嫌いになる。
そうだ!世の中にはネコの分類器作ったことある人っているんじゃないの?そして公開してくれてる人もいらっしゃるんじゃないの?と淡い期待を抱きながら、Googleで検索・・・・・
早速ネコ画像でテスト!
OpenCVに付属のサンプルプログラム、openCVSamplefacedetectionで試してみます。
まず、openCVSamplefacedetection→src→main→res→rawに分類器をcascade_cat.xmlという名前で置きます。
そして、FdActivity.javaを以下のように1行だけ変更、これだけでネコを認識するようになっちゃう、ホントOpenCVって便利ですよね。
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { @Override public void onManagerConnected(int status) { switch (status) { case LoaderCallbackInterface.SUCCESS: { Log.i(TAG, "OpenCV loaded successfully"); // Load native library after(!) OpenCV initialization System.loadLibrary("detection_based_tracker"); try { // load cascade file from application resources //InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface); ここをコメントアウト InputStream is = getResources().openRawResource(R.raw.cascade_cat); //ここを追加。 File cascadeDir = getDir("cascade", Context.MODE_PRIVATE); mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface.xml"); FileOutputStream os = new FileOutputStream(mCascadeFile); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = is.read(buffer)) != -1) { os.write(buffer, 0, bytesRead); } is.close(); os.close(); mJavaDetector = new CascadeClassifier(mCascadeFile.getAbsolutePath()); if (mJavaDetector.empty()) { Log.e(TAG, "Failed to load cascade classifier"); mJavaDetector = null; } else Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath()); mNativeDetector = new DetectionBasedTracker(mCascadeFile.getAbsolutePath(), 0); cascadeDir.delete(); } catch (IOException e) { e.printStackTrace(); Log.e(TAG, "Failed to load cascade. Exception thrown: " + e); } mOpenCvCameraView.enableView(); } break; default: { super.onManagerConnected(status); } break; } } };
テスト結果
ネコを認識するようにはなったけど、処理がめちゃくちゃ重い。これは自分が持っているスマホがデバッグ用に買った廉価品だからなのか、それともそれではカバーできないレベルの重さなのか。あと、認識のアルゴリズムのパラメータを適切にすれば軽快になるのか、この辺を次の課題として今回はここでおしまい。
最後に認識された可愛いネコたちの画像をどうぞ。
このアプリに関する記事一覧はこちらから。

コメント