Cloud Vision API のリクエストとレスポンス

このドキュメントでは、Google Cloud Vision API REST のリクエストとレスポンスについて説明します。このドキュメントの前に、スタートガイドをお読みになることをおすすめします。Vision API タスクを実行するためのアプリケーションの開発に関するチュートリアルについては、ラベル チュートリアルをご覧ください。

POST リクエスト

Cloud Vision API は使いやすい REST API で、リクエスト内で送信した画像のデータ解析を HTTP POST オペレーションにより実行します。この API ではリクエストとレスポンスの両方で JSON を使用します。一般的な Vision API JSON リクエストには、検出対象の画像(1 つまたは複数)の内容と、各画像に対して行う一連のオペレーション(「機能」)が含まれます。

現時点では、Vision API は 1 つのコレクション(images)で構成されます。このコレクションは 1 つの HTTP リクエスト メソッド(annotate)をサポートしています。

POST https://vision.googleapis.com/v1/images:annotate

(完全な詳細については、Vision API リファレンスをご覧ください。将来的に他のコレクションやメソッドが追加される可能性があります。)

この POST リクエストの認証には、API キーまたは OAuth トークンを POST リクエストのヘッダー内から直接渡しす必要があります。API では(GET リクエストではなく)POST リクエストを使用する必要があります。これにより、認証パラメータを、リクエスト URL に埋め込むかわりにリクエスト ペイロード内で渡せるようになります。POST リクエストおよびレスポンスの JSON 形式については以下で説明します。

JSON リクエスト形式

annotate リクエストは AnnotateImageRequest タイプの JSON リクエストを渡します。以下に例を示します。

{
  "requests":[
    {
      "image":{
        "content":"/9j/7QBEUGhvdG9...image contents...eYxxxzj/Coa6Bax//Z"
      },
      "features":[
        {
          "type":"LABEL_DETECTION",
          "maxResults":1
        }
      ]
    }
  ]
}

これらのフィールドの概要を以下に示します。AnnotateImageRequest フィールドについて詳しくは、Vision API リファレンスをご覧ください。

  • requests - リクエストの配列。画像ごとに 1 つ必要です。
    • image - このリクエストの画像データ。この image フィールドには子 content フィールドまたは子 source フィールドが含まれている必要があります。
      • content - 画像の内容。base64 でエンコードします。
      • source - このリクエストの画像ソース。
        • gcs_image_uri - このリクエストで使用する特定の画像の Google Cloud Storage URI。ワイルドカードは使用できません。
    • features - この画像を検出するための機能の配列。
      • type - 機能の種類([Vision API リクエストの種類](#feature-types)をご覧ください)。
      • maxResults - この機能の種類で返される結果の最大数。API が返す結果の数はこれより少ない場合もあります。

Google Cloud Storage に保存されている画像へのリンクを設定することができます。これらの画像には、Vision API リクエストで使用している認証情報を使用してアクセスできる必要があります。以下に例をあげます。

  • ユーザーが OAuth ユーザー認証情報を使用してアクセスする。
  • Vision API サービス アカウントにより、OAuth サービス アカウント認証情報を使用するアプリケーションからアクセスする。
  • 一般公開されている。

Cloud Storage URI を使用する AnnotateImageRequest の例を以下に示します。

{
  "requests":[
    {
      "image":{
        "source":{
          "gcs_image_uri":
            "gs://bucket_name/path_to_image_object"
        }
      },
      "features":[
        {
          "type":"LABEL_DETECTION",
          "maxResults":1
        }
      ]
    }
  ]
}

Vision API リクエストのタイプ

Vision API リクエスト内の画像ごとに、検出する機能を 1 つ以上指定し、画像ごとの features 配列内で渡すことができます。以下にタイプの一覧を示します。

機能のタイプ説明
LABEL_DETECTION 画像全体に対して画像コンテンツ分析を実行し、結果を返します。
TEXT_DETECTION 画像内のテキストに対して光学式文字認識(OCR)を実行します。
FACE_DETECTION 画像内の顔を検出します。
LANDMARK_DETECTION 画像内の地理的ランドマークを検出します。
LOGO_DETECTION 画像内の企業ロゴを検出します。
SAFE_SEARCH_DETECTION 画像の画像セーフサーチ プロパティを判別します。
IMAGE_PROPERTIES 画像の一連のプロパティ(画像のドミナント カラーなど)を計算します。

実行する機能解析を features 配列で列挙すると、任意の画像に対して複数の機能検出を実行できます。

{
  "requests":[
    {
      "image":{
        "content":"/9j/7QBEUGhvdG9zaG9...image contents...fXNWzvDEeYxxxzj/Coa6Bax//Z"
      },
      "features":[
        {
          "type":"FACE_DETECTION",
          "maxResults":10
        },
        {
          "type":"LABEL_DETECTION",
          "maxResults":10
        }
      ]
    }
  ]
}

JSON レスポンスの形式

annotate リクエストは、タイプが AnnotateImageResponse である JSON レスポンスを受け取ります。リクエストはどの機能タイプでも類似していますが、レスポンスは機能タイプごとに大きく異なる場合があります。詳細については、Vision API リファレンスをご覧ください。

LABEL_DETECTION レスポンス

LABEL_DETECTION リクエストは、EntityAnnotation タイプの一連の labelAnnotations が含まれるレスポンスを生成します。

次のコード例は、以下の写真で上位 5 件の一致に対するラベル検出の例です。

{
  "responses": [
    {
      "labelAnnotations": [
        {
          "mid": "/m/0bt9lr",
          "description": "dog",
          "score": 0.97346616
        },
        {
          "mid": "/m/09686",
          "description": "vertebrate",
          "score": 0.85700572
        },
        {
          "mid": "/m/01pm38",
          "description": "clumber spaniel",
          "score": 0.84881884
        },
        {
          "mid": "/m/04rky",
          "description": "mammal",
          "score": 0.847575
        },
        {
          "mid": "/m/02wbgd",
          "description": "english cocker spaniel",
          "score": 0.75829375
        }
      ]
    }
  ]
}

FACE_DETECTION レスポンス

FACE_DETECTION リクエストは、FaceAnnotation タイプの一連の faceAnnotations が含まれるレスポンスを生成します。

次のコード例は、以下の写真に対する顔検出レスポンスの例です。

{
  "responses":[
    {
      "faceAnnotations":[
        {
          "boundingPoly":{
            "vertices":[
              {
                "x":1916,
                "y":870
              },
              {
                "x":2106,
                "y":870
              },
              {
                "x":2106,
                "y":1091
              },
              {
                "x":1916,
                "y":1091
              }
            ]
          },
          "fdBoundingPoly":{
            "vertices":[
              {
                "x":1923,
                "y":910
              },
              {
                "x":2081,
                "y":910
              },
              {
                "x":2081,
                "y":1068
              },
              {
                "x":1923,
                "y":1068
              }
            ]
          },
          "landmarks":[
            {
              "type":"LEFT_EYE",
              "position":{
                "x":1969.4862,
                "y":955.17334,
                "z":-0.0016533856
              }
            },
            {
              "type":"RIGHT_EYE",
              "position":{
                "x":2019.262,
                "y":967.91278,
                "z":-28.925787
              }
            },
            {
              "type":"LEFT_OF_LEFT_EYEBROW",
              "position":{
                "x":1959.3801,
                "y":939.696,
                "z":14.981886
              }
            },
            {
              "type":"RIGHT_OF_LEFT_EYEBROW",
              "position":{
                "x":1980.2725,
                "y":943.3717,
                "z":-15.975462
              }
            },
            {
              "type":"LEFT_OF_RIGHT_EYEBROW",
              "position":{
                "x":2003.1469,
                "y":948.81323,
                "z":-29.651102
              }
            },
            {
              "type":"RIGHT_OF_RIGHT_EYEBROW",
              "position":{
                "x":2040.1477,
                "y":961.9339,
                "z":-32.134441
              }
            },
            {
              "type":"MIDPOINT_BETWEEN_EYES",
              "position":{
                "x":1987.4386,
                "y":956.79248,
                "z":-24.352777
              }
            },
            {
              "type":"NOSE_TIP",
              "position":{
                "x":1969.6227,
                "y":985.49719,
                "z":-41.193481
              }
            },
            {
              "type":"UPPER_LIP",
              "position":{
                "x":1972.1095,
                "y":1007.2608,
                "z":-30.672895
              }
            },
            {
              "type":"LOWER_LIP",
              "position":{
                "x":1968.515,
                "y":1027.6235,
                "z":-28.315508
              }
            },
            {
              "type":"MOUTH_LEFT",
              "position":{
                "x":1957.8792,
                "y":1013.6796,
                "z":-6.6342912
              }
            },
            {
              "type":"MOUTH_RIGHT",
              "position":{
                "x":1998.7747,
                "y":1022.9999,
                "z":-28.734522
              }
            },
            {
              "type":"MOUTH_CENTER",
              "position":{
                "x":1971.396,
                "y":1017.4032,
                "z":-27.534792
              }
            },
            {
              "type":"NOSE_BOTTOM_RIGHT",
              "position":{
                "x":1993.8416,
                "y":995.19,
                "z":-29.759504
              }
            },
            {
              "type":"NOSE_BOTTOM_LEFT",
              "position":{
                "x":1965.5908,
                "y":989.42383,
                "z":-13.663703
              }
            },
            {
              "type":"NOSE_BOTTOM_CENTER",
              "position":{
                "x":1974.8154,
                "y":995.68555,
                "z":-30.112482
              }
            },
            {
              "type":"LEFT_EYE_TOP_BOUNDARY",
              "position":{
                "x":1968.6737,
                "y":950.9704,
                "z":-3.0559144
              }
            },
            {
              "type":"LEFT_EYE_RIGHT_CORNER",
              "position":{
                "x":1978.8079,
                "y":958.23712,
                "z":-5.4053364
              }
            },
            {
              "type":"LEFT_EYE_BOTTOM_BOUNDARY",
              "position":{
                "x":1967.8793,
                "y":959.22345,
                "z":-0.62461489
              }
            },
            {
              "type":"LEFT_EYE_LEFT_CORNER",
              "position":{
                "x":1962.1622,
                "y":954.26093,
                "z":10.204804
              }
            },
            {
              "type":"LEFT_EYE_PUPIL",
              "position":{
                "x":1967.9233,
                "y":954.9704,
                "z":-0.77994776
              }
            },
            {
              "type":"RIGHT_EYE_TOP_BOUNDARY",
              "position":{
                "x":2016.6268,
                "y":962.88623,
                "z":-31.205936
              }
            },
            {
              "type":"RIGHT_EYE_RIGHT_CORNER",
              "position":{
                "x":2029.2314,
                "y":970.985,
                "z":-29.216293
              }
            },
            {
              "type":"RIGHT_EYE_BOTTOM_BOUNDARY",
              "position":{
                "x":2017.429,
                "y":972.17621,
                "z":-28.954475
              }
            },
            {
              "type":"RIGHT_EYE_LEFT_CORNER",
              "position":{
                "x":2007.4708,
                "y":965.36237,
                "z":-22.286636
              }
            },
            {
              "type":"RIGHT_EYE_PUPIL",
              "position":{
                "x":2017.0439,
                "y":967.18329,
                "z":-29.732374
              }
            },
            {
              "type":"LEFT_EYEBROW_UPPER_MIDPOINT",
              "position":{
                "x":1969.7963,
                "y":934.11523,
                "z":-3.3017645
              }
            },
            {
              "type":"RIGHT_EYEBROW_UPPER_MIDPOINT",
              "position":{
                "x":2021.7909,
                "y":947.04419,
                "z":-33.841984
              }
            },
            {
              "type":"LEFT_EAR_TRAGION",
              "position":{
                "x":1963.6063,
                "y":987.89252,
                "z":77.398705
              }
            },
            {
              "type":"RIGHT_EAR_TRAGION",
              "position":{
                "x":2075.2998,
                "y":1016.2071,
                "z":13.859237
              }
            },
            {
              "type":"FOREHEAD_GLABELLA",
              "position":{
                "x":1991.0243,
                "y":945.11224,
                "z":-24.655386
              }
            },
            {
              "type":"CHIN_GNATHION",
              "position":{
                "x":1964.3625,
                "y":1055.4045,
                "z":-23.147352
              }
            },
            {
              "type":"CHIN_LEFT_GONION",
              "position":{
                "x":1948.226,
                "y":1019.5986,
                "z":52.048538
              }
            },
            {
              "type":"CHIN_RIGHT_GONION",
              "position":{
                "x":2046.8456,
                "y":1044.8068,
                "z":-6.1001
              }
            }
          ],
          "rollAngle":16.066454,
          "panAngle":-29.752207,
          "tiltAngle":3.7352962,
          "detectionConfidence":0.98736823,
          "landmarkingConfidence":0.57041687,
          "joyLikelihood":0.90647823,
          "sorrowLikelihood":4.1928422e-05,
          "angerLikelihood":0.00033951481,
          "surpriseLikelihood":0.0024809798,
          "underExposedLikelihood":3.5745124e-06,
          "blurredLikelihood":0.00038755304,
          "headwearLikelihood":1.1718362e-05
        }
      ]
    }
  ]
}

JSON リクエストの生成

このセクションの例では、Python スクリプトを使用して Cloud Vision AnnotateImageRequest を作成しています。

import argparse
import base64
import json
import sys

def main(input_file, output_filename):
    """Translates the input file into a json output file.

    Args:
        input_file: a file object, containing lines of input to convert.
        output_filename: the name of the file to output the json to.
    """
    request_list = []
    for line in input_file:
        image_filename, features = line.lstrip().split(' ', 1)

        with open(image_filename, 'rb') as image_file:
            content_json_obj = {
                'content': base64.b64encode(image_file.read()).decode('UTF-8')
            }

        feature_json_obj = []
        for word in features.split(' '):
            feature, max_results = word.split(':', 1)
            feature_json_obj.append({
                'type': get_detection_type(feature),
                'maxResults': int(max_results),
            })

        request_list.append({
            'features': feature_json_obj,
            'image': content_json_obj,
        })

    with open(output_filename, 'w') as output_file:
        json.dump({'requests': request_list}, output_file)

DETECTION_TYPES = [
    'TYPE_UNSPECIFIED',
    'FACE_DETECTION',
    'LANDMARK_DETECTION',
    'LOGO_DETECTION',
    'LABEL_DETECTION',
    'TEXT_DETECTION',
    'SAFE_SEARCH_DETECTION',
]

def get_detection_type(detect_num):
    """Return the Vision API symbol corresponding to the given number."""
    detect_num = int(detect_num)
    if 0 < detect_num < len(DETECTION_TYPES):
        return DETECTION_TYPES[detect_num]
    else:
        return DETECTION_TYPES[0]

Python スクリプトは、一連の画像に対して実行する機能検出を指定する入力テキスト ファイルを読み取ります。入力ファイルの各行には、画像ごとに、画像のパスと、「feature:max_results」という形式の機能指定子が記述されています。機能は 1~6 の整数値を使用して(上述の get_detection_type() 関数の定義のように)マップされています。

たとえば、スクリプトに対する次の入力ファイルは、image1 に対する顔およびラベル検出注釈と、image2 に対するランドマークおよびロゴ検出注釈を要求します。いずれも注釈ごとの結果の最大数は 10 件です。

filepath_to_image1.jpg 1:10 4:10
filepath_to_image2.png 2:10 3:10

スクリプトはダウンロードして実行できます。入力ファイルと出力ファイルは次のように指定します。

python generatejson.py -i <inputfile> -o <outputfile>

次のサブセクションの例では、サンプル画像に対して Cloud Vision AnnotateImageRequest を生成し、curlPython を使用してリクエストを送信し、Cloud Vision から返された AnnotateImageResponse を表示しています。

生成されたリクエストを Curl を使用して送信

次の例では、Cloud Vision が次の画像に対して注釈を付けています。

スクリプトの入力ファイル visioninfile.txt には、画像ファイルのパスのリストが記録されています。また、ランドマーク(2)、ロゴ(3)、ラベル(4)の 3 つの機能注釈が画像に対して指定されています。すべての注釈について、最大で 10 件のレスポンスが指定されます。

/Users/username/<username>/desktv.jpg 2:10 3:10 4:10

スクリプトの実行時には入力ファイル引数と出力ファイル引数が使用されます。出力は vision.json に書き込まれます。注: 読みやすいように、以下の例では行が続いていることを示す「\」を使ってコマンドを複数行に分けて表記しています。このコマンドを実行すると、コマンドとすべての引数が 1 行のコマンドラインで入力されます。

python generatejson.py \
    -i /Users/<username>/testdata/visioninfile \
    -o /Users/<username>/testdata/vision.json

このスクリプトは入力ファイルを処理して、画像について要求された機能注釈をコンソールに表示し、組み立てられたリクエストを vision.json に書き込みます。

/Users/<username>/testdata/desktv.jpg 2:10 3:10 4:10
detect:LANDMARK_DETECTION
results: 10
detect:LOGO_DETECTION
results: 10
detect:LABEL_DETECTION
results: 10

生成される JSON の内容は、次のように切り捨てられ、フォーマットされます。

{
   "requests": [
      {
         "image": {
            "content": "/9j/4AAQS...0LSP//Z"
         },
         "features": [
            {
               "type": "LANDMARK_DETECTION",
               "maxResults": "10"
            },
            {
               "type": "LOGO_DETECTION",
               "maxResults": "10"
            },
            {
               "type": "LABEL_DETECTION",
               "maxResults": "10"
            }
         ]
      }
   ]
}

Cloud Vision にリクエストを送信するために、curl が使用されます。

curl -v -k -s -H "Content-Type: application/json" \
    https://vision.googleapis.com/v1/images:annotate?key=<API-key> \
    --data-binary @/Users/<username>/testdata/vision.json

Cloud Vision API がレスポンスを返します。この画像ではランドマークとロゴは検出されていないため、レスポンスには landmarkAnnotation および logoAnnotation オブジェクトがありません。レスポンスにある複数のラベル注釈が、信頼度スコアの高い順に並べ替えられます。

 ...
 {
   "responses": [
     {
       "labelAnnotations": [
         {
           "mid": "/m/0c_jw",
           "description": "furniture",
           "score": 0.91564965
         },
         {
           "mid": "/m/01y9k5",
           "description": "desk",
           "score": 0.2922152
         },
         {
           "mid": "/m/04bcr3",
           "description": "table",
           "score": 0.12354217
         },
         {
           "mid": "/m/03vf67",
           "description": "sideboard",
           "score": 0.10264879
         },
         {
           "mid": "/m/06ht1",
           "description": "room",
           "score": 0.056943923
         },
         {
           "mid": "/m/078n6m",
           "description": "coffee table",
           "score": 0.051967125
         },
         {
           "mid": "/m/03qh03g",
           "description": "media",
           "score": 0.031322964
         },
         {
           "mid": "/m/0fqfqc",
           "description": "drawer",
           "score": 0.030417876
         },
         {
           "mid": "/m/02z51p",
           "description": "nightstand",
           "score": 0.024424918
         },
         {
           "mid": "/m/07c52",
           "description": "television",
           "score": 0.01784919
         }
       ]
     }
   ]
 }

生成されたリクエストを Python で送信

この例では、次の画像に対する Cloud Vision 注釈を要求しています。

スクリプトの入力ファイル visioninfile.txt には、画像ファイルの URI が含まれています。また、ロゴ(3)、ラベル(4)、テキスト(5)の 3 つの機能注釈があり、注釈ごとに最大 10 件のレスポンスがあります。

/Users/<username>/testdata/google.jpg 3:10 4:10 5:10

スクリプトの実行時には入力ファイル引数と出力ファイル引数が使用されます。出力は vision.json に書き込まれます。注: 読みやすいように、以下の例では行が続いていることを示す「\」を使ってコマンドを複数行に分けて表記しています。このコマンドを実行すると、コマンドとすべての引数が 1 行のコマンドラインで入力されます。

python generatejson.py \
    -i /Users/<username>/testdata/visioninfile.txt \
    -o /Users/<username>/testdata/vision.json

スクリプトは入力ファイルを処理し、要求された機能注釈の概要をコンソールに表示します。

detect:LOGO_DETECTION
results: 10
detect:LABEL_DETECTION
results: 10
detect:TEXT_DETECTION
results: 10

さらに、組み立てられた JSON リクエストを vision.json に書き込みます(内容は以下のように切り捨てられ、フォーマットされます)。

{
  "requests": [
    {
      "image": {
        "content": "/9j/4...A//9k="
       },
       "features": [
          {
            "type": "LOGO_DETECTION",
            "maxResults": "10"
          },
          {
            "type": "LABEL_DETECTION",
             "maxResults": "10"
          },
          {
            "type": "TEXT_DETECTION",
            "maxResults": "10"
          }
       ]
     }
  ]
}

Python を使用してリクエストが Cloud Vision に送信され、レスポンスが表示されます。レスポンスにある複数のラベル注釈が、信頼度スコアの高い順に並べ替えられます。

$ python
...
>>> import requests
>>> data = open('/Users/<username>/testdata/vision.json', 'rb').read()
>>> response = requests.post(url='https://vision.googleapis.com/v1/images:annotate?key=<API-key>',
    data=data,
    headers={'Content-Type': 'application/json'})
>>> print response.text
{
  "responses": [
    {
      "logoAnnotations": [
        {
          "mid": "/m/045c7b",
          "description": "Google",
          "score": 0.35000956,
          "boundingPoly": {
            "vertices": [
              {
                "x": 158,
                "y": 50
              },
              {
                "x": 515,
                "y": 50
              },
              {
                "x": 515,
                "y": 156
              },
              {
                "x": 158,
                "y": 156
              }
            ]
          }
        }
      ],
      "labelAnnotations": [
        {
          "mid": "/m/021sdg",
          "description": "graphics",
          "score": 0.67143095
        },
        {
          "mid": "/m/0dgsmq8",
          "description": "artwork",
          "score": 0.66358012
        },
        {
          "mid": "/m/0dwx7",
          "description": "logo",
          "score": 0.31318793
        },
        {
          "mid": "/m/01mf0",
          "description": "software",
          "score": 0.23124418
        },
        {
          "mid": "/m/03g09t",
          "description": "clip art",
          "score": 0.20368107
        },
        {
          "mid": "/m/02ngh",
          "description": "emoticon",
          "score": 0.19831011
        },
        {
          "mid": "/m/0h8npc5",
          "description": "digital content software",
          "score": 0.1769385
        },
        {
          "mid": "/m/03tqj",
          "description": "icon",
          "score": 0.097528793
        },
        {
          "mid": "/m/0hr95w1",
          "description": "pointer",
          "score": 0.03663468
        },
        {
          "mid": "/m/0n0j",
          "description": "area",
          "score": 0.033584446
        }
      ],
      "textAnnotations": [
        {
          "locale": "en",
          "description": "Google\n",
          "boundingPoly": {
            "vertices": [
              {
                "x": 61,
                "y": 26
              },
              {
                "x": 598,
                "y": 26        },

              },
              {
                "x": 598,
                "y": 227
              },
              {
                "x": 61,
                "y": 227
              }
            ]
          }
        }
      ]
    }
  ]
}
>>>

外出先でもリソースをモニタリング

Google Cloud Console アプリを入手して、プロジェクトの管理にお役立てください。

フィードバックを送信...

Google Cloud Vision API ドキュメント