連載
» 2012年01月18日 00時00分 UPDATE

Androidで動く携帯Javaアプリ作成入門(28):Android 4.0で注目の顔認識をアプリに組み込むには (1/2)

[緒方聡,株式会社イーフロー]

古くて新しい「顔認識」をアプリに組み込んでみよう

 連載第27回の「開発者が知らないと損するAndroid 4.0の新機能44選」では、Android 4.0の新機能を紹介しました。その中で筆者にとって印象的だったのが「顔認識」です。

 「顔認識による画面アンロック」は、フロントカメラで顔認識を行い端末のロックを解除するというものです。触らずに解除できるという点が便利そうです。「顔認識によるオートフォーカス」も「画像・動画を面白くするライブエフェクト」も、画面アンロックと同様、撮影前のプレビューで顔認識を行うというのが特徴的です。

 Androidの顔認識自体は歴史が古く、実はAndroid 1.0のころから存在します。そのころからの顔認識は静止画が対象です。

 今回は、この古い顔認識と新しい顔認識について取り上げます。いつものようにサンプルは以下よりダウンロード可能です。

FaceDetectExample.zip※本サンプルでは、Microsoft Wordのクリップアートの画像を使用しています。以降、サンプルアプリを使ったスクリーンショットもMicrosoft Wordのクリップアートの画像を基にしています

静止画の顔認識「FaceDetector」

 「android.media.FaceDetector」というクラスを使用することで、静止画の顔認識が行えます。

図1 顔認識結果 図1 顔認識結果

FaceDetectorの使い方

 使い方は以下のような感じです。

// 認識した顔の情報を保持する配列を定義
FaceDetector.Face faces[] = new FaceDetector.Face[10];
// 画像サイズと顔情報配列の長さでFaceDetectorを生成
FaceDetector detector = new FaceDetector(width, height, faces.length);
// 顔認識開始
detector.findFaces(bitmap, faces);

 顔認識を行う前に顔情報の数を決めなければならないのが多少ぎこちないですが、使い方としては簡単です。

FaceDetectorの使う際の注意点

 顔認識は同期処理で行われます。大き目の画像を顔認識に掛けると、数秒かかることがあります。1600x1600サイズの画像を顔認識させたところ、最新のGalaxy Nexusでも5秒程度かかりました。ユーザーの操作を妨げないように、また「Application Not Responding」 (通称:ANR)が発生しないように注意してください。

 FaceDetector#findFaces()に渡すBitmapインスタンスの色深度は16bitでなければなりません。これはFaceDetectorがAndroid 1.0のころからあるAPIであること、Android 1.0〜2.2までは基本的に色深度が16bitだったこと、互換性を考慮して実装を変えていないと思われることなどがその理由です。

 現在では、Bitmapクラスは32bitで扱うことが多いため、以下のように読み込む際に16bitにするか、すでにあるBitmapであれば、顔認識用に減色したBitmapを作るかします。

// 読み込む際に16bitに減色
Options opts = new Options();
// RBG_565を選択(透過ならARGB_444)
opts.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeResource(
    context.getResources(), R.drawable.image0, opts);
// または、16bitのコピーを生成
Bitmap bitmap2 = bitmap.copy(Bitmap.Config.RGB_565, true);

FaceDetectorで得られる情報

 顔認識結果の「FaceDetector.Face」クラスには、以下の情報が含まれています。

情報取得メソッド 説明
Face#confidence() 信頼度。0から1の間の値。高いほどよく、0.3以上ならそこそこ信頼できる(とJavadocには書かれている)
Face#eyesDistance() 目と目の間の距離。今回のサンプルではこの値を元に顔(赤い枠)の大きさを求めている
Face#getMidPoint(PointF point) 顔の中央を求める
Face#pose(int euler) X軸、Y軸、Z軸に対する顔の傾きを取得

顔認識の精度はどれくらい?

 今回のサンプルでは正面を向いた顔写真を使ったので、すべての顔が信頼度0.5程度で認識されました(信頼度の信頼性については後述します)。

図2 すべてのサンプル画像の顔認識結果 図2 すべてのサンプル画像の顔認識結果
r503.gif
r504.gif


 顔認識をいろいろな画像で試してみたところ、以下のような傾向がわかりました。

  • 証明写真のようにはっきりとした正面の顔写真はまず認識できる
  • 画像に対して顔が小さく、かつピントが合っていないと認識できないことがある
  • 顔の傾き加減で認識できないことがある
  • 顔の一部が隠れていると認識できないことがある
  • 画像が大きすぎると思わぬところに顔が認識される
  • イラストや漫画はほとんど認識できない

 以下は、少し大きめの写真で顔認識した際に、誤認識した箇所です。

図3 誤認識結果 図3 誤認識結果
r506.jpg

 右の画像は、拡大するとネクタイの模様が目と口に見えなくもないですが、左の画像の方はどうして顔に認識されてしまったのか分かりません。

 また、どちらも信頼度が0.5程度あり、筆者が試した限りでは認識できた場合の信頼度は常に0.5程度であるため、この信頼度は当てにならないと感じています。

 イラストや漫画は写真とは反対に、顔が小さい方がよく認識される傾向ですが、それでも認識率はよくありません。

 次ページでは、静止画ではなく、プレビューを使った顔認識機能について解説します。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

Focus

- PR -

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。