はじめに
先日、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を指定するか、ローカルのファイルを指定するか選べます。画像以外に指定できる属性はvisualFeatures
とdetails
とlanguage
です。詳細はこちらを確認していただくとして、最低限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でアカウントを作成してください。皆様のご登録をお待ちしています!