Cloud Vision APIのLABEL_DETECTION
では,画像データをPOST送信するだけで,その画像の中に何が写っているかを瞬時に返してくれる.
https://cloud.google.com/vision/?hl=ja
料金表の説明も書いてあるが,一ヶ月あたり1000リクエストまでは無料なので,一人で実験用に使うくらいなら気にしなくても大丈夫だと思うので使ってみた.実際に試してみると分かるが,ものすごく的確な結果がすばやく返ってくる.かなり興奮した.
ということで,実際にAPIを呼び出して感動するまでの手順を完璧にまとめておく.本記事内で紹介するソースコードとかはコピペすれば動くはずなので,是非実際に好きな写真を与えて実行してみてほしい.
APIキーを取得する
最初のステップは,APIキーを取得する作業.こちらの記事: がとてもわかりやすかった.
途中でAPIキーの種類を選ぶシーンがあり,上記記事では「ブラウザ キー」を選択しているが,本記事ではローカルサーバーからAPIを呼ぶので「サーバー キー」を選択してください.以降の説明ではここで取得したキーをAPI_KEY
と書きます.
ローカルサーバのプログラムを書く
ローカルサーバーのプログラムをPython 2.7で書きます.後述しますが,APIに写真を与えるために自作ツールtfPhotoPaletteを使いました.このツールでは,画像の任意部分を切り抜いたり,サイズを縮小したりできます.
今回書くローカルサーバー側のプログラムは,簡単に書くと以下のように,
- tfPhotoPaletteから画像を受け取って,
- 受け取った画像をCloud Vision APIにセットしてリクエスト送信する.
- Cloud Vision APIから返却されたJSONデータをtfPhotoPaletteに返す
ような処理を担います.この一連の流れが完了すると,tfPhotoPaletteにはラベリングされた結果が表示されます.
まずは,必要なモジュールを以下のようにpipインストールします.
$ pip install flask $ pip install requests
続いて,以下のPythonプログラムを適当な名前(例えばpalette_server.py
)で保存します.関数goog_cloud_vison
内の一行目のAPI_KEY
の部分は先ほど取得したAPIサーバー キーで置き換えてください.*1
# coding: utf-8 from flask import Flask, request, jsonify import urllib import base64 import json import requests app = Flask(__name__) default_port = 52892 GOOGLE_CLOUD_VISION_API_URL = 'https://vision.googleapis.com/v1/images:annotate?key=' def goog_cloud_vison (image_content): api_url = GOOGLE_CLOUD_VISION_API_URL + API_KEY req_body = json.dumps({ 'requests': [{ 'image': { 'content': image_content }, 'features': [{ 'type': 'LABEL_DETECTION', 'maxResults': 10, }] }] }) res = requests.post(api_url, data=req_body) return res.json() @app.route('/', methods=['GET']) def hello (): return 'Hello! This is a palette_server.' @app.route('/api/classify', methods=['POST']) def classify (): # tfPhotoPaletteから受信するJSON形式のリクエスト tfpp_json = request.json if ('jpg' in tfpp_json): image_base64_str = tfpp_json['jpg'].replace('data:image/jpeg;base64,', '') img_jpg = image_base64_str.decode('base64') image_content = base64.b64encode(img_jpg) # Label Detection: Google Cloud Vision で物体認識する res_json = goog_cloud_vison(image_content) # tfPhotoPalette向けの付加情報 res_json['description'] = 'Label Detection (Google Cloud Vision)' return jsonify(res_json) else: return jsonify(description='Bad request') app.run(port=default_port)
tfPhotoPaletteを入手して起動
Chrome ウェブストアからインストールできます. インストールが完了すると,chrome://apps/のリスト内にアプリのアイコンが現れるので,それをクリックすると起動できます.
ローカルサーバを起動
$ python palette_server.py
写真を与えて,Label Detection!
ウィンドウ右下の「Play」ボタンをクリックすると小窓が開きます.左上のセレクトボックスを「Original photo」や「Cropped photo」に設定して,その隣の「Classify」ボタンをクリックします.これでローカルサーバに画像が送信されます.
ローカルサーバは受け取った画像データをセットして,Cloud Vision APIリクエストを送信します.1秒未満待つと,以下のように,先程の小窓にラベル付けされた結果が表示されます.
クリックして拡大
結果をよく見てみると,vegetable
が入っているsoup
っぽいcurry
という状況が完璧に説明されています.驚いた.
余談
ラベリング結果のJSONに含まれるmid
というのは,Freebaseというナレッジグラフ上での固有IDらしい.実際にFreebaseのウェブサイトで検索してみるとcurry
が/m/0hr1s_w
となっていることが確認できる.*2