MicrosoftのFace API をサクッとPythonで試してみる

#始めに
こんにちは。久々の投稿です。
最近、機械学習関連でGoogleやMicrosoftがかなり優秀なAPIを提供しています。
今まではOpenCVやNeural networkフレームワークを使用して自作していたものがAPIを呼ぶだけで気軽に利用できるということで、ちょっと使ってみたいという方にはかなり敷居が下がったのではないでしょうか。
ということで、今回はMicrosoftのFace APIを試したいと思います。
今さら顔認識かよと思われそうですが、これはかなり優秀なAPIでして目や鼻の位置はもちろん年齢や性別、似た顔の検索やグルーピングまでも可能なAPIなのです。少し前に流行った [How old do I look?] (https://how-old.net/)も同じAPIを使っているはずです。
恐らく、OpenCV等を利用して自分でせっせとアルゴリズムを書くよりも優秀なのです。。

#APIを利用できるようにしよう
先ずは、Microsoftのページに行ってFace APIを取得しましょう。
https://www.microsoft.com/cognitive-services/en-us/face-api
ページ下の[Buy on Azure]を押してAzureのアカウント登録します。
登録が終わったら使用したいAPIを選択します。
ここでは、Freeの「30,000 transactions per month」を選択します。

![Choose Face API.jpg](https://qiita-image-store.s3.amazonaws.com/0/99765/dc399689-b5b4-7de7-fd8f-8b7b518fa80c.jpeg)

無事キーを取得すると、自分のページに以下のように表示されるので
「Show」ボタンを押してKeyを表示させます。
このKeyは後で必要になるので適当にコピーして保存しておいてください。

![Face API.jpg](https://qiita-image-store.s3.amazonaws.com/0/99765/2775d1a8-c68d-577a-b9c8-9b2724806b3f.jpeg)


#コードを書いてみよう
今回はお試しなのでPythonでサクッとコードを書きます。

```face_test
import httplib, urllib, base64
import cv2
import numpy as np
import json
import sys

headers = {
    # Request headers
    'Content-Type': 'application/octet-stream',
    'Ocp-Apim-Subscription-Key': '[Input your key]',
}

params = urllib.urlencode({
    # Request parameters
    'analyzesFaceLandmarks': 'false',
    'analyzesAge': 'true',
    'analyzesGender': 'true',
    'analyzesHeadPose': 'false',
})

def display_expression(data,img):
    font = cv2.FONT_HERSHEY_PLAIN
    font_size = 2

    data = json.loads(data)
    for face in data:
        f_rec  =  face['faceRectangle']
        width  =  f_rec['width']
        height =  f_rec['height']
        left   =  f_rec['left']
        top    =  f_rec['top']
        cv2.rectangle(img,(left,top),(left+width,top+height),(0,200,0),2)
        
        f_attr = face['attributes']
        gender = f_attr['gender']
        age = f_attr['age']
        cv2.putText(img, gender, (left, 30+top+height), font, font_size, (0, 200, 0), 2)
        cv2.putText(img, str(age), (left, 60+top+height), font, font_size, (0, 200, 0), 2)



if __name__ == '__main__':
    if len(sys.argv) < 1:
        quit()
    file_path = sys.argv[0]
    conn = httplib.HTTPSConnection('api.projectoxford.ai')
    conn.request("POST", "/face/v0/detections?%s" % params, open(file_path, 'rb'), headers)
    response = conn.getresponse()
    data = response.read()

    print(data)

    img = cv2.imread(file_path)
    display_expression(data, img)

    cv2.imshow('image',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    conn.close()
```


**コード解説**
先ほど取得したKeyを[Input your key]に入力します。

```
'Ocp-Apim-Subscription-Key': '[Input your key]',
```

リクエストに送るパラメータの無効／有効を切り替えて取得する情報を変更できます。

```
    # Request parameters
    'analyzesFaceLandmarks': 'false',
    'analyzesAge': 'true',
    'analyzesGender': 'true',
    'analyzesHeadPose': 'false',
```

表示部分はOpenCVを使っています。

#結果

![Nozomi.jpg](https://qiita-image-store.s3.amazonaws.com/0/99765/a715ba9c-c90b-880f-bfa5-6509f69bb352.jpeg)

![Ryan.jpg](https://qiita-image-store.s3.amazonaws.com/0/99765/5e0740c8-b030-ef40-3524-a533d8925200.jpeg)

複数人でもできちゃいます。（性別と年齢の精度が怪しいですが）
![Students.jpg](https://qiita-image-store.s3.amazonaws.com/0/99765/e00eb41f-94d4-ed0c-2e4e-033d0ff1a434.jpeg)



#まとめ
顔の位置に関してはかなり正確に検出できていますが、性別や年齢についてはまだ怪しいところがあるようです。（特にアジア系の顔について精度が悪い印象があります）
Microsoft APIにはその他にも音声や動画用など数多くのAPIが用意されていますので他のも色々使ってみたいと思います。もっとも、本気で使おうとすると有料プランに移行しないといけないのがすが。。

今後、機械学習や画像処理関係のプロジェクトはGoogleやMicrosoftのAPIを呼ぶことで初期の検証や考察などはだいぶ楽に行えると感じました。
また、これらを使った面白いWebサービスやIoTなどの登場にも期待しています。
最近、Raspberry Pi3を手に入れたので、そのうちに面白いIoTを自作したいと思います！