集合写真のメガネの数をカウントする
こんな話がある。
フーターズに行って「わーお客さんたちみんなメガネですねー」と言われてからコンタクトを真剣に検討している
— 煮穴子 (@dichika) 2013年5月8日
実際、昨晩開催されたGlobal TokyoRの集合写真においてもメガネが目立つ(ゲストスピーカーのHenningさんの記事参照)。
https://henningsway.github.io/post/2017-04-01-tokyo-r/
ということで集合写真からメガネ着用率を算出したい。
今回はMicrosoft Face APIを用いて集合写真から顔検出&メガネ着用の有無を判定したいと思う。
以下のステップで進める。
ローカルの画像を画像サーバ(imgur)にアップロードする
上記サイトの集合写真をFace APIにそのまま送ると、一つ一つの顔が小さすぎて顔検出に失敗する。
したがってローカルにいったんダウンロードし、引き延ばした画像を用いることにする。
ただし、Face APIはウェブ上の画像を対象としているため、ローカルの画像についてはいったんどこかの画像サーバにアップロードする必要がある(追記)指定を変えることで画像サーバにアップロードする必要はないとのこと。詳しくはuriboさんの記事を参照ください。
今回は一時的にimgurにアップロードしてメガネ着用率を算出後に消去することにする。
imgurにはimguRパッケージを用いてアップロードする。
結果のlinkにアップロード先のURLが格納されている。
# ローカルの画像を画像サーバ(imgur)にアップロードする library("imguR") tmp <- "oretachinoglobalr.png" # 引き延ばした画像 res_upload <- upload_image(tmp) url_image <- res_upload$link
画像をMicrosoft FACE APIにPOSTして結果を取得する
先の画像URLをMicrosoft FACE APIにPOSTして、結果を取得する。
この際、Subscribe Keyが必要なので取得しておいてほしい。
このあたりの記事を参照のこと。
POSTにはhttrパッケージを用いる。
# 画像をMicrosoft FACE APIにPOSTして結果を取得する library("httr") MS_FACE_KEY <- "取得したSubscribe Key" url_request <- "https://westus.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses,emotion" body <- list(url=url_image) res <- POST(url=url_request, encode="json", body=body, add_headers(`Ocp-Apim-Subscription-Key`=MS_FACE_KEY), content_type_json() ) res <- content(res)
結果を集計する
結果はcontent()でJSONからRのリストに変換されている。
この結果を集計する。
集計後はアップロードした画像を消去する。
この際、imguRパッケージのdelete_image()にdeletehashを指定する。
# リストで返ってくる結果を集計する count_megane <- table(unlist(lapply(res,function(x)x$faceAttributes$glasses))) # アップロードした画像を消去する delete_image(res_upload$deletehash)
結果は以下の通り。
Face APIではメガネとして noGlasses、readingGlasses、sunglasses、swimmingGoggles の4つを判定可能である。
メガネ着用率は43.8%という結果になった。
この数字が高いか低いかわからないので、外国の集合写真などと比較してみる必要があるだろう。がんばってほしい。
> count_megane NoGlasses ReadingGlasses 18 14 > round(prop.table(count_megane) * 100, 1) NoGlasses ReadingGlasses 56.2 43.8
まとめると、以下のようなコードになる。
# ローカルの画像を画像サーバ(imgur)にアップロードする library("imguR") tmp <- "oretachinoglobalr.png" # 引き延ばした画像 res_upload <- upload_image(tmp) url_image <- res_upload$link # 画像をMicrosoft FACE APIにPOSTして結果を取得する MS_FACE_KEY <- "取得したSubscribe Key" url_request <- "https://westus.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses,emotion" body <- list(url=url_image) res <- POST(url=url_request, encode="json", body=body, add_headers(`Ocp-Apim-Subscription-Key`=MS_FACE_KEY), content_type_json() ) res <- content(res) count_megane <- table(unlist(lapply(res,function(x)x$faceAttributes$glasses))) # アップロードした画像を消去する delete_image(res_upload$deletehash) count_megane round(prop.table(count_megane) * 100, 1)
余談だが、当初はGoogle Cloud Vision APIでやろうかと思っていた。
しかしメガネの着用有無が判定できないのでやむなくMicrosoft FACE APIを用いた。
Enjoy!