Android　で OpenCV のサンプル mixedprocessing を試す

[AndroidStudio で OpenCV をインポートする](https://qiita.com/ohwada/items/71eb18296aac46f9f5ee)
の続きです。

### 概要

Android 用 OpenCV　には、
８個のサンプルが同封されている。

そのうち　mixedprocessing は、
Native API  を使うサンプルサンプルです。
前回の記事で作った Android のライブラリをインポートする手法は使えないので、
アプリごとに Android 用のOpenCV をインポートしてビルドする。

### tutorial-2-mixedprocessing

OpenCVの Java API と Native API の２つの方法で、
カメラからの画像を変換して、表示するサンプルです。

メニューは下記の４つ
- Preview RGBA
カメラ画像をカラーで描画する
- Preview Gray　　　
カメラ画像をグレースケールで描画する
- Canny　
キャニー ( Canny) 法によりエッジを検出して描画する
- Find feature　　　
Native API により特徴点を検出して、小さな赤い丸を描画する

- [wikipedia : キャニー法](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%83%E3%82%B8%E6%A4%9C%E5%87%BA#%E3%82%AD%E3%83%A3%E3%83%8B%E3%83%BC%E6%B3%95_(Canny_edge_detector))

- [OpenCV : Canny法によるエッジ検出](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_canny/py_canny.html)

- [OpenCV : 特徴検出の共通インタフェース](http://opencv.jp/opencv-2svn/cpp/features2d_common_interfaces_of_feature_detectors.html)

- [OpenCV : 描画関数 cv::circle](http://opencv.jp/opencv-2svn/cpp/drawing_functions.html#cv-circle)

### アプリを作成する

まず、下記の記事をお読みください。

- [AndroidStudio で OpenCV をインポートする](https://qiita.com/ohwada/items/71eb18296aac46f9f5ee)

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

(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/tutorial-2-mixedprocessing/src/org/opencv/samples/tutorial2/Tutorial2Activity.javaを
app/src/main　にコピーして、
MainActivity.java　にリネームする。

```MainActivity.java

public class MainActivity extends CameraActivity implements CvCameraViewListener2 {

    public native void FindFeatures(long matAddrGr, long matAddrRgba);

    public void onCreate(Bundle savedInstanceState) {
        // 省略
    }


    public void onResume() {
        // 省略
    }



    public boolean onCreateOptionsMenu(Menu menu) {
        // 省略
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        // 省略
    }


    public void onCameraViewStarted(int width, int height) {
        // 省略
    }


    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        // 省略
    }


    private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {
        public void onManagerConnected(int status) {
            // 省略
    }
};
```


(8) native コードを作成する。
samples/tutorial-2-mixedprocessing/jni ディレクトリを
app/src/main にコピーして、
cpp　にリネームする。
プロジェクトのファイル構成に合わせて変更する。


```jni_part.cpp
/**
 * org_opencv_samples_tutorial2_Tutorial2Activity　を
 * jp_ohwada_android_opencv48_MainActivity　に変更する
 */

JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_FindFeatu
```


(9) app/build.gradleを変更する


```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 "mixed_sample"
            }

    buildTypes {
    externalNativeBuild {
        cmake {
            path 'src/main/cpp/CMakeLists.txt'
        }
    }
```


(10) cmake を修正する
Make　するとエラーが出るので、
cmake を修正する

(11) Makeする
Build -> Make Projec


### cmake を修正する

Makeすると、
エラーが出るので、
プロジェクトのファイル構成に合わせて
下記の２つの cmake を修正する

- opencv/native/jni/abi-armeabi-v7a/OpenCVConfig.cmake
- opencv/native/jni/abi-armeabi-v7a/OpenCVModules-release.cmake

> CMake Warning at /Users/ohwada/AndroidStudioProjects/Opencv48/opencv/native/jni/abi-armeabi-v7a/OpenCVConfig.cmake:129
  > OpenCV: Include directory doesn't exist:
  > '/Users/ohwada/AndroidStudioProjects/Opencv48/sdk/native/jni/include'.

```OpenCVConfig.cmake
# /sdk/native/ を /opencv/native/　に変更する

set(__OpenCV_INCLUDE_DIRS "${OpenCV_INSTALL_PATH}/sdk/native/jni/include")
```

> CMake Error at /Users/ohwada/AndroidStudioProjects/Opencv48/opencv/native/jni/abi-armeabi-v7a/OpenCVModules.cmake:245 (message):
  > The imported target "libcpufeatures" references the file
   >  "/Users/ohwada/AndroidStudioProjects/Opencv48/sdk/native/3rdparty/libs/armeabi-v7a/libcpufeatures.a"
  > but this file does not exist. 

```OpenCVModules-release.cmake
# /sdk/native/ を /opencv/native/　に変更する

set_target_properties(libcpufeatures PROPERTIES
  IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
  IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/sdk/native/3rdparty/libs/armeabi-v7a/libcpufeatures.a"
  )

list(APPEND _IMPORT_CHECK_FILES_FOR_libcpufeatures "${_IMPORT_PREFIX}/sdk/native/3rdparty/libs/armeabi-v7a/libcpufeatures.a" )
```

### アプリを実行する


下記の３つが同封されていることが確認できる。
- libopencv_java4.so
- libc++_shared.so
- libmixed_sample.so
![opencv48_analyze_apk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/3c4bdd45-c13a-81ff-b908-dbb63b670e4b.png)


アプリが起動すると、
カメラのアクセス許可を要求する。
![opencv48_permission.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/3637c069-a118-7115-c02e-fe6525623b85.png)

スクリーンショット

Preview RGBA (カラー)
![opencv48_rgba.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/96d039df-0b55-f09d-3b61-5863654eaf2c.png)

Preview Gray (グレースケール)
![opencv48_gray.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/5b7f07fa-6a6e-318f-fccb-b097041aa90d.png)

Canny(エッジを検出)
![opencv48_canny.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/cf8ae0eb-d0d9-cb7e-1de2-17ab03a4107a.png)


Find feature(特徴点検出)
![opencv48_find._featurepng.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/62cf4105-3b2a-2397-926d-46c56f87097a.png)

　　


サンプルコードをgithub に公開した。
 https://github.com/ohwada/Android_Samples/tree/master/Opencv48