en

hi, it seems you are using microsoft internet explorer. it doesn't match web standard and causes problems browsing this site. please please please use mozilla firefox or google chrome instead. thank you!

zh

哦哦!您正在使用Internet Explorer 瀏覽器,它與我們的網頁標準並不相容,可能會導致畫面顯示不正常。
請改用 Mozilla Firefox 或者 Google Chrome 才能正常瀏覽本網站,謝謝!

11.01.2012

實作人臉偵測

 

從 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,並不會改變圖片本身的大小或是比例。






沒有留言:

張貼留言