Apitore blog

Apitoreを運営していた元起業家のブログ

Microsoft Cognitive Services (WebAPI) を使う方法

はじめに

先日、Apitore WebAPIハンズオン Vol.3 @東京を開催しました。このハンズオンではMicrosoftのCognitive Servicesを使う方法をゼロから解説しました。アクセストークンの発行からAPIの呼び出しまで抑えていますので、これに参加すればMicrosoftのWebAPIはスラスラと呼べるようになります。今回は宣伝がてら特別にハンズオンの内容を紹介します。

ソースコード

GitHubでサンプルコードを公開しています。

アクセストークンの発行

ゼロから解説します。 Microsoft Cognitive Servicesはこちらです。例えば、画像認識、顔認識、感情推定、動画分析、機械翻訳、Bing検索など、Microsoftの技術を使えるサービスになります。実運用する場合はAzuruアカウントを作ってクレジットカード登録等々しないといけませんが、試用版もあります。試用版であれば、Microsoft/Facebook/LinkedIn/GitHubのアカウントで30日間有効なアクセストークンが発行できます。30日以降はAzuruを使わないといけませんが、テンポラリのアカウントを増やせば・・・ゴニョゴニョ。

今回は試しにComputer Vision APIを使ってみます。画像認識、OCR(光学文字認識/手書き文字認識)、ランドマーク認識、有名人認識、動画解析、動画サムネール抽出があります。

画像認識を使ってみます。 アクセストークンの発行およびAPIの仕様を確認するために「ドキュメント」をクリックしてください。

今回はJavaで解説します。

「Prerequisites」の「You can get free subscription keys here」をクリックします。

Subscriptions」をクリックします。

「Computer Vision API」の「作成」をクリックします。

使用条件に同意します。

サインインしてアクセストークンを発行します。

こんな感じでアクセストークンが発行できました。あとで使うので「キー1」をどこかにコピーしておいてください。なお、このURLは他のAPIのアクセストークンを発行するときに使うのでブクマしておくと良いでしょう。

WebAPIの仕様

APIの仕様書はこちらにあります。「ドキュメント」にも例があります。 今回は画像認識を使うので、ドキュメントの一番上のサンプルコードを参照しながら解説します。画像認識WebAPIのエンドポイントはhttps://westcentralus.api.cognitive.microsoft.com/vision/v1.0/analyzeです。

画像はURLを指定するか、ローカルのファイルを指定するか選べます。画像以外に指定できる属性はvisualFeaturesdetailslanguageです。詳細はこちらを確認していただくとして、最低限visualFeatures=Tagsがあれば大体の需要は満たすと思います。

POSTで投げればレスポンスが返ってきます。

WebAPIをコールする

実際にWebAPIをコールしてみます。公式にもサンプルコードがありますが、今回はSpring WebのRestTemplateを使います。Spring Webは使い勝手が良く、APIのコールに適しています。GitHubでサンプルコードを公開しています。 依存ライブラリはこちらです。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <version>1.5.3.RELEASE</version>
</dependency>

画像URL指定の場合のAPIコール

static String ENDPOINT     = "https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/analyze";
static String ACCESS_TOKEN = "YOUR-ACCESS-TOKEN";
public static void main(String[] args) {
  RestTemplate restTemplate = new RestTemplate();
  restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
  String url = String.format("%s?visualFeatures=Tags", ENDPOINT);
  ObjectMapper mapper = new ObjectMapper();
  String json = "{\"url\":\"https://upload.wikimedia.org/wikipedia/commons/1/12/Broadway_and_Times_Square_by_night.jpg\"}";
  HttpHeaders headers = new HttpHeaders();
  headers.setContentType(MediaType.APPLICATION_JSON);
  headers.set("Ocp-Apim-Subscription-Key", ACCESS_TOKEN);
  HttpEntity<String> entity = new HttpEntity<String>(json, headers);
  ResponseEntity<Map> response = restTemplate
      .exchange(url, HttpMethod.POST, entity, Map.class);
  Map res = response.getBody();
  System.out.println(res);
}

解説します。YOUR-ACCESS-TOKENに最初に取得したアクセストークンをコピペしてください。これで動きます。 もう少し解説します。今回はvisualFeatures=Tagsを指定しました。画像URLはjsonで渡すことになります。APIのレスポンスはResponseEntityで受けています。SDKがないので、とりあえずMapオブジェクトで受け取っています。Tagsを指定すると、レスポンスは以下のような配列が入ってきますので、List list = res.get("tags")みたいな感じで受け取ってあげてください。

"tags": [
    {
      "name": "person",
      "confidence": 0.98979085683822632
    },
    {
      "name": "man",
      "confidence": 0.94493889808654785
    },
    {
      "name": "outdoor",
      "confidence": 0.938492476940155
    },
    {
      "name": "window",
      "confidence": 0.89513939619064331
    }
  ],

ローカルから画像を読み込む場合のAPIコール

static String ENDPOINT     = "https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/analyze";
static String ACCESS_TOKEN = "YOUR-ACCESS-TOKEN";
public static void main(String[] args) throws IOException {
  // 初期化
  RestTemplate restTemplate = new RestTemplate();
  restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
  // レスポンスの内容を設定
  String url = String.format("%s?visualFeatures=Tags", ENDPOINT);
  // 画像データの読み込み
  Path path = Paths.get("./images/image3.JPG");
  byte[] data = Files.readAllBytes(path);
  // ヘッダーの設定とリクエストの設定
  HttpHeaders headers = new HttpHeaders();
  headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
  headers.set("Ocp-Apim-Subscription-Key", ACCESS_TOKEN);
  HttpEntity<byte[]> entity = new HttpEntity<byte[]>(data, headers);
  // APIコール部分
  ResponseEntity<Map> response = restTemplate
      .exchange(url, HttpMethod.POST, entity, Map.class);
  Map res = response.getBody();
  System.out.println(res);
  List<Map> list = (List<Map>) res.get("tags");
  for (Map mp: list)
    System.out.println(mp.get("name"));
}

ポイントはbyte[] data = Files.readAllBytes(path);です。画像をバイナリーで読み込んでHttpEntityのbodyに突っ込みます。このテクニックは基本的に画像処理系APIでは必須です。ひとつ覚えれば応用が効きます。

おわりに

最後は駆け足になりましたが、これでMicrosoft Cognitive ServicesのWebAPIが使えるようになります。Cognitive ServicesのそのほかのAPIも同じ要領で使えます。私が公開しているGitHubには、FaceAPIとEmotionAPI、BingImageSearchAPIのサンプルがあります。お役に立てば幸いです。 Apitoreでは定期的にハンズオンを開催しています。よろしければconnpassをご登録いただくか、メルマガを出すのでApitoreでアカウントを作成してください。皆様のご登録をお待ちしています!