AndroidStudio で OpenCV をインポートする

### OpenCV

OpenCV( Open Source Computer Vision Library) は、
オープンソースの画像処理のライブラリである。

開発言語は、CPUの特性を活かすためにC/C++が採用されている。
Java、Python、.NET、MATLAB　用のラッパーが用意されている。

プラットフォームは、Windows、macOS、LINUX に加えて、Android、iOSをサポートしている。

[OpenCV](https://ja.wikipedia.org/wiki/OpenCV)

### Android 用 OpenCV


OpenCV の公式なサポートとして、
Android 用の SDK が用意されている。

C/C++ソースコード、Javaソースコード、ビルド済みの共有ライブラリ(shared object file)が同封されている。

OpenCV の Core 部分は、共有ライブラリとして同封されている。

Java のソースコードは、Android API 21 からサポートされた Camera2 API と Runtime Permission に対応している。

AndroidStudio にインポートできるように　build.gradle　が同封されている。

８個のサンプルが同封されている。

[OpenCV for Android](https://opencv.org/android/)


[reference : camera2](https://developer.android.com/reference/android/hardware/camera2/package-summary)


[developer : アプリの権限をリクエストする](https://developer.android.com/training/permissions/requesting)

### 開発環境

- mcOS : 10.11.6 El Capitan
- Android Studio : 2.2
- buildTools : 28.0.3
- SDK : 26
- NDK : 20.0.5594570
- Cmake : 3.6.4111459

- 実機 : Nexus5
Android : 6.0.1 Marshmallow

### AndroidStudio に OpenCV をインポートする。


OpenCVの公式ドキュメントには、
Eclipse にインポートする手順が掲載されている。

[OpenCV4Android SDK : Import OpenCV library and samples to the Eclipse]
(https://docs.opencv.org/2.4/doc/tutorials/introduction/android_binary_package/O4A_SDK.html)

Android Studio にインポートする手順は。
下記の記事を参考にした。


- [Android StudioでOpenCVを使う](https://qiita.com/tifa2chan/items/a2ec4f5d90eeb9cf1802)

- [AndroidStudioにOpenCVを入れる](https://qiita.com/sourcekatu/items/c5fe7850b2731d7e14b2)

- [AndroidStudioにOpenCV4.1.0を導入する](https://qiita.com/Khiroka/items/59d35f92963b31e1b633)

８個のサンプルを試すにあたり、サンプルごとにインポートしてビルドしていては、効率が悪い。
Android のライブラリ（aar）を作成する。

(1) OpenCV Android SDK をダウンロードする
https://github.com/opencv/opencv/releases
2019年11月時点の最新バージョンは4.1.2。

(2) 新規のプロジェクトを作成する
File -> New -> New Project -> Empty Activity
OpenCV Android SDK の sdk/build.gradle　に合わせて、
下記のバージョンを設定する
- compileSdkVersion 26
- minSdkVersion 21
- targetSdkVersion 26

(3) OpenCV の Android SDK をインポートする
File -> New -> Import Module
Module name を 「:sdk」　から「opencv」に変更する。

(4) 依存関係を設定する
 File -> Project Structure 

(5) Makeする
Build -> Make Projec
いろいろエラーが出るので、
opencv/build.gradle を修正する

### opencv/build.gradle を修正する

Makeすると、
いろいろエラーが出るので、
opencv/build.gradle を修正する

> buildToolsVersion is not specified.


```
// app/build.gradle に合わせて、下記を設定する
    buildToolsVersion "28.0.3"
```

> Could not find method doNotStrip() for arguments [**/*.so] on object of type

```
// 下記をコメントアウトする
                // doNotStrip '**/*.so'  // controlled by OpenCV CMake scripts
```

> Expected caller to ensure valid ABI: MIPS

```
// 実機のCPUに合わせて abiFilters を追加する
        ndk {
            abiFilters 'armeabi-v7a'
        }
```

> Unexpected native build target opencv_jni_shared. 

```
// 下記をコメントアウトする
                // targets "opencv_jni_shared"
```


下記のようなエラーが出る。
これは、OpenCV の Android SDK にて、廃止予定(Deprecated) の Camera API を使っているため。
 注意だけなので、無視しても支障ない。

>  注意:一部の入力ファイルは非推奨のAPIを使用またはオーバーライドしています。
> 注意:詳細は、- Xlint:deprecationオプションを指定して再コンパイルしてください。

[reference : Camera](https://developer.android.com/reference/android/hardware/Camera.html)


### AAR(Android Library) に "libc++_shared.so" を同封する

動作確認のためのアプリを実行すると、下記のエラーになる。

> dlopen failed: library "libc++_shared.so" not found

libcxx_helper/CMakeLists.txt を実行すると、
同封されるようだが、
私の環境では、機能しなかった。

下記を参考に、
NDKから "libc++_shared.so"　をコピーするCMakeLists.txt を作成する。

[Android Studio CMake - shared library missing libc++_shared.so? Can CMake bundle this?](https://stackoverflow.com/questions/39620739/android-studio-cmake-shared-library-missing-libc-shared-so-can-cmake-bundle)

```　opencv/build.gradle
           //  path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt')
            path 'CMakeLists.txt'
```

```　CMakeLists.txt
  configure_file(
    "${ANDROID_NDK}/sources/cxx-stl/${LIB_PATH}/libs/${ANDROID_ABI}/${SO_NAME}" 
    "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${SO_NAME}" 
    COPYONLY)
```
### 動作確認する

動作確認のためのアプリを作成する。

(1) 新規のプロジェクトを作成する
File -> New -> New Project -> Empty Activity

(2) aar をインポートする
File -> New -> Import Module -> Import JAR / AAR Package

(3) 依存関係を設定する
 File -> Project Structure 

(4) MainActivity.java を変更する


```　MainActivity.java
// OpenCVがロードできるか確認する
    if(OpenCVLoader.initDebug()){
        Log.d( TAG,  load "OpenCV Successfully" );
    }
```

(5) ビルドする
Build -> Build APK

(6) 共有ファイルが同封されていることを確認する
Build -> Analyze APK
下記の２つが同封されていることを確認する。
- libopencv_java4.so
- libc++_shared.so
![analyze_apk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/0df296c5-d8af-585a-918b-4f45c9254060.png)

(7) アプリを実行する
Run -> Run app

サンプルコードをgithub に公開した。
- Android のライブラリ（aar）を作成する
 https://github.com/ohwada/Android_Samples/tree/master/Opencv412Lib 
- 動作確認のためのアプリ
https://github.com/ohwada/Android_Samples/tree/master/Opencv41 

### 関連記事

- [Android　で OpenCV のサンプルを試す](https://qiita.com/ohwada/items/4239565266d03b4b551d)

- [Android　で OpenCV のサンプル camerapreview を試す]
(https://qiita.com/ohwada/items/53305d29f33bd14e6683)

- [Android　で OpenCV のサンプル mixedprocessing を試す](https://qiita.com/ohwada/items/6991e8e3a37d03149b16)

- [Android で OpenCV のサンプル face-detection を試す](https://qiita.com/ohwada/items/d4cae2924aabe18cc9c4)

- [Android で OpenCV と　MobleNet を使って 物体検出する]
(https://qiita.com/ohwada/items/d0a0d03ace3578e88b06)

- [Android で OpenCV を使って QRコードを検出する](https://qiita.com/ohwada/items/c5b7a4f3badedc64dc65)