OpenCVのサンプルを静的にAndroid Studioでビルドしたときのメモ

OpenCV for Android SDKに入っているsamples/face-detectionをStatic InitializationでAndroid Studioを使ってビルドするまでのメモ。
使ったものは、

プロジェクトを新規作成

Android Studioで空のプロジェクトを作成。
/app/src/main/に/samples/face-detection/*をコピー。
ただし、java/以下には既存のディレクトリを残して、src/からファイルだけをコピーする。
今回はパッケージ名をcom.sample.appとするので、java/com/sample/app/にsrc/org/opencv/samples/facedetect/*をコピー。
コピーした.javaファイルはそれぞれ

    package com.example.app;

と変更しておく。

また、AndroidManifest.xmlも該当する箇所を

    package="com.tanitter.face_detection.app"

と変更しておく。

(でもこんなことせず単にインポートしたらいいと思う。)

SDKを配置

/app/src/main/にjniLibsという名前のディレクトリを作る。
ここにはAPKに含める.soを入れる。
まず、/sdk/native/libs/*をコピーして入れておく。

/librariesを作って、その下に/sdk/java/をopencv/とリネームしてコピー。
/libraries/opencv/build.gradleを作って、中身を次のようにする。

apply plugin: 'android-library'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
    }
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.3"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 2480
        versionName "2.4.8"
    }

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            res.srcDirs = ['res']
            aidl.srcDirs = ['src']
        }
    }
}
<||

/settings.gradleを
>||
include ':app', ':libraries:opencv'

に変更。
/app/build.gradleに

dependencies {
    ...
    compile project(':libraries:opencv')
}

を追加。

また、/app/に/sdkをコピー。
こちらは、JNIをビルドするときのため。

JNIの設定

/app/src/main/jni/Android.mkを編集して

OPENCV_LIB_TYPE:=STATIC

を追加。

ただしデフォルトでは、Android Studio(gradle)はここで設定したAndroid.mkを見ないでJNIをビルドしてしまうので、build.gradleを編集して

android {
    ...
    sourceSets.main.jni.srcDirs = []
}

のようにして、gradleではJNIがビルドされないようにする。

JNIの関数名を編集

(パッケージ名をサンプルと同じにしていれば、この作業は必要ない。)
/app/src/main/jni/DectationBasedTracker_jni.(cpp|h)において、"org_opencv_samples_facedetect"を"com_example_app"で置換する。

初期化方法を変更

サンプルコードは、そのままだとOpenCV Managerを利用しようとするので、FdActivity.javaを編集して

    static {
        OpenCVLoader.initDebug();
    }

をFdActivityクラスに追加する。
また、onResume()を

    @Override
    public void onResume()
    {
        super.onResume();
        //OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
        mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    }

のようにする。

ビルド

まずは、JNIを手動でビルドする。
そのために、/app/src/main/に cd して /ndk-build を実行する。
出来上がったlibs/*はjniLibs/にコピーする。

そして、/gradlew build すれば、動作するAPKができるはず。