ホーム 開発支援情報 技術ブログ 使ってみようAPI講座 【使ってみようAPI講座】Lesson2 : 画像認識API

使ってみようAPI講座

【使ってみようAPI講座】Lesson2 : 画像認識API

掲載日:2015年03月02日

ドコモAPIを実際に使いながらご紹介する「使ってみようAPI講座」。Lesson2では画像認識APIを例に、アプリから実行する方法を紹介します。

画像認識API

このAPIは、画像に写っているものを認識、解析して、その名称などの情報を取得することができます。
認識できるものは、書籍やDVD、CD、PCソフト、ゲームソフト、食品パッケージといった商品です。現在500万件以上の市販品情報が登録されていて、その名称や関連情報のWebページURL、認識の確からしさを表すスコアなども取得可能です。

画像認識APIのSDK

サンプルアプリ

サンプルアプリの起動画面

画像認識APIのSDKには、サンプルアプリも含まれています。まずは、このサンプルをビルドしてみましょう。サンプルアプリは、Eclipseのプロジェクトとして提供しております。SDKのsampleフォルダにzipファイルがありますので、解凍して、Eclipseにインポートします。


プロジェクトのlibsフォルダには、ライブラリファイルが含まれています。このようにlibsフォルダにコピーするだけで、プロジェクトからSDKのライブラリを使うことができます。

APIキーの設定とAPIの実行手順

このサンプルアプリを実行するには、APIキーの設定(アプリ開発手順参照)が必要です。APIキーは、プロジェクトのRecognitionActivity.javaにある、RecognitionActivityクラスのフィールドに設定します。

// API キー
static final String APIKEY = "";

画像認識APIには3つの処理がありますが、いずれも同様のコードで実行することができます。メインとなる画像認識は、次のようなコードで情報を取得できます。resultDataに、結果のJSONデータが格納されていますので、必要に応じて、そのデータから情報を抽出します。

// 画像認識クラスを作成する
ImageRecognition recognize = new ImageRecognition();

// 画像認識リクエストデータクラスを用いてパラメータを設定する
ImageRecognitionRequestParam requestParam = new ImageRecognitionRequestParam();
requestParam
.setRecog(Recog.ALL);
requestParam
.setFilePath(画像ファイル名);

// 画像認識クラスにリクエストデータを渡し、レスポンスデータを取得する
ImageRecognitionResultData resultData = recognize.request(requestParam);

画像認識APIとカメラ機能を連携する

サンプルアプリは、画像のパス名を入力し、画像認識のボタンをタップすると、APIを実行して商品情報を表示します。また、その結果が妥当だったかどうかを、フィードバック(報告)することもできます。

今回は、このサンプルを少し改造してみましょう。Androidのカメラ機能や画像ギャラリーと連携するようにして、すぐに画像認識を試せるようにしてみます。

AndroidManifest.xmlへの追加

撮影したカメラ画像を保存するために、マニフェストファイルのPermission属性に、INTERNET、READ_EXTERNAL_STORAGEと共に、保存用のWRITE_EXTERNAL_STORAGEを追加します。

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

リスト1 AndroidManifest.xmlの一部

RecognitionActivity.javaの変更

次に、RecognitionActivity.javaを変更します。最初に、カメラで撮影した画像ファイルのURI用に、RecognitionActivityクラスのフィールドを追加します。

private Uri bitmapUri; // 画像ファイルのURI

リスト2 RecognitionActivity.javaの一部

そして、pushExecButtonメソッドを変更し、onActivityResultメソッドのオーバーライドを追加します。元のpushExecButtonメソッドでは、APIを実行するようになっていますが、これをカメラ撮影と画像ギャラリーと連携する処理に変更します。また、onActivityResultメソッドでは、撮影した画像または画像ギャラリーの画像ファイルのURIを用いて、APIを実行するようにします。

@SuppressLint("NewApi")
private void pushExecButton() {

   
// ギャラリー選択のIntent1
   
Intent intent = new Intent();

   
// APIレベル19(Kit)以降と区別する2
    intent
.setAction((Build.VERSION.SDK_INT < 19) ?
                   
Intent.ACTION_GET_CONTENT: Intent.ACTION_OPEN_DOCUMENT);
    intent
.addCategory(Intent.CATEGORY_OPENABLE);
    intent
.setType("image/*");

   
// カメラ撮影して保存する画像ファイル名を設定しておく3
   
File mediaFile = new File(
           
Environment.getExternalStoragePublicDirectory(
                                       
Environment.DIRECTORY_DCIM),
                                       
System.currentTimeMillis() + ".jpg");
    bitmapUri
= Uri.fromFile(mediaFile);

   
// カメラ撮影のIntent4
   
Intent intent_camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent_camera
.putExtra(MediaStore.EXTRA_OUTPUT, bitmapUri);

   
// ギャラリー選択でcreateChooserし、カメラ撮影のIntentを追加する5
   
Intent chooserIntent = Intent.createChooser(intent, "画像の選択");
    chooserIntent
.putExtra(Intent.EXTRA_INITIAL_INTENTS,
                                           
new Intent[] { intent_camera });
    startActivityForResult
(chooserIntent, 1);
}

@SuppressLint("NewApi")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   
if (requestCode == 1) {
       
if (resultCode == RESULT_OK) {
           
String path = bitmapUri.getPath(); // カメラ画像のパス名
           
if (data != null) {
               
// カメラ画像でない場合は、画像ギャラリーから取得する6
               
if (!data.getData().getPath().equals(bitmapUri.getPath())) {

                   
// APIレベル19(Kit)以降と区別する7
                   
Cursor cursor;
                   
if (Build.VERSION.SDK_INT < 19) {
                       
String[] columns = { MediaColumns.DATA };
                        cursor
= getContentResolver().query(data.getData(),
                                                    columns
, null, null, null);
                   
}
                   
else {
                       
String id = DocumentsContract.getDocumentId(
                                                                data
.getData());
                       
String selection = "_id=?";
                       
String[] selectionArgs = new String[]{id.split(":")[1]};
                        cursor
= getContentResolver().query(
                                   
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                                   
new String[]{MediaColumns.DATA},
                                    selection
, selectionArgs, null);
                   
}
                   
if (cursor.moveToFirst()) {
                        path
= cursor.getString(0);
                   
}
               
}
           
}

           
// 画像のパス名を表示する
           
EditText editText = (EditText)findViewById(R.id.edit_path);
            editText
.setText(path);

           
AlertDialog.Builder dlg = new AlertDialog.Builder(this);

           
// パラメータを設定する
           
ImageRecognitionRequestParam requestParam =
                                           
new ImageRecognitionRequestParam();
            requestParam
.setRecog(Recog.ALL);

           
// 画像のパスを設定する
            requestParam
.setFilePath(path);

           
// 実行
            task
= new RecognitionAsyncTask(dlg);
            task
.execute(requestParam);
       
}
   
}
}

リスト3 RecognitionActivity.javaの一部

この変更でのポイントは、次の3点です。

・カメラ機能と画像ギャラリーの連携に、intent機能を使う
・intentで呼び出した処理の戻り値を、onActivityResultで処理する
・KitKat以降では、画像ギャラリーの扱いが異なる

Androidでは、カメラ機能を直接操作することもできますが、標準のカメラアプリを使う方が簡単です。ここでは、カメラアプリと画像ギャラリーを呼び出すために、intent機能を使っています(コメント行の(1)、(4))。また、Intent.createChooserを使って、カメラアプリと画像ギャラリーの両方に対応したintentを発行しています(5)。

intentで呼び出した処理(Activity)の戻り値は、onActivityResultメソッドをオーバーライドすることで処理することができます。onActivityResultメソッドの3つめの引数に、intentの戻り値(画像ファイルのURI)が格納されています。

ただし、カメラ画像では、この値がNULLとなる機種がほとんどです。そのため、これがNULLか、あるいは設定したURI(3)と同じであれば、カメラ画像、そうでなければ、画像ギャラリーのURIと判断しています(6)。

Android 4.4(KitKat、APIレベル19)から、Storage Access Frameworkという機能が搭載され、画像ギャラリーから戻される画像URIが変更されました。そのため、Build.VERSION.SDK_INTで、実行している機種のAPIレベルを調べ、レベルに応じて処理を変更しています(27)。

実行してみよう

サンプルアプリの結果画面

変更したアプリを起動し、「画像認識要求実行」をボタンをタップすると、カメラ撮影か、ギャラリーかを選択できるダイアログが表示されるようになります。 カメラで撮影するか、ギャラリーの画像を選択すると、元の画面に戻ります。しばらくすると画像が認識され、右図のような表示になります。

最後に

今回は、APIの呼び出し方と、画像認識APIを例にしてSDKの使い方を解説しました。次回も、サンプルアプリを使ってドコモAPIの紹介をしていきます。

原著 : 高江 賢

お問い合わせ
「docomo Developer support」及び「作ろうスマートフォン/iモードコンテンツ」に関するお問い合わせです。よくあるご質問や技術ブログで解決しない場合は、お問い合わせください。