Core Imageの顔認識をOS Xで - その1 [OpenCV関係]
1 はじめに
こないだからいじっているポリゴンレンダラつながりでCore Imageフレームワークに10.7から実装された顔認識についてまとめてみる。僕の認識では顔認識と言えばOpenCVだったんだけど、顔認識のニーズは高くて独自実装がスマホやデジカメだけでなくテレビなどにも搭載されるようになっているらしい。アルゴリズムは基本的にはOpenCVと同じように、特徴をツリー(カスケード)に列挙してにして全てにマッチしたものを顔とみなす、という方法になっていると思われるが、ツリーの構成の仕方や学習データの違いで認識精度や実行効率に差が出てくるはずである。もちろんOpenCV以外はソースにあたれないので想像でしかないけど。
OS XのCore Imageフレームワークに顔認識の機能が10.7から追加された。もちろん本来iOSで使るようにというのが動機で、OS Xはオマケでついでに実装された、と言う感じになっている。しかし非力なiOSで実用に堪えるようならOS Xでは楽勝だろう、と思って試しに動かしてみることにした。最終的にOpenCVと比較する。
前もって言っておくが、僕が書くのはOS XとMac装備のFaceTimeカメラでの使い方に関してであって、iOSは知らない。iOSなら他の人がいっぱい書いてるだろうと思うのでそっちを見て欲しい。
ところでまず訂正がある。以前、CGImageはピクセルの色の並びのデフォルトがBGRで、NSBitmapImageRepはRGBだと書いたが、これは僕の勘違いだった。どちらもRGB並びだった。CIImageもデフォルトではRGBなのでこの範囲では全部一緒。申し訳ない。まず訂正しておく。この色の並びの問題は、あとで影響してくる。
2 CIDetector
Core Imageフレームワークの顔認識はCIDertectorというクラスで実現されている。呼び出すのは簡単で、インスタンスを作ったあと、CIImageの画像を渡して解析させるだけ。非常に簡単だけど、調整できるパラメータはOpenCVに比べると極端に少ない。2.1 インスタンス生成
CIDetectorのインスタンスを作るにはCIDetector detector; CIContext *ciContext; NSDictionary *dic; // ciContextとdicの初期化 detector = [[CIDetector detectorOfType:CIDetectorTypeFace context:ciContext options:dic] retain];と言う感じ。引数は3つあって
- 認識対象
- CIContextのインスタンス
- オプション
ふたつめの引数は描画コンテクストである。解析対象のCIImageと同じコンテクストを渡せ、とReferenceには書いてある(nilでもいいかどうかは書いてないが、nilを渡してもとりあえず動く)。コンテクストを渡すとパフォーマンスがあがる、となっている。このCIDetectorのインスタンスを作るタイミングによるけど、CIImageを作るまえにコンテクストが決定できれば渡すことができるだろう。
ReferenceにはCIDetectorは大量のリソースを作って保持したままにするので、なるべく使い回せ、と書いてある。実装ではこのインスタンスを作るタイミングが難しくなる。
最後の引数はオプションで、今のところ
- CIDetectorAccuracy(10.7以降)
- CIDetectorTracking(10.8以降)
- CIDetectorMinFeatureSize(10.8以降)
- CIDetectorAccuracyLow
- CIDetectorAccuracyHigh
CIDetectorTrackingは静止画に対してではなく、動画で連続して同じ顔を追跡したいなら、YES(の値を保持したNSNumberインスタンス)を与える。Referenceにもヘッダにもあまり詳しい記述はないけど、複数の顔があったときに、それぞれに別のID(整数)が振られてそれが何フレーム分同じ顔と認識したか、と言う情報が得られるらしい。
CIDetectorMinFeatureSizeは文字通り最小のサイズを指定する。元画像の大きさの比(0〜1)で指定する。
こういうオプションの違いによる効果はあとで実際に動作させて整理する。
2.2 認識実行
認識実行はCIDetectorのインスタンスにCIImage *image; NSArray *features = [detector featuresInImage:image];というふうに顔が含まれた画像をCIImageにして渡す。その結果がCIFeatureのインスタンスの配列で返ってくる。CIFeatureはたんなるコンテナクラスで、
- bounds
- type
このふたつだけではちょっとさみしいけど、実はCIFeatureのサブクラスでCFFaceFeatureというのがあって、顔認識の結果はこのインスタンスが返ってくる。
こいつは
- letEyePosition
- rightEyePosition
- mouthPosition
- trackingID
- trackingFrameCount
これらのプロパティについてはあとで実際の動作をまとめる。
この他にCIDetectorはfeaturesInImage:options:というメソッドも持っているが、画像がどっち向きなのか(縦なのか横なのかなど)を指定できるオプションを持っているだけである。iOSや、デジカメ画像を解析するときには意味があるけど、OS XでFaceTimeカメラを使う限りは関係ない。
2013-07-27 23:18
nice!(0)
コメント(0)
トラックバック(0)
コメント 0