LoginSignup
10
13

More than 5 years have passed since last update.

Android + OpenCV 4 で、顔認識をする

Last updated at Posted at 2019-01-24

概要

Android と OpenCV 4.0.1 のまとまった情報がなかったので、まとめてみました。
Android 開発の経験がある前提で、記載します。

OpenCV の用意

  • 4.0.1 の Android pack をダウンロードします。
  • 適当な場所に解凍します。

Android

  • モジュールをソースからインポートする

    Android プロジェクトで、プロジェクトを選択して、右クリックで「新規→モジュール」を選択します。

    • ソース・ディレクトリー/モジュール名

    ソース・ディレクトリー:
    C:\OpenCV-android-sdk\sdk など解凍したディレクトリーを入力します。
    ここで、注意するのが他のサイトだと「C:\OpenCV-android-sdk\sdk\java」になっていますが、「C:\OpenCV-android-sdk\sdk」が正しくなります。

    モジュール名:
    opencv など入力します。

  • opencv の build.gradle を編集

compileSdkVersion が古いバージョンになっている可能性がありますので、アプリケーションのバージョンと合わせてください。

  • モジュール依存関係を追加

プロジェクトを選択して、右クリックで「モジュール設定を開く」を選択します。
依存関係タブを選択して、先ほど入力したモジュール名を選びます。

  • 顔認識に必要なファイルをコピー

解凍した中から「haarcascade_frontalface_alt.xml」をassetsなどにコピーする。
C:\OpenCV-android-sdk\sdk\etc\haarcascades


準備は、上記で完了です。
後は、実装していきます。
顔認識した顔に枠線を付けて、ImageViewに表示します。
assetsに顔が入った画像がある前提で、記載します。


    private static final String FILE_NAME = "haarcascade_frontalface_alt.xml";

    private BaseLoaderCallback onLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            super.onManagerConnected(status);

            // haarcascade_frontalface_alt.xml をコピー
            File file = new File(getFilesDir().getPath() + File.separator + FILE_NAME);
            if (!file.exists()) {
                try (InputStream inputStream = getAssets().open(FILE_NAME);
                        FileOutputStream fileOutputStream = new FileOutputStream(file, false)) {
                    byte[] buffer = new byte[1024];
                    int read;
                    while ((read = inputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, read);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            CascadeClassifier cascadeClassifier = new CascadeClassifier(file.getAbsolutePath());

            try (InputStream inputStream = getAssets().open("image.jpg")) {
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

                Mat mat = new Mat();
                Utils.bitmapToMat(bitmap, mat);

                MatOfRect matOfRect = new MatOfRect();
                cascadeClassifier.detectMultiScale(mat, matOfRect);

                if (matOfRect.toArray().length > 0) {
                    for (Rect rect : matOfRect.toArray()) {
                        Imgproc.rectangle(mat, new Point(rect.x, rect.y),
                                new Point(rect.x + rect.width, rect.y + rect.height),
                                new Scalar(0, 255, 0), 5);
                    }
                    Utils.matToBitmap(mat, bitmap);
                }

                ImageView imageView = findViewById(R.id.imageView);
                imageView.setImageBitmap(bitmap);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        if (!OpenCVLoader.initDebug()) {
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, getApplicationContext(),
                    onLoaderCallback);
        } else {
            onLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
        }
    }
}

古いOpenCVの記事だと*.soをコピーするなどが書かれていますが、インポートするだけで問題ありません。

10
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
13