Google Cloud Platformのニューラルネットワークで写真の人物の顔の表情から感情分析
Contents
顔の感情分析
以前にGCP(Google Cloud Platform)のニューラルネットワークモデルのSpeech-to-Text APIを使って音声をテキスト化した時の事を記事とそのテキスト文章をanalyzeSentiment APIを使って感情分析をした時の記事を書いた。
今回はテキストからでは無く、人物の顔写真からの感情分析を行うCloud Vision APIについて試してみた事を備忘録として記事にしておく。
概要図
複数の人物の写っている写真より顔のパーツを検出して、
- 喜び
- 悲しみ
- 怒り
- 驚き
の4種類の感情を分析すると同時に顔のパーツの写真上の座標を検出する。
事前準備
GCP上でAPIを使用できる環境を整える必要があるのだが大まかな手順は以下の通り。
上記については以前の記事の「GCP(Google Clond Platform)でプロジェクトを作成する」から「VMインスタンスを作成する」までを参照して欲しい。
顔の感情分析を行う
前述の手順でAPI実行用のVMインスタンスが出来ている前提として以下の手順で感情分析を行う。
Cloud Vision APIを有効にする
顔感情分析で必要なAPIを有効にする。
Google Cloud Platformにログインしてメニューから”APIとサービス”ー>”ライブラリ”をクリックする。
“APIとサービスを検索”欄でCloud Vision APIを検索する。
「有効にする」ボタンをクリックする。
有効になった。
sshの起動
Compute EngineのVMインスタンスの画面にて該当インスタンスのSSH横の三角をクリックして”ブラウザウィンドウで開く”をクリックする。
APIキーの設定
しばらく待つと新しいsshウィンドウが開く。
”API認証情報を作成する”で控えておいたAPIキーを使うのだがAPIを呼び出すたびに何回も入力するのは面倒なので下記のコマンドで環境変数に保存しておく。
export API_KEY=控えておいたAPI KEY
ストレージにファイルをアップロード
人物の顔が写った写真をGoogleのストレージにアップロードする。
写真は著作権フリーの人物写真を探して利用させて貰うことにした。
今回使用するフリーの写真
今回使用させて貰ったのは以下の2つの写真。
1枚目は日本人家族の集合写真。
外国人からは日本人の表情が分かりづらいと聞いたことがあるので主に外国人の顔写真で学習したと思われるGoogleのAPIでそれぞれの感情が読み取れるのかを試してみようと思う。
2枚目は外国人の両親と赤ちゃんの写真。
両親はともかく赤ちゃんの表情から感情をどの様にGoogleのニューラルネットワークが分析するのか興味深い。
Cloud Storageにアップロード
メニューから”storage”ー>”ブラウザ”、バケットの作成で”cloudvision20200628”を作成してその中に感情分析したい画像をアップロードした。(バケットの作成からファイルのアップロードまで詳しいやり方は以前の記事を参照して欲しい)
尚、外部から参照できるようにallUsersの権限を追加している。
request_facedetect.jsonの作成
リクエスト用のJSONファイルを準備する。
{
"requests": [
{
"image": {
"source": {
"gcsImageUri": "gs://cloudvision20200628/face-detect-01.jpg"
}
},
"features": [
{
"type": "FACE_DETECTION"
}
]
}
]
}
gcsImageUri | Google Storage上の写真のパス名を指定する |
type | 分析のタイプを指定する
等が指定可能で複数のtypeを同時に指定する事も出来る 今回はFACE_DETECTIONのみを指定した |
実行コマンド
以下のコマンドでCloud Vision APIを呼び出して実行する。
curl -s -X POST -H "Content-Type: application/json" --data-binary @request_facedetect.json https://vision.googleapis.com/v1/images:annotate?key=${API_KEY}
実行結果(日本人家族)
最初に日本人家族の実行結果
検出結果のJSONは非常に長いので加工、省略してコメントを追記している。
{
"responses": [
{
"faceAnnotations": [
{
"boundingPoly": {
"vertices": [
{
"x": 1836,
"y": 818
},
{
"x": 2164,
"y": 818
},
{
"x": 2164,
"y": 1198
},
{
"x": 1836,
"y": 1198
}
]
},
"fdBoundingPoly": {
"vertices": [
{
"x": 1873,
"y": 880
},
{
"x": 2144,
"y": 880
},
{
"x": 2144,
"y": 1168
},
{
"x": 1873,
"y": 1168
}
]
},
"landmarks": [
{
"type": "LEFT_EYE", ←顔のパーツ位置(左目の座標)
"position": {
"x": 1958.7432,
"y": 1008.46277,
"z": -7.6293945e-06
}
},
{
"type": "RIGHT_EYE", ←右目の座標
"position": {
"x": 2055.521,
"y": 1000.0075,
"z": 4.8429937
}
},
{
以下省略
"type": "LEFT_OF_LEFT_EYEBROW", ←左眉(以下座標は省略)
"type": "RIGHT_OF_LEFT_EYEBROW", ←以下、顔のパーツ位置が続く
"type": "LEFT_OF_RIGHT_EYEBROW",
"type": "RIGHT_OF_RIGHT_EYEBROW",
"type": "MIDPOINT_BETWEEN_EYES",
"type": "NOSE_TIP",
"type": "UPPER_LIP",
"type": "LOWER_LIP",
"type": "MOUTH_LEFT",
"type": "MOUTH_RIGHT",
"type": "MOUTH_CENTER",
"type": "NOSE_BOTTOM_RIGHT",
"type": "NOSE_BOTTOM_LEFT",
"type": "NOSE_BOTTOM_CENTER",
"type": "LEFT_EYE_TOP_BOUNDARY",
"type": "LEFT_EYE_RIGHT_CORNER",
"type": "LEFT_EYE_BOTTOM_BOUNDARY",
"type": "LEFT_EYE_LEFT_CORNER",
"type": "RIGHT_EYE_TOP_BOUNDARY",
"type": "RIGHT_EYE_RIGHT_CORNER",
"type": "RIGHT_EYE_BOTTOM_BOUNDARY",
"type": "RIGHT_EYE_LEFT_CORNER",
"type": "LEFT_EYEBROW_UPPER_MIDPOINT",
"type": "RIGHT_EYEBROW_UPPER_MIDPOINT",
"type": "LEFT_EAR_TRAGION",
"type": "RIGHT_EAR_TRAGION",
"type": "FOREHEAD_GLABELLA",
"type": "CHIN_GNATHION",
"type": "CHIN_LEFT_GONION",
"type": "CHIN_RIGHT_GONION",
省略
"rollAngle": -3.5831172, ←息子(手前の子供)
"panAngle": 2.8962502,
"tiltAngle": -0.7956371,
"detectionConfidence": 0.7510176,
"landmarkingConfidence": 0.8474098,
"joyLikelihood": "VERY_LIKELY",
"sorrowLikelihood": "VERY_UNLIKELY",
"angerLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "VERY_UNLIKELY",
"underExposedLikelihood": "VERY_UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"headwearLikelihood": "VERY_UNLIKELY"
以下省略(顔感情分析のみ)
"rollAngle": -2.6513717, ←娘(手前の子供)
"panAngle": 3.2708335,
"tiltAngle": 1.9415131,
"detectionConfidence": 0.95929766,
"landmarkingConfidence": 0.80905235,
"joyLikelihood": "VERY_LIKELY",
"sorrowLikelihood": "VERY_UNLIKELY",
"angerLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "VERY_UNLIKELY",
"underExposedLikelihood": "VERY_UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"headwearLikelihood": "VERY_UNLIKELY"
省略
"rollAngle": -5.808591, ←祖母(右端)
"panAngle": -12.45207,
"tiltAngle": 7.7147107,
"detectionConfidence": 0.9816313,
"landmarkingConfidence": 0.71497536,
"joyLikelihood": "UNLIKELY",
"sorrowLikelihood": "VERY_UNLIKELY",
"angerLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "VERY_UNLIKELY",
"underExposedLikelihood": "VERY_UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"headwearLikelihood": "VERY_UNLIKELY"
省略
"rollAngle": -4.591464, ←母(後列)
"panAngle": -2.5934389,
"tiltAngle": -3.351017,
"detectionConfidence": 0.9577053,
"landmarkingConfidence": 0.64401776,
"joyLikelihood": "VERY_LIKELY",
"sorrowLikelihood": "VERY_UNLIKELY",
"angerLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "VERY_UNLIKELY",
"underExposedLikelihood": "VERY_UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"headwearLikelihood": "VERY_UNLIKELY"
省略
"rollAngle": 1.7782475, ←祖父(左端)
"panAngle": 9.86058,
"tiltAngle": -1.5865794,
"detectionConfidence": 0.61254394,
"landmarkingConfidence": 0.6965967,
"joyLikelihood": "LIKELY",
"sorrowLikelihood": "VERY_UNLIKELY",
"angerLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "VERY_UNLIKELY",
"underExposedLikelihood": "VERY_UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"headwearLikelihood": "VERY_UNLIKELY"
省略
"rollAngle": -1.6559919, ←父(後列)
"panAngle": -0.8663944,
"tiltAngle": 9.723327,
"detectionConfidence": 0.965396,
"landmarkingConfidence": 0.6743713,
"joyLikelihood": "VERY_UNLIKELY",
"sorrowLikelihood": "VERY_UNLIKELY",
"angerLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "VERY_UNLIKELY",
"underExposedLikelihood": "VERY_UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"headwearLikelihood": "VERY_UNLIKELY"
出力結果のJSONには各自の顔のパーツ位置の座標(X、Y、Z)の検出結果と感情分析の結果が出力された。
主な項目は以下の通り。
- detectionConfidence:検出信頼度
- joyLikelihood:喜び
- sorrowLikelihood:悲しみ
- angerLikelihood:怒り
- surpriseLikelihood:驚き
- underExposedLikelihood:露出
- blurredLikelihood:ピンぼけ
- headwearLikelihood:被りもの?
それぞれ6人の感情の検出結果は以下の通り。
祖父(左端) | 「喜んでいる」判定 元の写真では若干固目の表情だからなのかVERYの付かない”LIKELY”の判定 しかし日本人の表情であってもある程度正確に読み取れる事が分かった |
祖母(右端) | 「喜んでいない」判定 やや微笑んでいるように見えるのだがニューラルネットワーク的には”UNLIKELY”との判断 祖父もそうだが高齢者の表情の検知は全体的に厳し目に出ているように感じた |
父(後列) | 「どれでも無い」判定 全ての項目で”VERY_UNLIKELY”判定 かしこまった表情からは感情が読み取れないとの判定と思われる |
母(後列) | 「とても喜んでいる」判定 母親の表情から感情を正しく読み取っていると思う |
息子(前列子供) | 「とても喜んでいる」判定 子供達の表情はどちらも”VERY_LIKELY”判定 元の写真では若干微妙な表情だとは思ったのだが子供の方が感情が強目に判定されているのかも知れない 祖母の写真と比べてもそれほど大きな差は無いように思うのだが。。。 |
娘(前列子供) | 「とても喜んでいる」判定 |
実行結果(外国人家族)
続いて赤ちゃんを含む外国人家族の写真の検出結果。
前半部分省略
"rollAngle": 0.034466736, ← 父親
"panAngle": -11.247587,
"tiltAngle": -7.610189,
"detectionConfidence": 0.8356669,
"landmarkingConfidence": 0.74332947,
"joyLikelihood": "LIKELY",
"sorrowLikelihood": "VERY_UNLIKELY",
"angerLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "VERY_UNLIKELY",
"underExposedLikelihood": "VERY_UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"headwearLikelihood": "VERY_UNLIKELY"
"rollAngle": -5.8361053, ←赤ちゃん
"panAngle": 10.476092,
"tiltAngle": -0.96431774,
"detectionConfidence": 0.7338021,
"landmarkingConfidence": 0.6968528,
"joyLikelihood": "VERY_UNLIKELY",
"sorrowLikelihood": "VERY_UNLIKELY",
"angerLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "UNLIKELY",
"underExposedLikelihood": "VERY_UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"headwearLikelihood": "VERY_UNLIKELY"
"rollAngle": -6.7787957, ←母親
"panAngle": -11.010976,
"tiltAngle": -5.9172897,
"detectionConfidence": 0.7529465,
"landmarkingConfidence": 0.5972206,
"joyLikelihood": "VERY_LIKELY",
"sorrowLikelihood": "VERY_UNLIKELY",
"angerLikelihood": "VERY_UNLIKELY",
"surpriseLikelihood": "VERY_UNLIKELY",
"underExposedLikelihood": "VERY_UNLIKELY",
"blurredLikelihood": "VERY_UNLIKELY",
"headwearLikelihood": "VERY_UNLIKELY"
父親 | 「喜んでいる」判定 確かに妥当な判定かと思う |
母親 | 「とても喜んでいる」判定 こちらの判定も納得の結果 |
赤ちゃん | 「驚いていない」判定 surpriseLikelihoodがUNLIKELYでそれ以外はVERY_UNLIKELYの判定 合っているとも間違っているとも判定できない結果 この赤ん坊の表情からの感情を判定するのは難しいのかも知れない |
終わりに
以上で人物の顔写真から感情を検出するCloud Vision APIの記事は終了とする。
この記事が何処かで誰かの役に立つことを願っている。
尚、当記事中の商品へのリンクはAmazonアソシエイトへのリンクが含まれています。Amazonのアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。
最近のコメント