Web APIを使うと個人や一企業で開発する以上の機能やデータが簡単に手に入ります。多くは自社の保有するデータをオープンにするWeb APIが多いですが、中には各種機能をWeb APIとして公開するものもあります。

今回はそんな機能を提供するWeb APIの中から、Microsoft Cognitive Servicesを利用してアプリを作成します。

Microsoft Cognitive Servicesには顔認識、音声認識、言語解析などの様々な機能がありますが、今回は画像を分析するComputer Vision APIをMonacaと組み合わせてみたいと思います。作るのはディープラーニングのサンプルとしてよく見られる、写真に写っているものを判別するアプリです。

今回作成するアプリ

まずは動作を紹介します。なお、今回はOnsen UIを使っています。最初はこのように何も表示されていません。

そこで写真を撮影またはフォトライブラリから任意の写真を選択します。撮影すると写真がComputer Vision APIにアップロードされます。そしてその結果、タグや写真の説明、顔が認識されればその部分が赤枠で表示されます。

それでは作っていきましょう。

Computer Vision APIの利用登録

Computer Vision API のサイトでアカウントを作成します。
試用版も利用可能です。

試用版のアカウントを作成すると、以下の画面が表示されます。

エンドポイントキー1 の値は後ほど利用します。

Monacaでのアプリ作成

ベースのテンプレートにはOnsen UI V2 JS Minimumを使っています。

また、jQueryとJavaScript-Load-ImageをJS/CSSの追加と削除から登録しています。JavaScript-Load-Imageは後述する、写真を正しく表示するためのライブラリです。js-load-image で検索して追加してください。

HTMLについて

今回のHTMLは写真のプレビュー、ファイル選択そして読み取った情報を一覧表示する部分で構成されています。

      <ons-page>
        <p style="text-align:center" id="preview">
            <ons-icon size="250px" icon="photo"></ons-icon>
        </p>
        <p>
            <input type="file" id="file" />
        </p>
        <p>
            <ons-list>
                <ons-list-header>読み取った情報</ons-list-header>
                <div id="info">
                </div>
            </ons-list>
        </p>
    </ons-page>

JavaScriptについて

次にJavaScriptの実装です。今回のアプリでは大きく分けて以下の処理があります。

  1. 変数の定義、初期化
  2. 指定された画像をCanvasタグで描画
  3. 指定された画像をComputer Vision APIに送信
  4. 返却された内容を描画

まず、Onsen UIではDOM構築などが完了すると ons.ready が呼ばれます。

    ons.ready(function() {
      // 処理はこの中に記述していきます
    });

1~4の処理は、画像ファイルを選択したタイミングで実行します。

    ons.ready(function() {
      // ファイルを選択したら呼ばれるイベント
      $("#file").on("change", function(e) {
        // 処理はこの中に記述していきます
      });
    });

変数の定義、初期化

まず変数を定義、初期化します。ENDPOINT は 先ほど取得した エンドポイント に、YOUR_SUBSCRIPTION_KEY は先ほど取得した キー1 にそれぞれ差し替えてください。

    // ファイルを取得
    var f = e.target.files[0];
    if (!f)
      return;

    // エンドポイントを設定
    var ENDPOINT = "YOUR_ENDPOINT";

    // サブスクリプションキーを設定
    var SUBSCRIPTION_KEY = "YOUR_SUBSCRIPTION_KEY";

    // 描画のリセット
    $("#preview").html("");
    $("#info").html("");

指定された画像をCanvasタグで描画

次に取得したファイルオブジェクト(f)を使ってCanvasタグ内に画像を描画します。今回はJavaScript-Load-Imageというライブラリを使います。このライブラリを使うと画像の回転(Orientation)を読み込んで画像を正しく表示できるようになります。

    // 画像を表示する処理
    loadImage.parseMetaData(f, function (data) {
      var options = {canvas: true, maxWidth: 320};
      if (data.exif) {
        options.orientation = data.exif.get('Orientation');
      }
      loadImage(f, function(canvas) {
        $("#preview").html(canvas);
      }, options);
    });

### 指定された画像をComputer Vision APIに送信

そしてもう一つの処理として指定された画像をComputer Vision APIへ送ります。こちらは画像ではなくArrayBufferとしてデータを取得します。visualFeaturesパラメータでは取得したい内容を指定できます。これはCognitive Services APIs Referenceを参考にしてください。言語は現在のところenまたはzh(簡体中国語)にのみ対応しています。

    // ファイルとして読み込み
    var r = new FileReader();
    r.onload = function(e) {
      // Array Bufferとして取得
      var contents = e.target.result;

      // APIを呼ぶ際のパラメータ
      var params = {
        "visualFeatures": "Categories,Tags,Description,Faces,ImageType,Color,Adult",
        "details": "Celebrities",
        "language": "en",
      };

      // Ajaxを実行
      $.ajax({
        url: ENDPOINT + "/analyze?" + $.param(params),
        contentType: "application/octet-stream",
        headers: {
          "Ocp-Apim-Subscription-Key": SUBSCRIPTION_KEY
        },
        type: "POST",
        data: contents,
        processData: false
      })
      .done(function(data) {
        // 処理成功した場合
        // 処理内容は後述します
      })
      .fail(function(e) {
        // エラーの場合
        alert(`error : ${e.responseJSON.message}`);
      });
    }
    r.readAsArrayBuffer(f);

返却された内容を描画

最後に処理結果がうまくいった場合です。まず顔データがあれば、そのデータを使ってCanvasタグ内に枠線を引きます。後は取得できるメタデータの一部を画面上に描画します。

    var percentage = 320 / data.metadata.width;
    var ctx = $("canvas")[0].getContext('2d');

    // 顔データがあれば描画
    if (data.faces.length > 0) {
      for (var i = 0; i < data.faces.length; i++) {
        var face = data.faces[i];
        var f = face.faceRectangle;
        ctx.strokeStyle = "rgb(200, 0, 0)";
        ctx.strokeRect(f.top * percentage, f.left * percentage, f.width * percentage, f.height * percentage);
        ctx.stroke();
      }
    }
    // それ以外の写真のメタデータを表示
    $("#info").append(`
      <ons-list-header>カテゴリ</ons-list-header>
      <ons-list-item>${data.categories[0].name}</ons-list-item>
      <ons-list-header>タグ</ons-list-header>
      <ons-list-item>${data.description.tags.join(", ")}</ons-list-item>
      <ons-list-header>状況</ons-list-header>
      <ons-list-item>${data.description.captions[0].text}</ons-list-item>
    `);

他にも年齢や性別などたくさんのデータが取得できますので、レスポンスデータを確認してみてください。

ここまでの処理で写真を判別して情報を表示するアプリが作成できました。Web APIを使うことで難しそうに見える処理もごく簡単に実装できます。


Microsoft Cognitive ServicesではComputer Vision API以外にもたくさんのWeb APIを公開、提供しています。ぜひ使い方を覚えてアプリを一層魅力的なものにしてください。

今回のコードはmoongift/monaca-computer-visionにアップロードしてあります。実装時の参考にしてください。