AndroidStudio で OpenCV をインポートする
の続きです。
概要
Android 用 OpenCV には、
8個のサンプルが同封されている。
そのうち face-detection について、解説する。
face-detection
顔検出機能の最もシンプルなサンプルです。
2つの実行モードがある。
- Java APIを使う
- Native API を使う
どちらも、カスケード型分類器 を使用する。
Java API でも、Google Nexus Oneデバイスでほぼリアルタイムのパフォーマンスを表示できる。
メニューは2通りある。
- 顔のサイズを選択
- Java / Native Detector の切り替え
カスケード型分類器 (Cascade Classifier)
特徴分類ファイル (Classifier File) を利用したオブジェクト検出器です。
機械学習のCNN(Convolutional Neural Networks)に比べ、
検出精度は劣るが演算は高速です。
-
[opencv : カスケード型分類器
Haar Feature-based Cascade Classifier]
(http://opencv.jp/opencv-2svn/c/objdetect_cascade_classification.html) -
Whats the Difference Between Haar-Feature Classifiers and Convolutional Neural Networks
特徴分類ファイル (Classifier File)
カスケード型分類器 のための特徴を記述した XML ファイルです。
sdk/etc/ ディレクトリに2種類の特徴分類ファイルが用意されている。
- haarcascades ディレクトリ
haar-like 特徴で学習した特徴分類ファイル - lbpcascades ディレクトリ
Local Binary Patterns特徴で学習した特徴分類ファイル
lbpcascades ディレクトリに下記のファイルが用意されている。
- lbpcascade_frontalface.xml (正面 顔)
- lbpcascade_frontalface_improved.xml (正面 顔)
- lbpcascade_profileface.xml (右向き顔)
- lbpcascade_frontalcatface.xml(猫の正面顔)
- lbpcascade_silverware.xml (銀製食器)
特徴分類ファイルは、機械学習により作成することができる。
アプリを作成する
まず、下記の記事をお読みください。
下記を参考にした。
(1) 新規のプロジェクトを作成する
File -> New -> New Project -> Empty Activity
(2) OpenCV の Android SDK をインポートする
File -> New -> Import Module
(3) 依存関係を設定する
File -> Project Structure
(4) opencv/build.gradle を修正する
(5) AndroidManifest にカメラのアクセス許可を追加する。
(6) レイアウトファイルに、JavaCamera2View を配置する。
(7) MainActivity.java を作成する。
samples/f/Users/ohwada/Desktop/opencvーandroid_face-detection.txtace-detection/src/org/opencv/samples/tutorial2/FdActivity.javaを
app/src/main にコピーして、
MainActivity.java にリネームする。
(8) DetectionBasedTracker.java を作成する。
samples/face-detection/src/org/opencv/samples/tutorial2/DetectionBasedTracker.java を
app/src/main にコピーする。
(9) 特徴分類ファイルを配置する
sdk/etc/lbpcascades/lbpcascade_frontalface.xml を
app/src/main/res/raw にコピーする。
(10) native コードを作成する。
samples/face-detection/jni ディレクトリを
app/src/main にコピーして、
cpp にリネームする。
プロジェクトのファイル構成に合わせて変更する。
/**
* org_opencv_samples_facedetect を
* jp_ohwada_android_opencv48 に変更する
*/
JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject
(JNIEnv * jenv, jclass, jstring jFileName, jint faceSize)
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject
(JNIEnv * jenv, jclass, jlong thiz)
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart
(JNIEnv * jenv, jclass, jlong thiz)
JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop
(JNIEnv * jenv, jclass, jlong thiz)
(11) app/build.gradleを変更する
defaultConfig {
ndk {
abiFilters 'armeabi-v7a'
}
externalNativeBuild {
cmake {
arguments "-DOpenCV_DIR=" + project(':opencv').projectDir + "/native/jni",
"-DANDROID_TOOLCHAIN=clang",
"-DANDROID_STL=c++_shared"
targets "detection_based_tracker"
}
buildTypes {
externalNativeBuild {
cmake {
// 変更する
// path 'jni/CMakeLists.txt'
path 'src/main/cpp/CMakeLists.txt'
}
(12) cmake を修正する
(13) Makeする
Build -> Make Projec
アプリ の処理の流れ
(1) アプリが起動すると、
CameraActivity#onStart が呼ばれる。
Activity#requestPermissions を実行して、
カメラのアクセス許可を要求する。
(2) Activity#onResume が呼ばれる。
setupDetector() にて、
res/rawフォルダーから 特徴分類ファイル lbpcascade_frontalface.xml が読み込まれ、
アプリごとのファイル領域にコピーされる。
コピーした特徴分類ファイルのファイルパスを指定して
CascadeClassifier が生成される
(3) Activity#onCameraFrame が呼ばれる。
CascadeClassifier#detect にて、顔検出する。
検出した顔の位置を示すMatOfRectが得られる。
Imgproc#rectangle にて、検出した顔の位置に四角形を描画する。
opencv : Class CascadeClassifier
アプリを実行する
下記の3つが同封されていることが確認できる。
Native API を使うモードも試してみたが、
Java APIと目立った差がなかった。
Native API を使うメリットがよくわからん。
サンプルコードをgithub に公開した。
https://github.com/ohwada/Android_Samples/tree/master/Opencv49
おまけ : 猫の顔を検出する
特徴分類ファイルに、
haarcascade_frontalcatface.xml を使用する
サンプルコードはこちら
https://github.com/ohwada/Android_Samples/tree/master/Opencv51
おまけ : 特徴分類ファイルを自作する
特徴分類ファイルは機械学習により作成できます。
実践例