業界・業務から探す
導入目的・課題から探す
データ・AIについて学ぶ
News
Hakkyについて
ウェビナーコラム
◆トップ【AI・機械学習】
プロセスの全体像前処理・特徴量生成Fine Tuning手法まとめ機械学習モデルの選び方モデル評価手法プロトタイピング探索的分析(EDA)
ドミナントカラー検出セグメンテーション技術の基礎と実装局所特徴量抽出Grad-CAMまとめ画像の二値化とその手法モルフォロジー演算とその手法【Vision AI】Painterの紹介pix2structの紹介
AI

執筆者:Handbook編集部

Cloud Vision APIによる表情推定の方法

はじめに

本記事はCloud Vision APIを用いて、人の顔の写った画像の表情から感情を推定する手法について解説します。 Cloud Vision APIには以下のように様々な使用例があります。

  • 画像内のテキストを検出(OCR)
  • 画像内の手書き文字を検出(OCR)
  • ファイル内のテキストを検出(OCR - PDF / TIFF)
  • 顔の検出
  • ロゴの検出

本記事では、顔の検出モデルを用いて、画像に映っている人の顔の検出と感情を推定する手法について解説します。

動作環境

実行環境はGoogle Colaboratryを使用します。

Cloud Vision APIを使った表情推定

APIキーの取得と設定

APIキーの取得

Vision API を使用する方法を参考にkeyを取得して、ダウンロードします。

ダウンロードしたJSONキーファイルをGoogle Driveの任意のフォルダに配置してください。

Google Driveのマウント

Google Driveに保存したJSONキーファイルをGoogle Colaboratryで使用するため、Google Driveのマウントを行います。

from google.colab import drive
drive.mount('/content/drive')

APIキーの設定

環境変数GOOGLE_APPLICATION_CREDENTIALS にJSONキーファイルを設定します。

import os
json_path = "/content/drive/MyDrive/{JSONキーファイルまでのパス}"
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = json_path

以上で、Google Colaboratry上でCloud Vision APIを使用する環境が設定できました。

ローカル画像で顔を検出する

まず、google-cloud-visionのインストールを行います。バージョンの関係でcolabのカーネル再起動が必要になる可能性があります。

! pip install --upgrade google-cloud-vision

Vision API は、リクエストの本文で画像ファイルのコンテンツを Base64 エンコードの文字列として送信し、ローカル画像ファイルの特徴検出を行います。

def detect_faces(path):
    """Detects faces in an image."""
    from google.cloud import vision
    import io
    client = vision.ImageAnnotatorClient()

    with io.open(path, 'rb') as image_file:
        content = image_file.read()

    image = vision.Image(content=content)

    response = client.face_detection(image=image)
    faces = response.face_annotations

    # Names of likelihood from google.cloud.vision.enums
    likelihood_name = ('UNKNOWN', 'VERY_UNLIKELY', 'UNLIKELY', 'POSSIBLE',
                       'LIKELY', 'VERY_LIKELY')
    print('Faces:')

    for face in faces:
        print(face)

        print('anger: {}'.format(likelihood_name[face.anger_likelihood]))
        print('sorrow: {}'.format(likelihood_name[face.sorrow_likelihood]))
        print('under_exposed: {}'.format(likelihood_name[face.under_exposed_likelihood]))
        print('blurred: {}'.format(likelihood_name[face.blurred_likelihood]))
        print('headwear: {}'.format(likelihood_name[face.headwear_likelihood]))
        print('joy: {}'.format(likelihood_name[face.joy_likelihood]))
        print('surprise: {}'.format(likelihood_name[face.surprise_likelihood]))

        vertices = (['({},{})'.format(vertex.x, vertex.y)
                    for vertex in face.bounding_poly.vertices])

        print('face bounds: {}'.format(','.join(vertices)))

    if response.error.message:
        raise Exception(
            '{}\nFor more info on error messages, check: '
            'https://cloud.google.com/apis/design/errors'.format(
                response.error.message))

最後に、画像を指定して実行します。

path = "/content/drive/MyDrive/data/face_classfication/img/{画像名}"
detect_faces(path)

APIレスポンスの例

リクエストが成功すると、サーバーは 200 OK HTTPステータスコードと以下のようなJSON形式のレスポンスを返します。 FACE_DETECTIONレスポンスには、検出されたすべての顔の境界ボックス、顔で検出されたランドマーク(眼、鼻、口など)、顔の信頼性の評価、画像のプロパティ(喜び、悲しみ、怒り、驚きなど)が含まれます。

bounding_poly {
  vertices {
    x: 131
  }
  vertices {
    x: 304
  }
  vertices {
    x: 304
    y: 201
  }
  vertices {
    x: 131
    y: 201
  }
}
fd_bounding_poly {
  vertices {
    x: 153
    y: 40
  }
  vertices {
    x: 294
    y: 40
  }
  vertices {
    x: 294
    y: 182
  }
  vertices {
    x: 153
    y: 182
  }
}
landmarks {
  type_: LEFT_EYE
  position {
    x: 199.975204
    y: 95.6826248
    z: 0.000195264816
  }
}
landmarks {
  type_: RIGHT_EYE
  position {
    x: 251.364929
    y: 95.1845093
    z: 9.34194183
  }
}
landmarks {
  type_: LEFT_OF_LEFT_EYEBROW
  position {
    x: 182.755325
    y: 82.8586502
    z: 1.48230457
  }
}
landmarks {
  type_: RIGHT_OF_LEFT_EYEBROW
  position {
    x: 214.475098
    y: 83.4121704
    z: -6.94950485
  }
}
landmarks {
  type_: LEFT_OF_RIGHT_EYEBROW
  position {
    x: 239.461044
    y: 82.550293
    z: -2.40808153
  }
}
landmarks {
  type_: RIGHT_OF_RIGHT_EYEBROW
  position {
    x: 265.736053
    y: 80.8786316
    z: 17.1029663
  }
}
landmarks {
  type_: MIDPOINT_BETWEEN_EYES
  position {
    x: 227.034653
    y: 96.0518646
    z: -5.57333183
  }
}
landmarks {
  type_: NOSE_TIP
  position {
    x: 230.986206
    y: 125.472702
    z: -20.0874405
  }
}
landmarks {
  type_: UPPER_LIP
  position {
    x: 229.519165
    y: 143.124146
    z: -8.90386581
  }
}
landmarks {
  type_: LOWER_LIP
  position {
    x: 228.118942
    y: 158.690018
    z: -5.5889082
  }
}
landmarks {
  type_: MOUTH_LEFT
  position {
    x: 205.074875
    y: 152.04274
    z: 0.228711367
  }
}
landmarks {
  type_: MOUTH_RIGHT
  position {
    x: 248.141922
    y: 149.945862
    z: 8.04831409
  }
}
landmarks {
  type_: MOUTH_CENTER
  position {
    x: 229.182
    y: 150.334763
    z: -5.28811455
  }
}
landmarks {
  type_: NOSE_BOTTOM_RIGHT
  position {
    x: 243.280334
    y: 129.563736
    z: 0.667933762
  }
}
landmarks {
  type_: NOSE_BOTTOM_LEFT
  position {
    x: 212.446976
    y: 130.131882
    z: -4.61002302
  }
}
landmarks {
  type_: NOSE_BOTTOM_CENTER
  position {
    x: 229.107605
    y: 134.318207
    z: -9.16186905
  }
}
landmarks {
  type_: LEFT_EYE_TOP_BOUNDARY
  position {
    x: 199.583603
    y: 91.1806107
    z: -2.90877199
  }
}
landmarks {
  type_: LEFT_EYE_RIGHT_CORNER
  position {
    x: 210.043671
    y: 97.3392487
    z: 1.81678903
  }
}
landmarks {
  type_: LEFT_EYE_BOTTOM_BOUNDARY
  position {
    x: 199.416611
    y: 99.4496918
    z: -0.674886227
  }
}
landmarks {
  type_: LEFT_EYE_LEFT_CORNER
  position {
    x: 188.828522
    y: 95.4554291
    z: 2.54891539
  }
}
landmarks {
  type_: RIGHT_EYE_TOP_BOUNDARY
  position {
    x: 252.39679
    y: 90.4579315
    z: 6.66571236
  }
}
landmarks {
  type_: RIGHT_EYE_RIGHT_CORNER
  position {
    x: 262.695709
    y: 94.8234
    z: 15.8276482
  }
}
landmarks {
  type_: RIGHT_EYE_BOTTOM_BOUNDARY
  position {
    x: 252.437195
    y: 98.7239761
    z: 8.88353443
  }
}
landmarks {
  type_: RIGHT_EYE_LEFT_CORNER
  position {
    x: 242.094696
    y: 96.6214142
    z: 7.4578352
  }
}
landmarks {
  type_: LEFT_EYEBROW_UPPER_MIDPOINT
  position {
    x: 198.74379
    y: 78.7846069
    z: -5.86168909
  }
}
landmarks {
  type_: RIGHT_EYEBROW_UPPER_MIDPOINT
  position {
    x: 253.458069
    y: 77.2212372
    z: 4.23191833
  }
}
landmarks {
  type_: LEFT_EAR_TRAGION
  position {
    x: 154.92247
    y: 114.253929
    z: 55.0588684
  }
}
landmarks {
  type_: RIGHT_EAR_TRAGION
  position {
    x: 276.306488
    y: 115.056267
    z: 75.9458389
  }
}
landmarks {
  type_: FOREHEAD_GLABELLA
  position {
    x: 226.877396
    y: 83.9712143
    z: -6.47793674
  }
}
landmarks {
  type_: CHIN_GNATHION
  position {
    x: 227.365707
    y: 183.05275
    z: 1.38992953
  }
}
landmarks {
  type_: CHIN_LEFT_GONION
  position {
    x: 171.7603
    y: 160.07106
    z: 36.4307
  }
}
landmarks {
  type_: CHIN_RIGHT_GONION
  position {
    x: 262.318024
    y: 157.655167
    z: 54.1650734
  }
}
landmarks {
  type_: LEFT_CHEEK_CENTER
  position {
    x: 190.525955
    y: 128.656845
    z: 2.75064611
  }
}
landmarks {
  type_: RIGHT_CHEEK_CENTER
  position {
    x: 262.539917
    y: 127.522171
    z: 15.7195129
  }
}
roll_angle: -0.972454
pan_angle: 10.4220848
tilt_angle: -0.683650374
detection_confidence: 0.94866091
landmarking_confidence: 0.573678076
joy_likelihood: LIKELY
sorrow_likelihood: VERY_UNLIKELY
anger_likelihood: VERY_UNLIKELY
surprise_likelihood: VERY_UNLIKELY
under_exposed_likelihood: VERY_UNLIKELY
blurred_likelihood: VERY_UNLIKELY
headwear_likelihood: VERY_UNLIKELY

APIレスポンスの解釈

Cloud Vision APIで取れる感情は以下の4種類になります。

  • 楽しそう(joy_likelihood)
  • 悲しそう(sorrow_likelihood)
  • 怒ってそう(anger_likelihood)
  • 驚いてそう(surprise_likelihood)

感情の可能性評価は、UNKNOWN、VERY_UNLIKELY、UNLIKELY、POSSIBLE、LIKELY、VERY_LIKELY の 6 つの異なる値で表されます。
出力例は以下のようになります。

joy_likelihood: LIKELY
sorrow_likelihood: VERY_UNLIKELY
anger_likelihood: VERY_UNLIKELY
surprise_likelihood: VERY_UNLIKELY

他には、以下の3種類についての情報や顔周りのパーツの位置を取得できます。

  • マスクなどをしている
  • ぼやけている・かすんでいる
  • 帽子をかぶっている

出力例は以下のようになります。

under_exposed_likelihood: VERY_UNLIKELY
blurred_likelihood: VERY_UNLIKELY
headwear_likelihood: VERY_UNLIKELY

まとめ

本記事では、Cloud Vision APIを用いて、人の顔の写った画像の表情から感情を推定する手法について解説しました。

参照

2025年06月15日に最終更新
読み込み中...