顔認識のアルゴリズムを実装しよう

実装編

さて、APIリファレンスを軽くさらったところで、さっそく試していきましょう。

ライブラリのインポート

まずは必要なライブラリをインポートします。

  • requests: HTTPの通信を行うためのライブラリ
  • json:データをjson形式で使うためのライブラリ
  • pandas: CSVデータを使うためのライブラリ
import requests
import json
import pandas as pd

APIのエンドポイントのルートURLと、サブスクリプションキーの設定

APIのエンドポイントのルートURLと、サブスクリプションキーの設定を行います。

import requests
import json
import pandas as pd

SUBSCRIPTION_KEY = "" #ここで取得したAPI KEYを設定する
BASE_URL = "https://xxxxx.cognitiveservices.azure.com/face/v1.0/" # ここで取得したURLを設定する

グループ名の追加

さて、Person Groupの名前を付けます。ここでは、GROUP_NAMEという変数に名前を定義しておきましょう。

import requests
import json
import pandas as pd

SUBSCRIPTION_KEY = ""
BASE_URL = "https://xxxxx.cognitiveservices.azure.com/face/v1.0/"

#グループ名の指定
GROUP_NAME = "akb48"

Person Groupを作る関数の作成

それではまず、Person Groupを作成していきましょう。

 さて、最初にPerson Groupを作成します。APIリファレンスを読んでみましょう。

上記のリファレンスから、特に重要な内容のみ、まとめておきます。

Http Method PUT  
Request URL https://{endpoint}/face/v1.0/persongroups/{personGroupId}  
Request parameters personGroupId  
Request headers Content-Type
Ocp-Apim-Subscription-Key:APIキーを入れる値
 
Request body Fields
 
 

Person Groupの作成で確認した、API リファレンスをもとに、関数を作成します。

#Person Groupを作成する関数
def make_group():
    end_point = BASE_URL + "persongroups/" + GROUP_NAME  # エンドポイントを指定します
    payload = {"name": GROUP_NAME} # リクエストボディの中身を指定します
    headers = {"Ocp-Apim-Subscription-Key": SUBSCRIPTION_KEY} # ヘッダーを指定します
    r = requests.put( # putメソッドでHTTPリクエストを送ります
        end_point,
        headers=headers,
        json=payload
        )
    return r.json() #結果をJSON形式で取得します

Person Groupの作成

作成したPerson Groupの関数を実行します。エラーなく実行できると、Person Groupが作成できていると思います。

make_group() #実行します

こうすることで、Person Groupを作成することができます。

Person GroupにPersonを追加する関数の実装

今度は、作成したPerson GroupにPersonを追加する関数を実装します。

#make_person関数の実装
def make_person(name):
    end_point = BASE_URL + "persongroups/" + GROUP_NAME + "/persons" # エンドポイントを指定します
    headers = {"Ocp-Apim-Subscription-Key": SUBSCRIPTION_KEY} # ヘッダーを指定します
    payload = {"name": name} # リクエストボディを指定します
    r = requests.post( # POSTリクエストでHTTPメソッドを実行します
        end_point,
        headers=headers,
        json=payload)
    return r.json()

make_person関数を実行します。

make_person("大島優子")

そうすると、以下のような結果が取得可能です。

{'personId': 'b8f2516a-63b1-49ab-bf9c-fc64f320a796'}

このように、個別のPersonには個別のpersonIdが付与されます。

個別のpersonIdを指定して、今度はこのpersonIdにFaceを追加していくことになります。 また、今後このpersonIdを関数の引数に入れて、顔を追加する必要がでてきますので、JSON形式のデータを取得する方法を確認します。以下のようにコードを実行すると

make_person("大島優子")["personId"]

 

{'personId': 'b8f2516a-63b1-49ab-bf9c-fc64f320a796'}

という値を取得することができます。

このpersonIdをもとに、画像を追加するので、メモしておきましょう。

PersonにFaceを追加する関数を追加

今度は、PersonにFaceを追加する関数を追加します。引数には、以下の値を入れます。

  • person_id : さきほどmake_personで実行したときに、付与されたperson_id
  • image_url: prersonに紐づけたい画像URL

では、実装していきましょう。

# Personに顔の画像を追加する関数を追加
def add_face_to_person(person_id, image_url):
    end_point = BASE_URL + "persongroups/" + GROUP_NAME + \
        "/persons/" + person_id + "/persistedFaces" # エンドポイントを設定します
    headers = {"Ocp-Apim-Subscription-Key": SUBSCRIPTION_KEY}
    payload = {"url": image_url} # リクエストボディを設定します
    r = requests.post(end_point,
                      headers=headers,
                      json=payload
                      )
    return r.json()

それでは、実際にFaceを追加します。personIdでは、さきほど取得した浦島太郎の値をセット、imageurlには僕が適当にネットから拾ってきた、大島優子の画像をセットし、addfacetoperson関数を実行します。

#'dca7eaee-f45c-4f27-9751-9ac26bcb6828' をperonId
# 大島優子の画像URL(https://pbs.twimg.com/profile_images/1037966231406407680/cCWrFJ4j.jpg)をセットする
person_id = "dca7eaee-f45c-4f27-9751-9ac26bcb6828"
image_url = "https://pbs.twimg.com/profile_images/1037966231406407680/cCWrFJ4j.jpg"
add_face_to_person(person_id, image_url)

 

Person GroupにFaceを学習させる関数を実装

それでは、Person GroupにFaceを学習させていきましょう。現状、PersonにFaceが登録されているだけなので、このAPIのエンドポイントを利用すると、顔の学習を行うことができます。

# 顔を学習させる
def train_group(group_id):
    end_point = BASE_URL + "persongroups/" + GROUP_NAME + "/train" #エンドポイントを指定します
    headers = {"Ocp-Apim-Subscription-Key": SUBSCRIPTION_KEY}
    r = requests.post(end_point, headers=headers) #POSTリクエストを送ります
    return r.json() 

Person GroupにFaceを学習させる関数を実行

以下のように実行してみてください。

# 顔を学習させる
train_group(GROUP_NAME)

特になにもレスポンスはありませんが、エラーが起こらなければ、顔の学習が完了します。

URLからFaceを検出する関数を実装する

URLからFaceを検出する関数を実装します。 引数には、以下の値を入れます。

  • image_url: 画像のURL。
# URLから画像を検出する
def detect_face(image_url):
    end_point = BASE_URL + "detect" #エンドポイントを指定します
    headers = {"Ocp-Apim-Subscription-Key": SUBSCRIPTION_KEY}
    payload = {"url": image_url}
    r = requests.post(end_point, # POSTリクエストを送ります
                      json=payload,
                      headers=headers)
    return r.json()

URLからFaceを検出する関数を実行する

detect_face関数に、さきほど学習させた大島優子の画像を入れて、顔認識を行います。

# 実行する
image_url = "https://pbs.twimg.com/profile_images/1037966231406407680/cCWrFJ4j.jpg"
detect_face(image_url)

実行すると、以下のような結果が返ってくるはずです。

[{'faceId': '844452b4-0913-49c6-b77e-3c5dc7cd8373', 'faceRectangle': {'height': 93, 'left': 235, 'top': 148, 'width': 93}}]

このようなリスト形式で、顔だと判定された画像のfaceIdと、詳細なデータが返ってきます。このあとこのfaceIdを利用して、学習済みのモデルの中から、似ている顔画像を取得することができるようになります。

学習済みモデルから似ているPerson IDを取得する

では、次に学習した結果のPersonから、似ている人のIDを取得してみましょう。

# detectFaceから抽出したface_idから、学習済みモデルのfaceIdを取得
def identify(face_id):
    end_point = BASE_URL + "identify"
    headers = {"Ocp-Apim-Subscription-Key": SUBSCRIPTION_KEY}
    payload = {"faceIds": [face_id], "personGroupId": GROUP_NAME, }
    r = requests.post(
        end_point,
        json=payload,
        headers=headers
    )
    return r.json()

この関数を、さきほど入れた大島優子の画像のface_idから

# detectFaceから抽出したfaceIdから、学習済みモデルのfaceIdを取得
identify("08925fdb-311a-4730-85e5-a50fcad60a63")

結果

[{'candidates': [{'confidence': 1.0, 'personId': 'dca7eaee-f45c-4f27-9751-9ac26bcb6828'}], 'faceId': '08925fdb-311a-4730-85e5-a50fcad60a63'}]

この、candidatesの中のデータですが、以下の値が取得されます。

  • candidates: 顔が一致する候補者のリストを表示
  • confidence: 一致度で、0 ~ 1.0の割合で算出されます。今回1なのは、元のオリジナル画像と学習した画像が一緒なため、高くなっています。
  • personId:一致しているPersonのIDとなります。

今後はこのpersonIdから、データを取得することになります。

personIdから名前を取得する関数を実装する

では、identify関数を実行し、似ているPersonのIDを取得できたので、今度はPerson IDから、そのPersonの登録情報を取得する関数を実装します。 引数にはperson_idを指定します。

# Personを取得
def get_person(person_id):
    end_point = BASE_URL + "persongroups/" + GROUP_NAME + "/persons/" + person_id
    headers = {"Ocp-Apim-Subscription-Key": SUBSCRIPTION_KEY}
    r = requests.get(
        end_point,
        headers=headers
    )
    return r.json()

 

person_idから名前を取得する関数を実行する

さっそく、作成したget_person関数に、引数にpersonIdを入れて実行してみましょう。

get_person("dca7eaee-f45c-4f27-9751-9ac26bcb6828")

実行結果は以下のようになります。

{'name': '大島優子', 'persistedFaceIds': ['15b62de9-d257-4da9-95eb-9d88feb61283', '6cc44175-36b7-45e6-9356-cc35b28f8cad', '8ea3dce7-8415-4dbb-97bf-a6f5279848a3', '9463bf90-ff69-4979-803a-668cc02a21e6', 'd77d74b7-74f0-4588-8db4-056127452f00'], 'personId': 'dca7eaee-f45c-4f27-9751-9ac26bcb6828', 'userData': None}

中に入っているデータを確認します。

  • name: Personに紐づいている名前。最初にmakePerson関数で登録したユーザーと一致します。
  • pesistedFaceIds:Personに紐づけられた顔の画像。複数枚ある場合は複数枚出てきます。
  • personId:そのPersonのIDが取得できます。

これで、画像を送信すると顔認識ができるロジックが組み立てられました。

次の章では、大量のデータを学習させる方法について学んでいきましょう。