從 iOS 5.0 SDK 開始,就可以使用 CoreImage.framework 來實作人類的臉部偵測,透過 CIDetector 類別,我們可以製作一個偵測濾鏡,並且設定它的精準程度,下面就來看看如何實作它,在實作前請先對專案新增 CoreImage.framework,並引用其標頭檔於對應的 Class 中,新增的方法請參考 Xcode 4 新增 Framework 的方法一文。(圖片來源:www.cafebabel.co.uk)
從圖像中取得人臉偵測的數據
在 UIImage 中取得人臉偵測的數據非常的簡單,下列程式碼我們將製作一個臉部偵測的 CIDetector,並使用高精準度參數,最後將取得的數據存放於 NSArray 之中。
UIImage *imageSource = [self.myImageView image];
CIImage *image = [CIImage imageWithCGImage:imageSource.CGImage];
//宣告一個CIDetector並設定偵測類型與參數
CIDetector* faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace
context:nil options:[NSDictionary dictionaryWithObject:CIDetectorAccuracyHigh forKey:CIDetectorAccuracy]];
//取得偵測結果
NSArray *detectResult = [faceDetector featuresInImage:image];
NSLog(@"%@", detectResult);
成功取得四組的臉部偵測結果 |
ps:在上述製作 CIDetector 的參數中,其中一項參數 context,可以用來輸入預設的人臉,進而增加偵測的成功機率。
繪製取得的臉部數據
在成功取得臉部數據的資料之後,接下來就是要將這些資料繪出,以便驗證所偵測數據正確與否,在上述 NSArray 中所取得的每筆資料皆為 CIFaceFeature 型態,其中包含許許多多不同的屬性,下面我們就針對臉部、雙眼與嘴巴的部份進行驗證,由於繪製臉部的數據需要動用到 UIView 的 Layer,所以在實作前請先記得對專案新增 QuartzCore.framework,並引用其標頭檔於對應的 Class 中。
//繪製偵測結果
UIView *resultView = [[UIView alloc] initWithFrame:self.myImageView.frame];
[resultView setTransform:CGAffineTransformMakeScale(1, -1)];
[self.view addSubview:resultView];
for(CIFaceFeature* faceFeature in detectResult) {
//臉部
UIView* faceView = [[UIView alloc] initWithFrame:faceFeature.bounds];
faceView.layer.borderWidth = 1;
faceView.layer.borderColor = [UIColor orangeColor].CGColor;
[resultView addSubview:faceView];
//左眼
if (faceFeature.hasLeftEyePosition) {
UIView* leftEyeView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 5)];
[leftEyeView setCenter:faceFeature.leftEyePosition];
leftEyeView.layer.borderWidth = 1;
leftEyeView.layer.borderColor = [UIColor redColor].CGColor;
[resultView addSubview:leftEyeView];
}
//右眼
if (faceFeature.hasRightEyePosition) {
UIView* rightEyeView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 5)];
[rightEyeView setCenter:faceFeature.rightEyePosition];
rightEyeView.layer.borderWidth = 1;
rightEyeView.layer.borderColor = [UIColor redColor].CGColor;
[resultView addSubview:rightEyeView];
}
//嘴巴
if (faceFeature.hasMouthPosition) {
UIView* mouthView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 5)];
[mouthView setCenter:faceFeature.mouthPosition];
mouthView.layer.borderWidth = 1;
mouthView.layer.borderColor = [UIColor redColor].CGColor;
[resultView addSubview:mouthView];
}
}
在上述的程式碼中,我們設計的概念是,製作一個與原先圖片相同大小與位置的 UIView(resultView),並且將其座標系倒置,即原點位置於左下角,之後才去繪製偵測的結果,並把結果逐一加至這個 UIView(resultView)中。
會這樣做的原因是因為,在 CoreImage 所預設的座標系中,原點位在左下角,並非我們一般所認知的左上角,同理,如果你是使用 storyboard 介面設計你的程式時,圖片在 UIImageView 中的對齊方式,也請設定在左下角 Bottom Left,這樣才能確保所得出的結果,與繪製的結果一致。
ps:偵測數據的結果是以圖片原大小為準,並非經過 UIImageView 變形縮放的結果,改變 UIImageView,並不會改變圖片本身的大小或是比例。
沒有留言:
張貼留言