Google Cloud Vision APIで取得した顔パーツの座標位置をマッピングしてみた

Google Cloud Vision APIで顔の各パーツの検出ができるようになっていました。
もしかしたら僕が勘違いしていただけで最初から出来ていたのかもしれませんが、せっかくなのでその精度検証的なことをしてみます。

使用する画像はこちら。
![株式会社dottのイケメン担当](https://qiita-image-store.s3.amazonaws.com/0/19695/ddb47a6e-965b-5a89-1b80-825b9dec41ef.jpeg)

デスマ中で目が死んでいるこの画像を使って検証を行ってみたいと思います。

今回はPHPで簡単なスクリプトを用意しました。

```php:face.php

	//APIキー
	$api_key = "各自設定してください";

	//リファラー
	$referer = "各自設定してください";

	//画像へのパス
	$image_path = "各自設定してください";

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

	//APIアクセス
	$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"]);// レスポンスヘッダー

	//データ確認
	$arr = json_decode($json,true);
```

この辺りの基本的な使い方はQiitaにもいっぱい転がってるんで調べてみてください。
で、そのままその画像の上にマッピングしてみましょう。

```php:face.php
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		.point {
			width: 6px;
			height: 6px;
			display: block;
			position: absolute;
			background-color: red;
			border-radius: 3px;
		}
	</style>
</head>
<body>

<div style="background-image:url(画像パスを入れてください); width:356px; height: 380px; position: absolute;">
	<a href=""></a>

<?php
	foreach ($arr[responses][0][faceAnnotations][0][landmarks] as $key => $value) {
		$x = $value[position][y]-3;
		$y = $value[position][x]-3;
		echo <<<EOF
<a href="" class="point" style="top:{$x}px; left: {$y}px;"></a>
EOF;
	}
?>
	
</div>
</body>
</html>
```

で、その結果がこちら。
![CloudVisionでのマッピング結果](https://qiita-image-store.s3.amazonaws.com/0/19695/c146a119-c619-e8c8-6719-1c7a30ecc609.jpeg)
ちょっと顎の部分が少しだけずれているのかなと思いますが、他はほぼ完璧です。
なお、取れる値の種類は[公式ドキュメント](https://cloud.google.com/vision/reference/rest/v1/images/annotate#type_1)を見てみてください。
顎はCHIN_〜です。

ついでに顔検出APIとしては[detectFace();](http://detectface.com/)なんてものもあります。
せっかくなんでdetectFace();でも検出してみました。

![test_result.jpg](https://qiita-image-store.s3.amazonaws.com/0/19695/a7d45471-1bcf-cd97-e236-140aa7408fb5.jpeg)
検出する部位の名前も一緒に出しちゃったので少しわかりにくいですが、こっちの方が検出ポイントは多いです。
精度についてはしっかり比較しないとわかりませんが、輪郭についてはdetectFace();、内部のパーツについてはどっこいどっこいって感じでしょうか。

ただ、detectFace();の場合は無償版は回数制限が割と厳しく、サービスで利用するとしたら有償版を契約する必要があります。
金額は公式サイトで伏せているので、ここでは明示しませんが「Mac pro買えるよ」とだけ言っておきますね。


まあ、そんなわけでGoogle Cloud Visionで顔検出した結果としては十分に使用に耐えうるかなって感じです。
いろいろと遊べそうですね！！

※ちなみに、Cloud Vision APIは感情系の解析もいろいろしてくれるわけですが、

```json
{
  "responses": [
    {
      "faceAnnotations": [
        {
          "joyLikelihood": "VERY_UNLIKELY",
          "sorrowLikelihood": "VERY_UNLIKELY",
          "angerLikelihood": "VERY_UNLIKELY",
          "surpriseLikelihood": "VERY_UNLIKELY",
          "underExposedLikelihood": "VERY_UNLIKELY",
          "blurredLikelihood": "VERY_UNLIKELY",
          "headwearLikelihood": "VERY_UNLIKELY"
        }
      ]
    }
  ]
}
```

デスマって怖いですね、ってオチ。