顔検出機能を扱うiOS 5の「CIDetector」
まず、撮影した画像を受け取るにはUIImagePickerControllerDelegateプロトコルのimagePickerController:didFinishPickingMediaWithInfo:メソッドを実装します。
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// 撮影画像を取得
UIImage *originalImage = (UIImage *) [info objectForKey:UIImagePickerControllerOriginalImage];
// 撮影した写真をUIImageViewへ設定
picture.image = originalImage;
// 検出器生成
NSDictionary *options = [NSDictionary dictionaryWithObject:CIDetectorAccuracyLow forKey:CIDetectorAccuracy];
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:options];
// 検出
CIImage *ciImage = [[CIImage alloc] initWithCGImage:originalImage.CGImage];
NSDictionary *imageOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:6] forKey:CIDetectorImageOrientation];
NSArray *array = [detector featuresInImage:ciImage options:imageOptions];
// 検出されたデータを取得
for (CIFaceFeature *faceFeature in array) {
// 眼鏡画像追加処理へ
[self drawMeganeImage:faceFeature];
}
// カメラUIを閉じる
[self dismissViewControllerAnimated:YES completion:nil];
}
■ 撮影画像を取得してUIImageViewへ設定
- - PR -
まず、引数であるinfoからUIImagePickerControllerOriginalImageをキーにして撮影した画像を取得し画面にセットします。
■ 精度を設定して検出器生成
次に顔検出を行うCIDetectorクラスのインスタンスを生成します。3つ目の引数として渡すNSDictionaryには、CIDetectorAccuracyキーでCIDetectorAccuracyLowとCIDetectorAccuracyHighのどちらかをセットします。これは名前の通り、検出の精度を表しています。
CIDetectorAccuracyLowは検出精度は低いが、その分パフォーマンスが良くCIDetectorAccuracyHighは検出精度は高いが、その分パフォーマンスは悪くなります。
筆者が試したところ、写真によっては、どちらを利用しても検出精度はあまり変わらないという感想を持っています。そのため、今回はパフォーマンスを重視してCIDetectorAccuracyLowにしています。
■ 顔検出の実行
次は、いよいよ顔検出です。先ほど撮影した画像はUIImageクラスでしたが、検出はCIImageクラスでないとできないため、CIImageのインスタンスを生成します。また、検出のオプションを生成しますが、ここでは写真の向きを表すCIDetectorImageOrientationキーを設定しています。
撮影した画像のUIImageは向きを持っていますが、CIImageの時点で向きの情報は消えてしまいます。顔検出には写真の向きが必要になるため、「6」をCIDetectorImageOrientationキーとしてNSDictionaryを生成します。この「6」とは、ホームボタンが下にある状態で撮影した場合になります。
検出には、CIDetectorクラスのfeaturesInImageメソッドを利用します。CIImageとNSDictionaryを引数とし、検出された顔の数だけNSArrayが返されます。このNSArrayには、検出された顔の数だけCIFaceFeatureが入っています。
検出した顔にメガネをかけさせよう
顔検出で取得したCIFaceFeatureクラスからメガネの位置やサイズを決めていきます。
- (void)drawMeganeImage:(CIFaceFeature *)faceFeature
{
if (faceFeature.hasLeftEyePosition && faceFeature.hasRightEyePosition && faceFeature.hasMouthPosition) {
// 顔のサイズ情報を取得
CGRect faceRect = [faceFeature bounds];
// 写真の向きで検出されたXとYを逆さにセットする
float temp = faceRect.size.width;
faceRect.size.width = faceRect.size.height;
faceRect.size.height = temp;
temp = faceRect.origin.x;
faceRect.origin.x = faceRect.origin.y;
faceRect.origin.y = temp;
// 比率計算
float widthScale = picture.frame.size.width / picture.image.size.width;
float heightScale = picture.frame.size.height / picture.image.size.height;
// 眼鏡画像のxとy、widthとheightのサイズを比率似合わせて変更
faceRect.origin.x *= widthScale;
faceRect.origin.y *= heightScale;
faceRect.size.width *= widthScale;
faceRect.size.height *= heightScale;
// 眼鏡のUIImageViewを作成
UIImage *glassesImage = [UIImage imageNamed:@"megane.png"];
UIImageView *glassesImageView = [[UIImageView alloc]initWithImage:glassesImage];
glassesImageView.contentMode = UIViewContentModeScaleAspectFit;
// 眼鏡画像のリサイズ
glassesImageView.frame = faceRect;
// 眼鏡レイヤを撮影した写真に重ねる
[picture addSubview:glassesImageView];
}
}
CIFaceFeatureクラスには、左右の目の位置や口の位置などの情報が入っていますが、今回は顔の範囲であるboundsの値からメガネの位置やサイズを決めていきます。
CIFaceFeatureクラスのboundsはCGRectクラスです。x、y、width、heightの値がありますが、前項で説明した通り、取得した値の画像の向きが正しくないため、xとy、widthとheightの値を入れ替える必要があります。
入れ替えたら実際の画像サイズと表示されている画像サイズの比率を算出します。そして、顔の範囲のCGRectクラスを比率に合わせて修正していきます。
最後にメガネ画像のUIImageViewクラスを作成し、frameにサイズを合わせたCGRectクラスを指定します。できたViewを撮影した画像のサブViewとして追加すれば完成です。
iOSの顔検出は難しくない
今回はメガネの画像を、もともと人の顔と同じぐらいのサイズになるよう作成していたので、顔の範囲からメガネ画像の向きを決めましたが、もっと詳細にやる場合は、左右の目の位置や口の位置から正確にメガネの位置やサイズを決めることも可能です。
また、詳細な位置を利用すれば、斜めになっている顔にもキレイにメガネをかけることが可能です。
顔検出についての説明を重視したため、viewを重ねただけの、疑似的な画像表示となっていますが、CALayerクラスなどを利用して1枚の画像として作成すると、フォトライブラリへの保存なども可能になります。
顔検出という名前から、難しそうなイメージはありますが、便利なクラスが用意されているので難しく考えずに、皆さんいろいろと試してみてください。
■ @IT関連記事
画像をタッチ編集! アートなiPhoneカメラアプリを作る Retinaに映える! iOS美麗アプリ制作入門(3) カメラの起動やピクセル情報の扱いが簡単なopenFrameworksを使ってタッチやドラッグで画像の色見を変えるアプリを作ろう 「Smart & Social」フォーラム 2012/5/8 |
iPhoneで動くARアプリを作るためのライブラリ10選 モバイルARアプリ開発“超”入門(5) ARToolkitをはじめ、iOS(iPhone/iPad)で使えるAR(拡張現実)を実現するためのさまざまなライブラリをサンプルやコードを交えて紹介 「Smart & Social」フォーラム 2012/1/25 |
グランプリは生徒と先生が作った役に立つAR D89クリップ(34) 今年のiPhone・iPadアプリ大賞を勝手に決めてしまうイベントで、最終プレゼンに選ばれた12組のアプリを紹介します |
Web RTC、Face.jsとJSARToolkitのお味は? HTML5の味見しちゃうよ(1) Web RTC、Face.jsとJSARToolkitを試した。JavaScriptを使って、Webカメラで顔認識とAR(拡張現実)してみよう |
ARに使えるOpenCVで作る画像認識Androidアプリ モバイルARアプリ開発“超”入門(終) オープンソースのコンピュータヴィジョンライブラリ「OpenCV」を利用した画像認識アプリの作成について簡単なサンプルを交え解説 「Smart & Social」フォーラム 2012/3/1 |
Android 4.0で注目の顔認識をアプリに組み込むには Androidで動く携帯Javaアプリ作成入門(28) カメラを使った画面アンロック、オートフォーカス、ライブエフェクトなど応用例が多彩な顔認識機能を使うための基礎知識を解説 「Smart & Social」フォーラム 2012/1/18 |
もはやケータイに必須のカメラをAndroidで制御しよう Androidで動く携帯Javaアプリ作成入門(17) 標準カメラ制御用APIを解説します。起動・終了・撮影だけでなくフォーカスやフラッシュなども制御できます。ARに応用も!? 「Smart & Social」フォーラム 2010/5/27 |
App InventorでもAndroidで人気のカメラアプリを作る App Inventorでアプリ開発はどこまでできるのか(4) App Inventorのカメラ部品の概要、JavaのAPIで扱うときとの違いを解説し簡単な落書きカメラアプリの作り方を紹介する 「Smart & Social」フォーラム 2011/7/19 |
Windows Phoneで動くカメラアプリ作成の基礎知識 Silverlightベースで作るWP7アプリ開発入門(7) iPhoneやAndroidでも人気のカメラを使ったアプリの作り方の基本としてプレビュー表示や撮影画像の保存方法を解説 「Smart & Social」フォーラム 2011/12/2 |
Silverlightで作れるAR(拡張現実)アプリの基礎知識 楽しいWindows 7アプリ作成入門(4) オープンソースライブラリ「NyARToolkitCS」「SLARToolkit」の登場でWPF、C#、Silverlight環境でもARが体験できるようになりました |
1-2 |
INDEX | ||
iPhone/iPadスマートアプリ開発レシピ(3) iOS 5の顔検出機能とカメラを使ったiPhoneアプリを作る |
||
Page1 カメラと顔検出を利用したメガネアプリ いまさら聞けない顔“検出”と顔“認識”の違い カメラ機能を扱うiOSの「UIImagePickerController」 |
||
Page2 顔検出機能を扱うiOS 5の「CIDetector」 検出した顔にメガネをかけさせよう iOSの顔検出は難しくない |
Smart&Social フォーラム トップページへ |
- 夏休みの自由研究にマイコンボードで「電子サイコロ」を作ったり、音楽プログラミングをしたりしてみよう (2017/7/24)
子ども向け電子工作&プログラミング用マイコンボード「chibi:bit」の基本的な使い方を紹介する企画。夏休みの自由研究に「電子サイコロ」を作ったり、音楽プログラミングをしたりしてみよう - 子ども向け電子工作&プログラミング用マイコンボード「chibi:bit」の基本的な使い方 (2017/7/20)
子ども向け電子工作&プログラミング用マイコンボード「chibi:bit」の基本的な使い方を紹介する。夏休みの子どもの自由研究などに役立てつつ、プログラミングを始めるきっかけにしてみてはいかがだろうか - 3DゲームのAIをiOSのSceneKitとGameplayKitで作る基本 (2017/7/10)
3Dゲーム用のフレームワークSceneKitを使った簡単なアプリ制作を通して、3Dゲーム用の人工知能(AI)について学ぶ - UnityアプリをWebGL、UWP、Android、iOS用としてビルドしてみた (2017/6/27)
アプリをWebで実行できるように書き出す方法やWindows上でUWP、Android、iOS用などにビルドする方法について解説する【Windows 10、Unity 5.6に対応】
|
|