[C#] Cognitive Servicesで画像解析(Computer Vision API Describe Image)

Cloud Application Engineerの内海です。

今回はMicrosoft AzureのCognitive Servicesの中から画像解析等が可能なComputer Vision APIを使って、画像解析を行ってみたいと思います。

Microsoftの提供するCaptionBotの裏側、と言えばわかりやすいと思います。


REST APIへアクセスするために必要なもの

REST APIへのアクセスのためにSubscription keyが必要になります。

1.下記サイトの『Request new trials』より『Computer Vision – Preview』を作成
https://www.microsoft.com/cognitive-services/en-US/subscriptions

2.作成されたSubscriptionよりKeyを取得
(下記画面のShowを押下でKeyが可視化されます。)
computervisonapi1


今回サムネイル作成に利用する画像ファイル

以下の3点を満たしている必要があります。
・ 対応しているファイル形式はJPEGとPNG、GIF、BMP
・ ファイルサイズは4MB以下
・ ピクセル単位で50×50以上必要


REST APIへのアクセス手順

サムネイル作成を行いたい画像ファイルをHTTPリクエストでPOSTしましょう。

レスポンスとして画像に写っているオブジェクト等のタグと説明がjsonで返ってきます。

POST先アドレスは以下のものになります。

https://api.projectoxford.ai/vision/v1.0/describe

さらに、POST先アドレスにパラメータを仕込みます。

Key Value
maxCandidates 解析結果の候補の数を指定
指定しないと解析結果の候補の中で1番信頼度の高い結果だけが返ってくる

リクエストヘッダーは以下を設定しておきましょう。

Key Value
Content-Type 以下の3タイプの内から選択
どこかにアップロードした画像の場合
“application/json”
ローカル上の画像を送るなら以下のどちらか
“application/octet-stream”
“multipart/form-data”
Ocp-Apim-Subscription-Key 取得したSubscription Key

今回はローカル上のファイルを送るため、
リクエストボディには画像ファイルをByte配列として書き込みましょう。
画像ファイルのByte配列化はC#ならこんな感じ

var fs = new FileStream(/*ローカル上の画像ファイルパス*/, FileMode.Open, FileAccess.Read);
var byteData = new byte[fs.Length];
fs.Read(byteData, 0, byteData.Length);
fs.Close();

レスポンス

リクエストパラメータに加えリクエストヘッダーとボディに間違いがなければ画像のTag情報と解析結果のTextがjsonとして返ってきます。

{
  "description": {
    "tags": [
      "person",
      "man",
      "outdoor",
      "window",
      "glasses"
    ],
    "captions": [
      {
        "text": "Satya Nadella sitting on a bench",
        "confidence": 0.48293603002174407
      },
      {
        "text": "Satya Nadella is sitting on a bench",
        "confidence": 0.40037006815422832
      },
      {
        "text": "Satya Nadella sitting in front of a building",
        "confidence": 0.38035155997373377
      }
    ]
  },
  "requestId": "ed2de1c6-fb55-4686-b0da-4da6e05d283f",
  "metadata": {
    "width": 1500,
    "height": 1000,
    "format": "Jpeg"
  }
}

サンプルコード

サンプルコードを載せておきます。

公式リファレンスに載っているサンプルコードにローカル上の画像ファイルのPOST処理、レスポンスバイナリをファイルに書き込む処理を加えたものになります。

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web;

namespace Computer_Vision_API
{
    class Program
    {
        static void Main(string[] args)
        {
            string filename = /*ファイルパス*/;
            DescribeImage(filename);
            Console.WriteLine("Hit ENTER to exit...");
            Console.ReadLine();
        }
        static async void DescribeImage(string fname)
        {
            var client = new HttpClient();
            var queryString = HttpUtility.ParseQueryString(string.Empty);

            // Request headers
            client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", /*取得したSubscription Key*/);

            // Request parameters
            queryString["maxCandidates"] = "1";
            var uri = "https://api.projectoxford.ai/vision/v1.0/describe?" + queryString;

            HttpResponseMessage response;
            
            var fs = new FileStream(fname, FileMode.Open, FileAccess.Read);
            byte[] byteData = new byte[fs.Length];
            fs.Read(byteData, 0, byteData.Length);

            using (var content = new ByteArrayContent(byteData))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                response = await client.PostAsync(uri, content);
            }
            var responceBodyString = await response.Content.ReadAsStringAsync();
            Console.WriteLine(responceBody);
        }
    }
}