Google Cloud Vision API（画像解析）を30分で試す

# Google Cloud Vision APIとは

Google Cloud Vision APIとは、Googleの機械学習の画像認識APIです。
画像を載せてAPIコールすることで以下の情報の取得が可能です。

| カテゴリ | 判別内容 |
|----|----|
|物体検知|画像に含まれる物体を検知し、乗り物から動物まで多数のカテゴリの中から分類|
|OCR|画像に含まれるテキストを認識して抽出|
|有害コンテンツ検知|画像に含まれるアダルト コンテンツや暴力コンテンツのような有害コンテンツを検知|
|顔検知|画像に映る複数の人物の顔を検知し、感情の状態や帽子類の着用といった顔の主な属性を検知|
|ロゴ検知|画像に含まれるポピュラーな商品や企業のロゴを検知|
|ランドマーク検知|画像に含まれるポピュラーな自然構造物や人工構造物を検知|
|画像特性|画像に関する色データを検出|

# 課金について
Google Cloud Vision APIの課金表は下記となっています。
今回は、トライアル（無料枠）で試します。

![image](https://qiita-image-store.s3.amazonaws.com/0/66824/88c90e26-14b2-95bf-3fe3-05938b15e988.png)

課金の注意点としては、課金の単位はリクエスト数ではなく、ユニット数になります。
例えば、「物体検知」 と 「有害コンテンツ」 を同じ画像について1つのリクエストに含めた場合、「物体検知」で1ユニット、「有害コンテンツ」で1ユニットとカウントされます。

# Google Cloud Vision APIを用意

以下のサイトを参考にAPIキーを取得します。
[Cloud Vision APIの使い方まとめ (サンプルコード付き)](https://syncer.jp/cloud-vision-api)

# 検証

## 環境を用意
今回はPHPを利用して画像に有害コンテンツが含まれるか試すので、下記環境を用意しました。
- CentOS 6.7
- PHP 5.3.3

## サンプルプログラム
下記プログラムをサーバ上に配置
※api_keyの箇所は自分のAPIキーに変更してください。

```lang:サンプルプログラム
<?php
        // APIキー
        $api_key = "XXXXXXXXXXXXXXXXXXXXX" ;

        // 画像へのパス
        $image_path = "$argv[1]" ;

        // リクエスト用のJSONを作成
        $json = json_encode( array(
                "requests" => array(
                        array(
                                "image" => array(
                                        "content" => base64_encode( file_get_contents( $image_path ) ) ,
                                ) ,
                                "features" => array(
                                        array(
                                                "type" => "SAFE_SEARCH_DETECTION" ,
                                                "maxResults" => 3 ,
                                        ) ,
                                ) ,
                        ) ,
                ) ,
        ) ) ;

        // リクエストを実行
        $curl = curl_init() ;
        curl_setopt( $curl, CURLOPT_URL, "https://vision.googleapis.com/v1/images:annotate?key=" . $api_key ) ;
        curl_setopt( $curl, CURLOPT_HEADER, true ) ;
        curl_setopt( $curl, CURLOPT_CUSTOMREQUEST, "POST" ) ;
        curl_setopt( $curl, CURLOPT_HTTPHEADER, array( "Content-Type: application/json" ) ) ;
        curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false ) ;
        curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ) ;
        if( isset($referer) && !empty($referer) ) curl_setopt( $curl, CURLOPT_REFERER, $referer ) ;
        curl_setopt( $curl, CURLOPT_TIMEOUT, 15 ) ;
        curl_setopt( $curl, CURLOPT_POSTFIELDS, $json ) ;
        $res1 = curl_exec( $curl ) ;
        $res2 = curl_getinfo( $curl ) ;
        curl_close( $curl ) ;

        // 取得したデータ
        $json = substr( $res1, $res2["header_size"] ) ;                         // 取得したJSON
        $header = substr( $res1, 0, $res2["header_size"] ) ;            // レスポンスヘッダー

        // 出力
        echo "■出力結果" ;
        echo $argv[1] ;
        echo $json ;

```

## 有害コンテンツ解析について
有害コンテンツ解析の場合、下記4項目に対して解析画像がどのレベルに該当するか判断されます。

■項目

| 項目| 説明 |
|----|----|
|adult|アダルトコンテンツの度合い。|
|spoof|オリジナル画像に対して加工をしたものか。|
|medical|医療要素の度合い。内臓など。|
|violence|暴力性の度合い。|

■レベル

| レベル | 説明 |
|----|----|
|VERY_LIKELY|非常に高いレベル|
|LIKELY|高いレベル|
|POSSIBLE|そうだと言えるレベル|
|UNLIKELY|低いレベル|
|VERY_UNLIKELY|非常に低いレベル|
|NKNOWN|判定不能|

## 検証の実施

検証データとして、下記を用意

- ok01.jpg：有害コンテンツを含まない画像
- ng01.jpg：有害コンテンツを含む画像


```lang:有害コンテンツを含まない画像
# php ./chkimage.php ok01.jpg

================ 以下実行結果 ===============
  "responses": [
    {
      "safeSearchAnnotation": {
        "adult": "VERY_UNLIKELY",
        "spoof": "VERY_UNLIKELY",
        "medical": "VERY_UNLIKELY",
        "violence": "VERY_UNLIKELY"
      }
    }
  ]
}
```
⇒すべてVERY_UNLIKELY（非常に低いレベル）と判断されている為、解析結果は正しいです。

<br>

```lang:有害コンテンツを含む画像
# php ./chkimage.php ng01.jpg

================ 以下実行結果 ===============
  "responses": [
    {
      "safeSearchAnnotation": {
        "adult": "UNLIKELY",
        "spoof": "VERY_UNLIKELY",
        "medical": "POSSIBLE",
        "violence": "VERY_UNLIKELY"
      }
    }
  ]
}
```
⇒内臓系のグロテスクな画像を解析すると、medicalの項目がPOSSIBLE（そうだと言えるレベル）と判断されている為、解析結果は正しいです。


# 感想
- その他の様々な画像(10万枚の画像)でも解析してみましたが、識別精度は約99.997%程正しい結果でした。
- 中には問題ない画像でも有害コンテンツと判断された画像がありましたが、なぜ有害コンテンツと判断されたかは正直、謎です。
- 誰でも簡単にGoogleの画像解析APIを利用できる事は色々な用途で利用できそうだなぁと感じました。