Cloud Vision API を使用し、シンプルな REST API 内のパワフルな機械学習モデルをカプセル化することで、画像の内容を把握できます。

このコードラボでは、Vision API に画像を送信し、物体や顔、ランドマークが検出される様子を確認します。

学習すること

必要になるもの

チュートリアルの使用目的を教えてください

通読のみ 通読して、演習を行う

Google Cloud Platform の使用経験を教えてください

初心者 中級者 上級者

カンファレンス用コードラボのセットアップ

全てのパソコンは Codelab のみの使用となります!

ログイン後https://kiosk.gcplab.me/next17-tokへアクセスしてください。

退出なさる時はログアウトを忘れずにお願いいたします。

講師は、セットアップ済みの既存のプロジェクトで一時アカウントをあなたと共有するので、課金の有効化や本コードラボの実行に伴うコストについては心配いりません。それらのアカウントはすべて、コードラボ終了直後に無効化されます。

ログインに使用する一時ユーザー名/パスワードを講師から受け取った後、Google Cloud Console にログインします。https://console.cloud.google.com/.

割り当てられたプロジェクト ID をメモしてください (上のスクリーンショットでは「next17-tok-xxxx」)。以降、本コードラボでは PROJECT_ID と呼びます。

Google Cloud Shell を起動する

Google Cloud はラップトップからリモートで操作できるため、本コードラボでは、Cloud で動作するコマンドライン環境である Google Cloud Shell を使用します。この Debian ベース仮想マシンには、必要なすべての開発ツール (docker、gcloud、kubectl など) がロードされています。それは、永続的な 5GB ホームディレクトリを提供し、Google Cloud で動作し、ネットワーク性能と認証を大幅に改善します。そのため、本コードラボに必要なものは、ブラウザのみです (本コードラボは Chromebook でも動作します)

Google Cloud Shell をアクティブにするには、開発者コンソールで右上のボタンをクリックするだけです (プロビジョニングと環境への接続には数分しかかかりません)。

クラウド シェルに接続すると、すでに認証済みであり、プロジェクトがすでに PROJECT_ID に設定されていることが分かります。

$ gcloud auth list
認定済みアカウント:
 - <myaccount>@<mydomain>.com (アクティブ)
$ gcloud config list project
[core]
project = <PROJECT_ID>

何かしらの理由でプロジェクトが設定されていない場合、次のコマンドを発行してください。

$ gcloud config set project <PROJECT_ID>

PROJECT_ID が分かりませんか?セットアップステップでどの ID を使用したかを確認するか、コンソール ダッシュボードで検索してください。

画面の左上にあるメニューアイコンをクリックします。

ドロップダウンで [API Manager] を選択します。

[API を有効にする] をクリックします。

次に、検索ボックスで「vision」を検索します。[Google Cloud Vision API] をクリックします。

有効にする」をクリックして、Cloud Vision API を有効にします。

有効になるまで数秒待ちます。有効になると、以下のように表示されます。

Vision API には curl を使用してリクエストを送信することになります。そこで、リクエスト URL 内で渡すための API キーを生成する必要がでてきます。API キーを作成するために、プロジェクト ダッシュボードの [API Manager] セクションに移動します。

次に、[認証情報] タブを選択して、[認証情報を作成] をクリックします。

ドロップダウン メニューで [API キー] を選択します。

次に、生成されたキーをコピーします。

これで API キーが手に入りました。リクエストするたびに API キーの値を挿入しなくてすむように、生成した API キーを環境変数に保存します。キーの保存は Cloud Shell で行えます。以下の <your_api_key> を、先ほどコピーしたキーに置き換えてください。

export API_KEY=<YOUR_API_KEY>

Cloud Storage バケットを作成する

画像検出のために Vision API に画像を送信する方法は 2 通りあります。1 つは、API に base64 エンコードの画像文字列を送信する方法、もう 1 つは Google Cloud Storage に保存したファイルの URL を API に渡す方法です。ここでは Cloud Storage の URL を使用します。これを行うには、最初に画像を保存するための Google Cloud Storage バケットを作成する必要があります。

ご自分のプロジェクトの Cloud Console で [Storage] を開きます。

次に、[バケットを作成] をクリックします。ご自分の一意のバケット名(ご自分のプロジェクト ID など)を入力し、[作成] をクリックします。

画像をバケットにアップロードする

下のドーナツの画像を右クリックして [名前を付けて画像を保存] をクリックし、donuts.jpeg としてダウンロード フォルダに保存します。

先ほど Storage ブラウザに作成したバケットに移動し、[ファイルをアップロード] をクリックしてから donuts.jpeg を選択します。

バケットにファイルが入っていることがわかります。

これでご自分のバケットにファイルが入り、Vision API へのリクエストを作成し、このドーナツの写真の URL を渡せるようになりました。

ご自分の Cloud Shell 環境で、以下を使用して request.json ファイルを作成します。その際、「my-bucket-name」を、作成した Cloud Storage のバケット名に置き換えてください。

request.json

{
  "requests": [
      {
        "image": {
          "source": {
              "gcsImageUri": "gs://my-bucket-name/donuts.jpeg"
          } 
        },
        "features": [
          {
            "type": "LABEL_DETECTION",
            "maxResults": 10
          }
        ]
      }
  ]
}

最初に、Cloud Vision API のラベル検出機能について見てみましょう。このメソッドは、画像に含まれる物体のラベル(単語)の一覧を返します。

Vision API を呼び出す前に、Vision API のリード アクセスを許可するために、バケット内の画像へのアクセスを更新する必要があります。以下のコマンドを実行して、この画像へのグローバル リード アクセスを許可します。その際、「my-storage-bucket」を、ご自分のバケット名に置き換えてください。このコマンドは、コマンドラインから Cloud Storage へのアクセスを可能にする、デフォルトで Cloud Shell 環境にインストールされている gsutil を使用します。

gsutil acl ch -g AllUsers:R gs://my-storage-bucket/donuts.jpeg

これで curl を使って Vision API を呼び出す準備が整いました。

curl -s -X POST -H "Content-Type: application/json" --data-binary @request.json  https://vision.googleapis.com/v1/images:annotate?key=${API_KEY}

以下のようなレスポンスが返されます。

{
  "labelAnnotations": [
    {
      "mid": "/m/02wbm",
      "description": "Food",
      "score": 94
    },
    {
      "mid": "/m/0ggjl84",
      "description": "Baked Goods",
      "score": 90
    },
    {
      "mid": "/m/02q08p0",
      "description": "Dish",
      "score": 85
    },
    {
      "mid": "/m/0270h",
      "description": "Dessert",
      "score": 83
    },
    {
      "mid": "/m/0bp3f6m",
      "description": "Fried Food",
      "score": 75
    },
    {
      "mid": "/m/01wydv",
      "description": "Beignet",
      "score": 67
    },
    {
      "mid": "/m/0pqdc",
      "description": "Hors D Oeuvre",
      "score": 54
    }
  ]
}

API は見事に、ドーナツの具体的な種類(Beignet=ベニエ)まで特定することができました。Vision API は、見つけ出した各ラベルについて、その項目の名前とともに description を返します。また API は、画像内の物体と記述が一致している信頼度を示す 0~100 の数値として score も返します。mid の値は、Google のナレッジ グラフ内の該当項目の mid を呼び出します。該当項目に関する詳細な情報を取得するためにナレッジ グラフ API を呼び出すときは、その mid を使用できます。

次に、Vision API の顔検出とランドマーク検出のメソッドを見てみましょう。顔検出メソッドは、画像内で発見された顔に関するデータを返します。このデータには、その顔の感情や画像内での位置も含まれます。ランドマーク検出は、一般的なランドマークや曖昧なランドマークを特定し、そのランドマークの名前や経度と緯度の座標、そのランドマークが特定された画像内の位置を返します。

新しい画像をアップロードする

この 2 つの新しいメソッドを使うために、顔とランドマークが写っている新しい画像を Cloud Storage バケットにアップロードしましょう。以下の画像を右クリックして [名前を付けて画像を保存] をクリックし、selfie.jpeg としてダウンロード フォルダに保存します。

次に、前の手順と同じ方法で、ダウンロードしたファイルをご自分の Cloud Storage バケットにアップロードします。写真のアップロードが完了したら、以下の gsutil コマンドを使って新しい画像へのアクセス制御を更新します。

gsutil acl ch -g AllUsers:R gs://my-storage-bucket/selfie.jpeg

リクエストを更新する

次に、ラベル検出の代わりに顔検出とランドマーク検出を使用するために request.json ファイルを更新し、新しい画像の URL も含めます。「my-bucket-name」は、ご自分の Cloud Storage のバケット名に置き換えてください。

request.json

{
  "requests": [
      {
        "image": {
          "source": {
              "gcsImageUri": "gs://my-bucket-name/selfie.jpeg"
          } 
        },
        "features": [
          {
            "type": "FACE_DETECTION"
          },
          {
            "type": "LANDMARK_DETECTION"
          }
        ]
      }
  ]
}

Vision API を呼び出してレスポンスを解析する

これで前の手順と同じ curl コマンドを使って Vision API を呼び出す準備が整いました。:

curl -s -X POST -H "Content-Type: application/json" --data-binary @request.json  https://vision.googleapis.com/v1/images:annotate?key=${API_KEY}

まず、レスポンスの faceAnnotations オブジェクトを確認してみましょう。画像内に見つかった各顔(この場合は 3 つ)について、API がオブジェクトを返していることがわかります。省略したレスポンスは以下のとおりです。

{
      "faceAnnotations": [
        {
          "boundingPoly": {
            "vertices": [
              {
                "x": 669,
                "y": 324
              },
              ...
            ]
          },
          "fdBoundingPoly": {
            ...
          },
          "landmarks": [
            {
              "type": "LEFT_EYE",
              "position": {
                "x": 692.05646,
                "y": 372.95868,
                "z": -0.00025268539
              }
            },
            ...
          ],
          "rollAngle": 0.21619819,
          "panAngle": -23.027969,
          "tiltAngle": -1.5531756,
          "detectionConfidence": 0.72354823,
          "landmarkingConfidence": 0.20047489,
          "joyLikelihood": "POSSIBLE",
          "sorrowLikelihood": "VERY_UNLIKELY",
          "angerLikelihood": "VERY_UNLIKELY",
          "surpriseLikelihood": "VERY_UNLIKELY",
          "underExposedLikelihood": "VERY_UNLIKELY",
          "blurredLikelihood": "VERY_UNLIKELY",
          "headwearLikelihood": "VERY_LIKELY"
        }
        ...
     }
}

boundingPoly からは、画像内の顔周辺の x, y 座標がわかります。fdBoundingPolyboundingPoly よりも小さいボックスで、顔の皮膚部分でエンコードされます。landmarks は、顔の各特徴に対するオブジェクトの配列です(初めて見るものも含まれているかもしれません)。この値からは、ランドマークの種類とともに、その特徴の 3 次元の位置(x, y, z 座標)がわかります。この z 座標は奥行きを示しています。残りの値からは、楽しさや悲しみ、怒り、驚きの尤度など、その顔の詳細がわかります。上記のオブジェクトは、画像内で一番奥の人物のものです。彼はおどけた表情をしていますが、それが joyLikelihoodPOSSIBLE という値に表れています。

次に、レスポンスの landmarkAnnotations の部分を見てみましょう。

"landmarkAnnotations": [
        {
          "mid": "/m/0c7zy",
          "description": "Petra",
          "score": 0.5403372,
          "boundingPoly": {
            "vertices": [
              {
                "x": 153,
                "y": 64
              },
              ...
            ]
          },
          "locations": [
            {
              "latLng": {
                "latitude": 30.323975,
                "longitude": 35.449361
              }
            }
          ]

ここで Vision API は、この写真がペトラ遺跡で撮影されたことを理解することができました。この画像に含まれる視覚的な手掛かりがほとんどないことを踏まえると、これは実に見事だといえます。このレスポンスに含まれる値は、前述の labelAnnotations のレスポンスに似ています。

このレスポンスからは、ランドマークの mid、ランドマークの名前(description)、および信頼度(score)がわかります。boundingPoly には、ランドマークが特定された画像内の領域が示されています。locations キーからはこのランドマークの経度と緯度の座標がわかります。

ここまで、Vision API のラベル検出、顔検出、およびランドマーク検出のメソッドを見てきましたが、その他にまだ 3 つのメソッドがあります。他の 3 つのメソッドについては、ドキュメントをご覧ください。

このコードラボでは、Vision API を使用して画像を分析する方法について学びました。今回の例では、ご自分のファイルの Google Cloud Storage の URL を API に渡しましたが、画像の base64 エンコードの文字列を渡すこともできます。

学習したこと

次のステップ