この記事はMonstar Lab, Inc. Advent Calendar 2016 12日目の記事です。
遅まきながらCloud Vision APIです。
Type=FACE_DETECTION
(顔認識)でやってみます。
Google Cloud Vision API
公式
Google Cloud Vision APIを使ってみた
お値段
料金表
ユニット
単位での請求となる。
1000ユニットまでなら無料で使える。
ユニットは画像の枚数のことではない。
1画像に対して"顔認識とラベル検知"としてAPI利用した場合、2ユニット利用となる。
APIキーの発行
実装前の準備です。
Google Developers Consoleに請求先情報を未登録の方はクレジットカードを握りしめて作業を開始してください。
※無料トライアルでも登録必須です。
-
公式から
コンソールを開く
- 請求先情報などの入力を行う
- 新規にプロジェクトを作成
-
Google Cloud API
->Vision API
を選択 -
有効にする
-> 課金を求められるのでOK -
認証情報
->認証情報を作成
->APIキー
を選択 - とりあえず
制限なし
でAPIキーを作成
実装
公式サンプルがあります。
Type=LABEL_DETECTION
(物体の分類)になっているので、リファレンスを見ながら、必要なところを顔認識に書き換えます。
簡単に、1人だけ写ってる画像から表情(感情)を抽出する、という内容にします。
Feature typeの書き換え
before
annotateImageRequest.setFeatures(new ArrayList<Feature>() {{
Feature labelDetection = new Feature();
labelDetection.setType("LABEL_DETECTION");
labelDetection.setMaxResults(10);
add(labelDetection);
}});
after
annotateImageRequest.setFeatures(new ArrayList<Feature>() {{
Feature labelDetection = new Feature();
labelDetection.setType("FACE_DETECTION");
labelDetection.setMaxResults(1);
add(labelDetection);
}});
結果は1件だけ取得するようにします。
結果取得対象の書き換え
before
private String convertResponseToString(BatchAnnotateImagesResponse response) {
String message = "I found these things:\n\n";
List<EntityAnnotation> labels = response.getResponses().get(0).getLabelAnnotations();
if (labels != null) {
for (EntityAnnotation label : labels) {
message += String.format("%.3f: %s", label.getScore(), label.getDescription());
message += "\n";
}
} else {
message += "nothing";
}
return message;
}
after
private String convertResponseToString(BatchAnnotateImagesResponse response) {
String message = "I found these facial expressions:\n\n";
List<FaceAnnotation> labels = response.getResponses().get(0).getFaceAnnotations();
if (labels != null) {
for (FaceAnnotation label : labels) {
message += String.format("Joy:%s", label.getJoyLikelihood());
message += "\n";
message += String.format("Sorrow:%s", label.getSorrowLikelihood());
message += "\n";
message += String.format("Anger:%s", label.getAngerLikelihood());
message += "\n";
message += String.format("Surprise:%s", label.getSurpriseLikelihood());
}
} else {
message += "nothing";
}
return message;
}
(とても雑で申し訳ないです。。。)
結果
Likelihood
の言葉が示すとおり、「喜んでいる(楽しそうな)表情である可能性」という形で返ってきます。
値の意味はこちらにある通りです。
UNKNOWN
を除いて5段階評価となっています。
なお、そもそも"人でない場合"は結果は0件となります。
精度(の感想)
そんなに細かく検証したわけではないので、感想レベルに留まります。
- 正面向きでハッキリした表情なら"VERY_LIKELY"となる。
- 帽子をかぶっていても大丈夫だが、目元が暗くなると判別できなくなる。
- 横向きでもハッキリした笑顔なら大丈夫。
- "くしゃっとした笑顔"はJoyとSorrowの両方が"LIKELY"や"POSSIBLE"となり、曖昧。
- 真顔は全て"VERY_UNLIKELY"。
- 笑顔は精度出るが、他は微妙な気がする。
- モノクロ画像は結果が曖昧になる。
- 元は結果の得られた画像も、モノクロにすると全て"VERY_UNLIKELY"になる、など。
- 写実的なら絵でも銅像でも"顔"と判断される。
- モナリザ:OK(無表情あつかい)
- 阿修羅像:OK(無表情あつかい)
- 三億円事件のモンタージュ写真:OK(機械には悲しんでる様に映るらしい)
- 森気楼氏の絵:OK(感情も結構取れる!)
- 西村キヌ氏の絵:NG
- アニメのキャラクター:NG
まとめ
20年前から好きでしたが、改めて森気楼氏の絵は素晴らしいと思いました。
それが言いたかっただけです。