VisionAPIで「神奈川沖浪裏」と「夜警」の画像を識別する

# やってることを３行で

- GCPの**VisionAPI**を使って物体検出する方法をまとめてるよ
- **Datalab**上で**GCS**にある画像の検出結果を受け取ってjsonとして出力するよ
- 毛筆で書かれている文字でも検出できるよ（完璧じゃないけどね）

# VisonAPIで物体検出する
[VisionAPI](http://cloud.google.com/vision/)は、GoogleがGCPのサービスとして展開している画像認識に関する機械学習・人工知能系のサービスの一つ

今回はそれを利用して物体検出をする。そして、VisionAPIは直接APIをいじらなくても利用できるけど、プロダクトやサービスに組み込むのを前提にAPIでの実行の仕方をまとめておく

## 1.GCSに画像を置く
自身のGCP環境にアクセスして、Storage(GCS)サービスに移動して任意のバケットを作成する
StorageはAWSのS3みたいなやつ

こんな感じ

![スクリーンショット 2019-04-07 8.37.052.png](https://qiita-image-store.s3.amazonaws.com/0/55225/e1fd94c3-c609-d6a7-b377-1ef5df7a78d2.png)

今回は、gcppde_2019というバケットに画像を入れている前提で話を進める

GCSのバケットの作成方法は以下を参照

[ストレージ バケットの作成【公式リファレンス】](https://cloud.google.com/storage/docs/creating-buckets?hl=ja)

今回は以下の2つの画像を題材にVisionAPIを用いる
1.神奈川沖浪裏　『葛飾北斎(1831-33)』
![1024px-The_Great_Wave_off_Kanagawa.jpg](https://qiita-image-store.s3.amazonaws.com/0/55225/2c7e9e75-5481-25bf-e0e8-1d2b46d199d5.jpeg)

2.夜警 『レンブラント・ファン・レイン(1642)』
![The_Nightwatch.jpg](https://qiita-image-store.s3.amazonaws.com/0/55225/5b8f6053-5df3-ed4d-ff10-1dcc23d25e48.jpeg)


## 2.Datalabを立ち上げる
APIをPython経由でやりとりしたいので、Datalabでインタラクティブに実行する環境を整える

Datalabの起動方法の詳細は以前作成したページもしくは公式リファレンスを参照

[Qiita:Datalabで分析環境を用意する [GCP]](http://qiita.com/Hyperion13fleet/items/583624038204d57884a3)

[公式リファレンス](http://cloud.google.com/datalab/?hl=ja)

## 3. VisionAPIを有効にする(その他の認証も通す)
Datalabを立ち上げて画像をGCS上に用意しただけではまだVisionAPIは使えない

サービスを利用するにあたり、諸々認証を通しておく必要があるらしい
丁寧にフローチャートで手順を紹介してくれていた[codelab developerページ](https://codelabs.developers.google.com/codelabs/cloud-vision-api-python/index.html?index=..%2F..index#0)を参考にcloud shell上で認証を設定

*cloud shellはGCPのホーム画面にあるターミナルアイコンをクリックすると起動する奴

```shell 

# 自身のPROJECT_IDをconfigに書き込み
gcloud config set project <PROJECT_ID>

# visionAPIの機能を有効化
gcloud services enable vision.googleapis.com

# 先ほど設定したPROJECT_IDと同じものを環境変数として設定
export GOOGLE_CLOUD_PROJECT="<PROJECT_ID>"

# VisionAPI用のIAMの作成
gcloud iam service-accounts create my-vision-sa --display-name "my vision service account"

# 上記で作成したサービスアカウントのクレデンシャル情報を生成
gcloud iam service-accounts keys create ~/visionapi_key.json --iam-account my-vision-sa@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

# クレデンシャル情報を環境変数に登録
export GOOGLE_APPLICATION_CREDENTIALS="/home/${USER}/visionapi_key.json"

```

## 4.DatalabでAPIを利用する
DatalabでVisionAPIを利用するにあたり、google-cloud-visionのライブラリを入れる必要があるので、先に`pip install`しておく

### 神奈川沖浪裏の特徴をラベルとして検出する
神奈川沖浪裏の画像のラベルを検出する

＊実際にはDatalab上でAPIを実行している

```python:実際に実行したコード
# visionapiのライブラリをインストールする
!pip install google-cloud-vision -q

from google.cloud import vision
from google.cloud.vision import types

import json

client = vision.ImageAnnotatorClient()
image = vision.types.Image()

# 神奈川沖浪裏をラベル検出する
image_path = 'The_Great_Wave_off_Kanagawa.jpg'
image.source.image_uri = 'gs://gcppde_2019/{image_path}'.format(image_path=image_path)

# ラベルの検出
resp = client.label_detection(image=image)
labels = resp.label_annotations

# ラベル検出結果を辞書に入れる
dict_labels_detection = dict()
for x in labels:
  dict_labels_detection[x.description] = x.score

# jsonに出力する
output_json = 'output.json'
f = open(output_json, "w")
json.dump(dict_labels_detection, f, ensure_ascii=False, indent=4, sort_keys=True, separators=(',', ': '))
f.close()

```
jsonで出力した中身は以下のように出力される

```json:実行結果

{
    "Art": 0.6772549152374268,
    "Graphic design": 0.7239609956741333,
    "Graphics": 0.6353771090507507,
    "Illustration": 0.8577896952629089,
    "Mountain": 0.7596312165260315,
    "Sky": 0.7326111197471619,
    "Water": 0.9684016108512878,
    "Water resources": 0.846031904220581,
    "Wave": 0.9043536186218262,
    "Wind wave": 0.8947387933731079
}

```
**Water**や**Wave**がスコア上位に上がってきているので、この画像の構図のメイン部分は確実に押さえている

**Mountain**もあることから富士山も検知していることがわかる



Datalabではこんな感じで実行している
![スクリーンショット 2019-04-07 10.01.04.png](https://qiita-image-store.s3.amazonaws.com/0/55225/6be5ef1d-b168-8702-9deb-0ebc42c1c59a.png)

### 神奈川沖浪裏の署名をテキスト検出する
次に文字検出のAPIを使ってみる

葛飾北斎の署名はかなり崩した書体で北斎としてしか書かれていないが、どの程度テキスト検出できるだろうか？

タイトルの方は比較的読み取りやすく書かれており、少なくとも現代人でも「富嶽三十六景 神奈川沖浪裏」は読める

APIを使うと

```python

# 文字検出
resp_text = client.text_detection(image=image)
texts = resp_text.text_annotations
[text.description for text in texts]

# 結果
['ˊ袃\nつVy\n冨嶽114-六景禁川(+\n浪喪\n',
 'ˊ',
 '袃',
 'つ',
 'Vy',
 '冨',
 '嶽',
 '114-',
 '六',
 '景',
 '禁',
 '川',
 '(',
 '+',
 '浪',
 '喪']

```
**冨嶽**はイケるのか。。。

旧字体でちゃんと読み取ってるのに**三十六景**はうまくいってない
神奈川沖浪裏も微妙だな。。。

### 物体検出で位置情報を取得する
最後に夜警の人間を人間と識別できるか、どの位置に存在するかを識別できるかをAPIを使って検出する

目検で見る限り顔だけしか書かれていない人も含めて**20人**絵画に描かれている（はず）

```python:夜警の人物を検出
# 物体位置検出

image = vision.types.Image()
# 夜警の人物の位置を検出する
image_path = 'The_Nightwatch.jpg'
image.source.image_uri = 'gs://gcppde_2019/{image_path}'.format(image_path=image_path)

resp_locale = client.object_localization(image=image)
obj_location = resp_locale.localized_object_annotations
obj_location

# 結果
# nameで物体を人間と識別し、その検出範囲の四隅をx,yで表現している
[mid: "/m/01g317"
name: "Person"
score: 0.9664505124092102
bounding_poly {
  normalized_vertices {
    x: 0.5419900417327881
    y: 0.475355863571167
  }
  normalized_vertices {
    x: 0.7189512252807617
    y: 0.475355863571167
  }
  normalized_vertices {
    x: 0.7189512252807617
    y: 0.9799382090568542
  }
  normalized_vertices {
    x: 0.5419900417327881
    y: 0.9799382090568542
  }
}

```

人物を何人検出しているか調べる

```python

resp_locale = client.object_localization(image=image)
obj_location = resp_locale.localized_object_annotations

# 人物を何人検出しているかを調べる
cnt = 0
for objct in obj_location:
  if objct.name == 'Person':
    cnt+=1
    
print(cnt)

>> 5

```

実際の結果から`Person`と識別しているものを数え上げると全部で**5**人を検出している

主に手前にいる人達（体全体が描かれている人達）が検出されている
![スクリーンショット 2019-04-07 10.40.44.png](https://qiita-image-store.s3.amazonaws.com/0/55225/9df4f5bf-40fb-630f-0244-fcdc1d4fddb7.png)


#おわりに
ということで、GCS、Datalab、VisionAPIを使って画像を識別することが出来た

GCPの起動から実際にAPIを利用するまで３０分くらいで全て完結したので、個人的には満足

おしまい


# 参考リンク
[Google Cloud Visionを使ってみる](http://www.itbook.info/web/2016/11/google-cloud-vision%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F.html)

[Google Cloud Vision APIを試してみる](Qiita:http://qiita.com/jkshr/items/7b4495cd80b40ae1173b)

[Google Cloud Visionを使ってなんか作ってみた話](Qiita:http://qiita.com/dkawashi/items/2d35a8e46523ed591d12)