OpenCV 2.4.6-Android-sdkのサンプルにあるface-detectionを一から作ってみましょう。
まあ、一からと言ってもC++のソースとヘッダーやその他のコードも、まんまお借りする訳ですけど...。
今回の作業には、android-ndkとCygwinが必要ですので、事前にインストールして環境設定しておいてください。
android-ndk
Cygwin
肝はJNIプロジェクトの作成です。
が、その前に以下の項目を事前に決めておきます。
NDKでビルドする場合、メソッド名規約を守らないとUnSatisfiedLinkErrorが出て簡単に落ちます。
●アプリケーション・プロジェクト名
●パッケージ名(重要)
●アクティビティ名
●レイアウト名
アプリケーション・プロジェクト名はなんか適当に、facedetect246とかにします。
パッケージ名は例えば、jp.example.facedetect246にします。
アクティビティ名も例えば、FdMainActivityとかにします。
レイアウト名はサンプルにならって、face_detect_surface_viewにしときます。
まずは、普通にJavaで新規プロジェクトを作成します。
Eclipseを起動して、File->New->Projectで、上記の名称でプロジェクトを作成。
プロジェクト名を右クリックしてPropertiesを選んで、EncodingをUTF-8、Targetを4.0.3、ライブラリにOpenCV 2.4.6を設定しておきます。
まずサンプルコードを先に移植しておきます。
これをやっておかないと、C++のプロジェクトを追加しようとしても、Eclipseはどこに追加すればいいのか分からなくなるようです。
新規プロジェクトのjp.example.facedetect246パッケージに以下のPublic classを追加。
DetectionBasedTracker
サンプルのresフォルダーからrawとlayoutをコピーして、プロジェクトをRefreshしておきます。
rawにはカスケードファイルが入っています。
サンプルのface-detectionのコードを移植。
FdActivity -> FdMainActivity
DetectionBasedTracker -> DetectionBasedTracker
エラー箇所を修復したら、C++プロジェクトを作成します。
プロジェクト名を右クリックして、New -> Otherを選択。
C/C++の中の、「Convert to a C/C++ Project(Adds C/C++ Nature)」を選択。
Convert to a C/C++ Projectのウィンドウが開いたら、
Candidate for Conversionの自プロジェクトにチェックが入っているのを確認。
Project option で「Makefile Project」と「CygwinGCC」を選んでFinish。
Project Explorerにincludesの項目が追加されています。サンプルとは異なっていると思いますが気にしなくていいです
プロジェクト名を右クリックして、New -> Folderを選択。jniフォルダーを作っておきます。
この中にサンプルのmkファイルやcppのソース・ヘッダーが置かれます。
で、その前にプロジェクトのC/C++の設定をしておきます。
プロジェクト名を右クリックしてPropertiesを選んで、C/C++ Buildを設定。
Build command欄に、NDKのndk-build.cmdの場所をフルパスで設定。
Build directoryが自プロジェクトになっているのを確認。
Behaviourタブを選んで、Buildの2つの欄を空白にして、cleanのチェックも外しておきます(サンプル参考)。
次に、C/C++ GeneralのPath and SymbolsでSource Locationに自プロジェクトのjniフォルダーをAddして、既存のものをDeleteしておきます。
忘れてました
C/C++ GeneralのPath and SymbolsのIncludesで、NDKのincludeフォルダーをAddしておいてください。
例:C:\android-ndk-r8d\platforms\android-8\arch-arm\usr\include
これをやっておかないと、C++のソース・ヘッダーでJNICALLが分からん...というような文句がでます。
AndroidManifest.xmlに以下を追加。
android:minSdkVersion="9"
----------------
android:screenOrientation="landscape"
----------------
<supports-screens android:resizeable="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front" android:required="false"/>
<uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>
この時点ではC++のコードが何も無いので、Eclipseのコンソールにはビルドエラーが吐き出されていると思います。
では、C++の環境を作ります。
まずサンプルどおりに、jniフォルダーに以下のファイルを作っておきます。
Android.mk
Application.mk
DetectionBasedTracker_jni.cpp
DetectionBasedTracker_jni.h
Android.mkとApplication.mkはサンプルどおりです。
DetectionBasedTracker_jni.cppとDetectionBasedTracker_jni.hですが、修正します。
メソッド名規約は、"Java_パッケージ名_クラス名_メソッド名"です。
今回の作り方なら、クラス名_メソッド名はそのままでいいですが、パッケージ名のところが異なります。
サンプルでは、Java_org_opencv_samples_facedetectとなっていますが、ここの例では、Java_jp_example_facedetect246になります。
なおオリジナルのヘッダーファイルには「勝手に書き換えんなよ」と書いてますが....書き換えます。
最後に、プロジェクトをcleanすればC++のコードがビルドされて、プロジェクトにobjとlibs/armeabi-v7a/libdetection_based_tracker.soが作成されます。
PS
cppのソースを移植した場合、Eclipseが山ほどエラーを吐き出す場合があります。
特にnamespaceについてのSymbolエラーですが、実はエラーじゃない場合があります。
Eclipseが誤判定しているような感じ。ndkかCygwinとの相性かもしれないのですが...まだ分かりません。
このままではRunできないので、Eclipseを再起動してみてください。エラーが解消されます...というかエラーが消えるはず。
以上です。
こんな感じ。
なんかオリジナルのサンプルアプリよりカメラ画面が小さくなったような気がするが...気のせいか?。
インストール
サンプルなので、インストール・実行は自己責任でお願いします。
Target:Android 2.3.3 or later
動作確認実機:Xperia acro(docomo) Android 2.3.4、dtab01(docomo) Android 4.1.2
なお、このアプリの実行には別途、OpenCV Managerが必要です。
先に、GooglePlayでインストールしておいてください。
-
アプリをQRコードからインストールする方法はコチラを参照
タブレットの場合
QRコードでダウンロードすると、Downloadフォルダー内でzipファイルになってインストールできない状態の場合があります。
その場合は、拡張子のzipをapkに変更してファイル名をタップすればインストール用のダイアログが出ますので、そこからインストールしてください。
他のOpenCV関連ページ
OpenCV覚書
矩形領域の座標を取得するページ
OpenCV 2.3.1でカスケードを作って、Androidで使ってみる
アンドロイドでOpenCV(お顔の検出)
アンドロイドでOpenCV(色検出)
アンドロイドでOpenCV(特徴点検出)
Android OpenCV 2.3.1で画像認識
AndroidでOpenCV 2.4.6を使ってみる
OpenCV + NyMMDで初音ミクさんにご挨拶してもらいます