techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

Google Cloud Vision APIを使って顔識別用の顔画像を作る

動機

Tensorflowで顔識別をさせてみたいが,顔画像を大量に用意しなければならない。
顔認識をさせて顔画像を切り出さないといけないが,調べてみるとOpenCVの顔認識はデフォルトだとそこまで精度は高くないらしい…。
そこで今回は,Google Cloud Vision APIを利用して顔認識を行い,顔画像を切り出そうと思います。

Google Cloud Vison APIとは

その名のとおり,Googleが提供する画像認識のAPIです。
顔認識,物体認識,OCRなど様々な機能が提供されています。
参考に女の子の動画を貼っておきます。

www.youtube.com

同時に色んな認識機能を使うことができますが,今回は顔認識のみを利用します。
顔認識では,顔の位置だけでなく各パーツ(目,鼻など)の位置も返してくれるそうです。

実装

久しぶりにPythonを書くので,調べながらちゃっちゃか書いていきます。
今回,画像の切り出しにはOpenCVを使用したので,予め入れておいてください。
前もって下記リンクからAPI Keyは取得しておきましょう。

console.developers.google.com

#!/usr/bin/python
#coding:utf-8
import cv2
import os
import sys
import base64
import json
import requests

# APIのURL
api_url = 'https://vision.googleapis.com/v1/images:annotate?key='

# APIキー
api_key = '自分のAPIキーを入れる'

# リクエスト用のデータ作成
with open(sys.argv[1], 'rb') as image:
    base64_image = base64.b64encode(image.read())

    data = {
        'requests': [{
            'image': {
                'content': base64_image,
            },
            'features': [{
                'type': 'FACE_DETECTION',
                'maxResults': 100,
            }]
            
        }]
    }

    # リクエスト送信
    header = {'Content-Type': 'application/json'}
    response = requests.post(api_url + api_key,  json.dumps(data), header)

    # 分析結果の取得
    if response.status_code == 200:
        #print response.text
        json_response = json.loads(response.text)
        # 顔認識の結果が含まれていれば切り出す
        if json_response['responses'][0].has_key('faceAnnotations'):
            # 認識できた顔の数だけループ
            for i, face in enumerate(json_response['responses'][0]['faceAnnotations']):
                # 顔画像位置
                vertices = [(v.get('x', 0.0), v.get('y', 0.0)) for v in face['fdBoundingPoly']['vertices']]
                #print vertices
                # 顔画像の切り出し
                src = cv2.imread(sys.argv[1])
                dst = src[vertices[0][1]:vertices[2][1], vertices[0][0]:vertices[2][0]]
                # 顔画像の出力パスを作成
                root, ext = os.path.splitext(sys.argv[1])
                face_image_path = root + '_face' + str(i) + ext
                # 顔画像の出力
                cv2.imwrite(face_image_path , dst)
        else:
            print u'顔が認識されませんでした'
    else:
        print 'Http response error'

よく使われてる画像で試してみました。
元画像
f:id:hayatedayon:20160611104642j:plain

顔画像
f:id:hayatedayon:20160611104647j:plain

うまく切り出されています。

Google画像検索でとってきた,集合写真などでも,
ある程度顔が認識できる画像であれば,顔画像を切り出すことが可能でした。

アニメの分類機も作ってみたいので,アニメ画像でもトライしましたが,
ほとんど認識することができませんでした…。
(そりゃそうですね)

次回は切り出した顔画像を使って顔識別をしたいと思います。