顔認証のクラウドサービスMercury Cloudでさらに遊んでみる – 複数の顔検知 –

2021.11.05

Mercury Cloudの顔検知APIは、一枚の画像に複数の顔が含まれていても全ての顔を検出できます。

どれくらいの精度で検知できるのかを確認するため、今回は検知した顔を四角の枠で囲ってみます。

やってみる

顔検知のAPIへのアクセス方法などは以前の記事で行ったので今回は割愛します。

スクリプトの準備

5.1 準備

に pythonのファイルがあるので、これらをダウンロードします。

api_parameters.pyをテキストエディターで開き、パラメーターを自身の情報に置き換えます。

スクリプトの編集

pythonのOpenCVを使って四角の枠を描画します。OpenCVは標準ライブラリではないのでインストールしておきます。

pip install opencv-python

四角の枠(長方形)の描画は、cv2.rectangle() を使ってできます。

サンプル

import cv2

img = cv2.imread('~/Downloads/ogp-960x504.png')
cv2.startWindowThread()
cv2.rectangle(img, pt1=(50, 150), pt2=(125, 250), color=(0, 255, 0),thickness=2)
cv2.imshow('rectangle',img)
cv2.waitKey(10000)
cv2.destroyAllWindows()

cv2.rectangleのpt1は四角形の左上の座標, pt2は四角形の右下の座標 です。

Mercury Cloudの顔検知APIで顔を検知すると結果として

{
    "trace_id": "9632cc0a876244770b28daa63b860bb1",
    "results": [
        {
            "code": 0,
            "message": "Success.",
            "internal_code": 0
        }
    ],
    "batches": [
        {
            "faces": [
                {
                    "quality": 0.9888282,
                    "rectangle": {
                        "top": 62,
                        "left": 976,
                        "width": 78,
                        "height": 77
                    },
                    "angle": {
                        "yaw": 60.39208,
                        ~~~~~
                        ~~~~~
}

batches->facesの中のrectangleという項目が座標を表すデータとなっています。

なので座標情報は、

  • pt1=(left, top)
  • pt2=(left+width,top+height)

となります。

今回はサンプルでダウンロードしたdetect_faces.pydisplay_detected_results関数を以下のように編集して四角形の枠で顔を囲むようにしてみました。

def display_detected_results(response_body):
    results = response_body["results"]
    batches = response_body["batches"]
    batch_index = 0

    img = cv2.imread(sys.argv[1])
    cv2.startWindowThread()

    for result in results:
        if result["code"] != 0:
            print("Detect error:", json.dumps(results[batch_index]))
        faces = batches[batch_index]
        batch_index += 1
        for face in faces["faces"]:
            display_detected_face(face)
            cv2.rectangle(img, pt1=(face["rectangle"]["left"],face["rectangle"]["top"]), pt2=(face["rectangle"]["left"]+face["rectangle"]["width"],face["rectangle"]["top"]+face["rectangle"]["height"]), color=(0,255,0), thickness=2)

    cv2.imshow('rectangle',img)
    cv2.waitKey(10000)
    cv2.destroyAllWindows()

スクリプト実行

python detect_faces.py "{検知したい画像のパス}"

で実行します。

既存のスクリプト実行の結果は以下のようになります。 顔が検出されたかどうかを示す検出resultsフィールドに、検出された顔の詳細が含まれています

Detect image: {image_path}\image.jpg
Http status code: 200
Detect face. rectangle: {'top': 625, 'left': 350, 'width': 793, 'height': 818} angle: {'yaw': -0.42474133, 'pitch': 9.596367, 'roll': 0.07245465}
Predicted attributes:
        Age: 29 ~ 39
        Gender: MALE
        Cap: HAT_STYLE_TYPE_NONE
        Glasses: TRANSPARENT_GLASSES
        Mask: COLOR_TYPE_NONE

これに編集を加えたので、顔を四角で囲った画像を表示するようになっています

画像1

この画像なら

Http status code: 200
Detect face. rectangle: {'top': 180, 'left': 594, 'width': 63, 'height': 63} angle: {'yaw': 34.193096, 'pitch': 11.0047245, 'roll': 6.500332}
Predicted attributes:
	Age: 27 ~ 37
	Gender: MALE
	Cap: HAT_STYLE_TYPE_NONE
	Glasses: GLASSES_STYLE_TYPE_NONE
	Mask: COLOR_TYPE_NONE
Detect face. rectangle: {'top': 234, 'left': 33, 'width': 99, 'height': 114} angle: {'yaw': 57.880013, 'pitch': 5.3685126, 'roll': 8.39082}
Predicted attributes:
	Age: 15 ~ 25
	Gender: FEMALE
	Cap: HAT_STYLE_TYPE_NONE
	Glasses: GLASSES_STYLE_TYPE_NONE
	Mask: COLOR_TYPE_NONE
Detect face. rectangle: {'top': 273, 'left': 678, 'width': 60, 'height': 66} angle: {'yaw': 77.87407, 'pitch': -2.5616593, 'roll': -5.100396}
Predicted attributes:
	Age: 37 ~ 47
	Gender: MALE
	Cap: HAT_STYLE_TYPE_NONE
	Glasses: GLASSES_STYLE_TYPE_NONE
	Mask: COLOR_TYPE_NONE
Detect face. rectangle: {'top': 180, 'left': 870, 'width': 45, 'height': 45} angle: {'yaw': -10.604447, 'pitch': 4.961412, 'roll': 8.63713}
Predicted attributes:
	Age: 22 ~ 32
	Gender: MALE
	Cap: HAT_STYLE_TYPE_NONE
	Glasses: GLASSES_STYLE_TYPE_NONE
	Mask: COLOR_TYPE_NONE

と4つの顔が検知されました。枠で囲った画像は以下のようになります。

画像2

この画像なら

Http status code: 200
Detect face. rectangle: {'top': 112, 'left': 933, 'width': 67, 'height': 67} angle: {'yaw': 5.148779, 'pitch': 4.206533, 'roll': -2.3302898}
Predicted attributes:
	Age: 39 ~ 49
	Gender: MALE
	Cap: HAT_STYLE_TYPE_NONE
	Glasses: GLASSES_STYLE_TYPE_NONE
	Mask: COLOR_TYPE_NONE
Detect face. rectangle: {'top': 127, 'left': 63, 'width': 86, 'height': 86} angle: {'yaw': -31.70326, 'pitch': -1.8403594, 'roll': -9.5565}
Predicted attributes:
	Age: 40 ~ 50
	Gender: MALE
	Cap: HAT_STYLE_TYPE_NONE
	Glasses: GLASSES_STYLE_TYPE_NONE
	Mask: COLOR_TYPE_NONE
Detect face. rectangle: {'top': 116, 'left': 551, 'width': 67, 'height': 67} angle: {'yaw': -4.3974, 'pitch': 4.528134, 'roll': 2.737622}
Predicted attributes:
	Age: 21 ~ 31
	Gender: MALE
	Cap: HAT_STYLE_TYPE_NONE
	Glasses: GLASSES_STYLE_TYPE_NONE
	Mask: COLOR_TYPE_NONE

こうなりました。

画像3

同じ画像の傾きを変えて複数表示させてみたところ、

Http status code: 200
Detect face. rectangle: {'top': 112, 'left': 268, 'width': 54, 'height': 54} angle: {'yaw': 4.396627, 'pitch': 4.2450356, 'roll': -1.7384199}
Predicted attributes:
	Age: 38 ~ 48
	Gender: MALE
	Cap: HAT_STYLE_TYPE_NONE
	Glasses: GLASSES_STYLE_TYPE_NONE
	Mask: COLOR_TYPE_NONE

このように傾きなしの一つの顔のみを検知してくれました。

真ん中の画像は色が暗すぎて検知してくれていないようです。

最後に

Mercury Cloudの顔検知APIを使い複数の顔が写っている画像を使って顔検知の実験をしてみました。

顔の範囲が小さかったり、画像が荒かったりすると検知されない、正面の画像を回転させると検知されない ということがわかりました。

実際にサービスに顔検知を組み込むとなると、さまざまな画像でテストをした方が良さそうですね。