くらげ人間のパソコンカタカタメモ

くらげ人間は足がたくさんあるのでめっちゃ早くキーボードを打てるってわけ。

Android Studio(Java)でOpenCVを使う / Android StudioのC++サポート機能(JNI/Android NDK)でOpenCVを使う

なんやかんやあってAndroid上で画像処理をすることになったのでメモ。私はこれまで画像処理を少しやっててAndroidでやろうとした時の諸々です。
正直今更感はあるしここを見なくても調べたら色々出てくると思うのでおすすめ。参考にしたサイトは文中と最後に載せておきたいと思います。
Android Studioを入れてOpenCVを使いましょうという話。

環境

Android Studioのインストール

Download Android Studio and SDK tools  |  Android Developersから本体のダウンロード。リンク先のUSER GUIDEを押して左側のInstall Android Studioを押すとインストール方法が動画で出てくる。
PCスペックもあるんだろうけどDownloading Componentsのところは少し時間がかかったので気長に。

OpenCVのダウンロード

OpenCVAndroid用のもの(OpenCV for Android)があるのでそれをダウンロードする。今回はOpenCV 3.4.1を入れたいので、OpenCV 3.4.1 - OpenCV libraryのページに行って下の方にある[Download]から[Android pack]を選んでクリック。そのまま待っていれば自動でダウンロードが開始される。
f:id:kuragehuman:20181017001102p:plain

ダウンロードが終わったら、それを解凍して自分が使う場所に置いておく。私はCドライブ直下に置きました。

Android StudioOpenCVを使う

入れてきたAndroid StudioOpenCVを使ってみる。
エラーが出た時は大体下らへんをよく読めば良い、その辺に[Install ~~~]みたいに押せるところがあるのでそこをよく読めばなんとかなると思う。

新規プロジェクト作成

まずは普通にAndroid Studioを起動するとこんな画面が出るので[Start a new Android Studio project]を選んでプロジェクトの新規作成を行う。
f:id:kuragehuman:20181018003222p:plain

次の画面が出るので、Application nameは名前なので適当に付けて良い、Company domainは自分のドメイン名らしい。Google Playなどに公開しない場合は適当で良いっぽい(ちょっと理解が怪しいのでデフォルトのままが良いのかな)。公開する場合は調べてみてください。
今回の私のようにC++を使いたい場合は[Include C++ support]にチェックを入れるとよい。
f:id:kuragehuman:20181018003244p:plain

この画面では使いたいデバイスに合わせて設定する。使いたいデバイスバージョンについては、アンドロイド側で[設定]を開いて一番下までスクロールするとタブレット情報があると思う。今回は画像通り[API 25: Android 7.1.1]とした。
f:id:kuragehuman:20181018003309p:plain

次は[Empty Activity]のままで良いと思う。
f:id:kuragehuman:20181018003314p:plain

名前を変えたい場合は変える。
f:id:kuragehuman:20181018003326p:plain

最後にC++の設定をしてFinishをすると、プロジェクトが作成される。
f:id:kuragehuman:20181018003334p:plain

少し待っていると次のような画面になるのでデバイスを接続して実行(画面上部の緑色の再生ボタン)を押すと、接続されたAndroid上でサンプルアプリが実行されて画面上に「Hello~~~~」みたいなのが出る。
f:id:kuragehuman:20181018003350p:plain

プロジェクトが新規作成できた。良かったね。

C++にしたときに出るかもしれないエラー

NDKとCMakeを入れる必要がある(もしかしたらC++ supportにチェックを入れたら勝手にやってるかもしれないけど、私は容量不足で一回失敗して詰まってた)。
Android Studioツールバーにあるこのアイコンをクリック。もしくは[Tools] > [SDK Manager]を開く。
f:id:kuragehuman:20181018012443p:plain

そうしたら左のリストから[Appearance & Behavior] > [System Settings] > [Android SDK]と選んでいき、[SDK Tools]のタブを開くとこんな画面が出るので入れたいもののチェックボックスにチェックを入れる(今回はCMakeとNDK)。画像ではチェックがついてるけど、これはもう入っているから。
f:id:kuragehuman:20181018013041p:plain

チェックを入れてOKを押せば、インストール画面に移行するのでインストールして終わりです。

Android StudioOpenCVを使う(Java)

OpenCVAndroid Studioで使いたい。
ということを検索したら出てきたOpenCV for AndroidをAndroid Studioに導入するメモを参考にやってみた。バージョン的な問題か、最後の方に見知らぬエラーが出たのでそこは対処。

ライブラリのコピー

先ほどダウンロードして解凍しておいた[opencv-3.4.1-android-sdk]を開いて、[OpenCV-android-sdk] > [sdk] > [native]の中にある[libs]をコピーして、[(自分のプロジェクト)] > [app] > [src] > [main]の中に貼り付けて、そのフォルダ名を[jniLibs]に変更する。 この[jniLibs]はC++でやりたいときにもちょっと出てくる。

モジュールのインポート

OpenCVモジュールをインポートします。Android Studio上で[File] > [New] > [Import Module...]と進み、フォルダの参照から[opencv-3.4.1-android-sdk] > [OpenCV-android-sdk] > [sdk] > [java]を選択してOK。
f:id:kuragehuman:20181018005019p:plain

すると勝手にモジュール名がつくのでNext & Finish。
f:id:kuragehuman:20181018005121p:plain

エラーが出てくるとかもしれないけどとりあえず無視して、次に、[File] > [Project Structure...]からモジュールの設定を行う。
画面が開いたら左のリストから[app]を押して、[Dependencies]のタブを開いて右上の+マークから[3 Module dependency]を押してさっきインポートした名称のモジュールを選んでOKすると、設定されてAndroid Studioの左側に[openCVLibrary341]が出てくる。
f:id:kuragehuman:20181018005522p:plain f:id:kuragehuman:20181018005530p:plain

build.gradleの設定

SDKバージョンに関する設定をする。
[app]および[openCVLibrary341]の[build.gradle]を開いて(画像参照)、[OpenCVLibrary341]の[build.gradle]で決められている[compileSdkVersion][minSdkVersion][targetSdkVersion]を[app]で決められている値に合わせる([app]側がコピー元)。

AndroidManifestの修正

上記の参考文献には書かれていなかった問題で、Manifestファイルにエラーが出ることがあった。gradleを3.2.1にアップデートした時の問題?。
画像のようにエラーが表示されるので、[Open Manifest File]をクリック(もしくは左のリストから[openCVLibrary341] > [manifests]を開く)。

開いたファイルに書かれている下の一文が邪魔みたいなので削除してしまう。

<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" />

終わりです。
これでAndroid StudioOpenCVが使えると思います。JavaOpenCVが使いたいだけならここまでで大丈夫。

Android StudioOpenCVを使う(C++)

Android Studioの新規プロジェクト作成の時にチェックを入れていたC++ supportという機能は、Android Studio(Java)の中でC++で書かれたプログラムを呼び出したりできる機能で、Java Native Interface(JNI)っていうらしい(間違ってたら指摘してください)。
ここも検索して出てきたCMakeでAndroid向けのOpenCVを利用するを参考にしてやっている。手順が省けそうなところはちょっと省いた。

そのC++でプログラミングする中でもOpenCVを使いたい時にどうするかという話。今回ので言うと[app]の中の[cpp]の中にある[natib-lib.cpp]にあたる部分で使いたい場合。

include用のヘッダファイルをコピー

[opencv-3.4.1-android-sdk]を開いて、[OpenCV-android-sdk] > [sdk] > [native] > [jni] にある[include]というフォルダをまるまるコピーして、先ほど[(自分のプロジェクト)] > [app] > [src] > [main]に追加した[jniLibs]の中に張り付ける。

CMakeListsの設定

コピーしてきたヘッダファイルを使うために[app] > [CMakeLists.txt]を編集する。
f:id:kuragehuman:20181018010148p:plain

残念ながらいい感じに色分けができなかったので、自分のと見比べながら追加していってください。

# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
        native-lib

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        src/main/cpp/native-lib.cpp)

# OpenCV Library(3行追加)
add_library(opencv-lib SHARED IMPORTED)
include_directories(${pathToProject}/app/src/main/jniLibs/include)
set_target_properties(opencv-lib PROPERTIES IMPORTED_LOCATION ${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so)

(中略)

target_link_libraries( # Specifies the target library.
native-lib

opencv-lib    # (追加)

# Links the target library to the log library
# included in the NDK.
${log-lib} )
CMakeListsで使っているパスの変数の設定

だと思う。
[app]の[build.gradle]を編集する。(どこを編集するべきか書き忘れていた、2018/10/17 19:02 追記)

android {
    (略)
    defaultConfig {
        (略)
        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11"
                arguments "-DpathToProject:STRING=" + project.rootProject.getProjectDir().absolutePath    ←追加
            }
        }
    }

これでOpenCVC++でも使えるようになって、cv::Matとか使える。これで前使ってたプログラムの移植もしやすくなった(と思う)。