OpenCV for Android入門 – カメラ編

ここ最近はAndroidアプリ開発の勉強をしています。今回はOpenCVでデバイスのカメラを利用した動画像処理を試してみました。

技術Wikiの方にもAndroid関連のメモを残しています。
* Android – Tech Note
* OpenCV for Android – Tech Note

Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.

環境

* OpenCV4Android SDK 2.4.4 (今回はJava APIのみ使用)
* 検証デバイス: Galaxy S2 LTE(Android 2.3.6), AQUOS PHONE ZETA SH-02E(Android 4.0.4)
* 開発機: MacBook Air Mid 2012

基本的にAndroid 2.2(API Level 8)でも動作するように確認しながら進めていきたいと思います。

環境構築とサンプルアプリのビルドまでの手順は、公式サイトにスクリーンショット付きで丁寧に説明してくれています。Windows 7用のガイドですが、ほぼEclipse上での手順説明なのでMacでもパスを読み替える程度で簡単にできました。僕の場合はSDKを ~/Library/OpenCV2.4.4 以下にインストールしておきました。
* OpenCV4Android SDK — OpenCV 2.4.4 documentation

OpenCV Managerについて

OpenCV4Android SDK 2.4.2からライブラリ自体はOpenCV Managerというアプリで管理する構成に変更されました。これまでのようにアプリのバイナリにライブラリをコピーするのは無駄だからというのが主な理由とのことです。デバイスのアーキテクチャをOpenCV Managerが判別して適切なライブラリをインストールしてくれます。

using OpenCV Manager
using OpenCV Manager, feel the difference

確かにサイズは大きく減っていますね。ただ、アプリのユーザーにOpenCVを意識させることになるので(OpenCV Managerを別途インストールしてもらう必要がある)その辺りは微妙な気はしますけど。実際にAndroid端末にOpenCV ManagerをGoogle Playからインストール、実行してみました。ライブラリのインストールが成功すると以下のような画像が見られます。
opencv_manager_aquosphone

カメラアクセスの許可

OpenCVの使い方の前に、けっこう忘れがちなカメラアクセスの許可設定を行っておきます。AndroidManifest.xml ファイルを以下のように編集します。

以下、OpenCVでデバイスのカメラを利用した動画像処理を行う際の基本フローを整理していきます。

1. レイアウトの定義

OpenCVではカメラを扱う2つのクラス JavaCameraViewNativeCameraView が提供されています(両者の違いは後述)。これのどちらかをビューとしてXMLレイアウトファイル(res/layout/*.xml)に配置します。

ここでは JavaCameraView を配置しています。利用できる属性は camera_id (any/front/back) と show_fps (true/false) です。camera_id には利用するカメラ(フロント/バックカメラ)を指定するのですが、any を指定しておけば自動的にカメラを判別してくれます。show_fps を true にすると画面左上にFPSと画角が表示されます。デバッグ時は有効にしておくと良いです。

2. OpenCVライブラリの読み込みと初期化

OpenCV Managerを使う場合、Activityの中でOpenCVライブラリの読み込みを行う OpenCVLoader.initAsync メソッドを呼び出す必要があります。このメソッドは非同期で実行されるので、読み込み完了後にUIスレッドで呼ばれるコールバックメソッドも併せて実装しておきます。

JavaCameraViewとNativeCameraViewの違い

JavaCameraView と NativeCameraView は両方とも CameraBridgeViewBase のサブクラスです。
opencv4android_cameraview
JavaCameraView は android.hardware.Camera を利用した実装、NativeCameraView はOpenCVの VideoCapture を利用した実装という違いがあります。安定性という観点ではAndroid SDKの機能を利用した JavaCameraView の方が安定しているかと思われますが、そんなに気にしなくて大丈夫でしょう。

CvCameraViewListenerインタフェースの実装

CvCameraViewListener または CvCameraViewListener2 インタフェースの以下の3つのメソッドを実装します。
* onCameraViewStarted
* onCameraViewStopped
* onCameraFrame
3つめの onCameraFrame メソッドに任意の画像処理を実装することになります。また、CvCameraViewListener と CvCameraViewListener2 の違いは onCameraFrame の引数のみで、onCameraViewStarted および onCameraViewStopped は共通です。

CvCameraViewFrame インタフェースは以下のようになっています。CvCameraViewListener2.onCameraFrame ではこのインタフェースを実装した JavaCameraFrame/NativeCameraFrame のインスタンスが渡されます。

キャプチャしたフレーム画像をそのままカメラプレビューに表示させるには、CvCameraViewListener.onCameraFrame の場合は引数の inputFrame をそのまま return し、CvCameraViewListener2.onCameraFrame の場合は inputFrame.rgba() を return します。

OpenCVでカメラを利用した動画像処理を行う際の基本フローは以上になります。ここまでのまとめとして、カメラから取得したフレーム画像を線画風に変換する処理のサンプルコードを載せておきます。

opencv4android_linedraw
opencv4android line drawing

Galaxy S2 LTEでだいたい15fpsほどで動作しました。スマートフォンでもこの速度が出せるのには驚きました。

今回はAndroidでOpenCVを使ったアプリ開発を試してみましたが、特に難しいところもなくスムーズに進めることができました。OpenCVがAndroidをサポートした当初はバグだらけで大変だったらしいですが、現在はとても使いやすくなっているので昔挫折してしまった人はリベンジしてみてください。これからも引き続きいろいろ試していきたいです。

* 参考
opencv.org – Home > PLATFORMS > ANDROID
Android | Blog はじめました

あわせて読む:

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です