選取圖像 + 人臉識(shí)別

今天無(wú)意翻到了人臉識(shí)別,突然想在ios設(shè)備上實(shí)現(xiàn),這里我們主要用到了幾個(gè)類:CIContext瑰艘,CIDetector

CIContext

CIContext 是Core Image的一個(gè)對(duì)象窘行,Core Image是一個(gè)OS X和iOS的圖像處理框架。通過(guò)它Core Image可以繪制一個(gè)CIFilter產(chǎn)生的結(jié)果端考。一個(gè)Core Image Context可以基于CPU或GPU雅潭。

CIDetector

Core Image 已經(jīng)提供了 CIDetector 類。用它來(lái)做人臉檢測(cè)已經(jīng)相當(dāng)好了却特,并且它已經(jīng)被優(yōu)化過(guò)扶供,使用起來(lái)也很容易:

CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace context:context options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];NSArray *faces = [faceDetector featuresInImage:image];

從該圖片中檢測(cè)到的每一張面孔都在數(shù)組 faces 中保存著一個(gè) CIFaceFeature 實(shí)例。這個(gè)實(shí)例中保存著這張面孔的所處的位置和寬高裂明,除此之外椿浓,眼睛和嘴的位置也是可選的。

@interface CIFaceFeature : CIFeature
{
    CGRect bounds;
    BOOL hasLeftEyePosition;
    CGPoint leftEyePosition;
    BOOL hasRightEyePosition;
    CGPoint rightEyePosition;
    BOOL hasMouthPosition;
    CGPoint mouthPosition;
    
    
    BOOL hasTrackingID;
    int trackingID;
    BOOL hasTrackingFrameCount;
    int trackingFrameCount;
    
    BOOL hasFaceAngle;
    float faceAngle;
    
    BOOL hasSmile;
    BOOL leftEyeClosed;
    BOOL rightEyeClosed;
}

人臉監(jiān)測(cè)的步驟是:先獲取圖像,然后轉(zhuǎn)成CIImage格式扳碍,利用CIFeature特征提岔,使用探測(cè)器CIDetector拿到所有的人臉,然后在圖中圈出左腔,即可達(dá)到人臉識(shí)別的目的唧垦,關(guān)鍵代碼如下:

//獲取圖片
    UIImage *image = self.imageview.image;
    //轉(zhuǎn)成CIImage
    CIImage *ciImage = [CIImage imageWithCGImage:image.CGImage];
    //拿到所有的臉
    NSArray <CIFeature *> *featureArray = [self.detector featuresInImage:ciImage];

    if (featureArray.count == 0) {
        NSLog(@"未檢測(cè)到人臉");
        //初始化提示框;
        UIAlertController *alert1 = [UIAlertController alertControllerWithTitle:@"提示" message:@"未檢測(cè)到人臉" preferredStyle: UIAlertControllerStyleAlert];
        [alert1 addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
            //點(diǎn)擊按鈕的響應(yīng)事件;
        }]];
        
        //彈出提示框;
        [self presentViewController:alert1 animated:true completion:nil];
        
    }else{
        //遍歷
        for (CIFeature *feature in featureArray){
            
            //將image沿y軸對(duì)稱
            CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, -1);
            //將image往上移動(dòng)
            CGFloat imageH = ciImage.extent.size.height;
            transform = CGAffineTransformTranslate(transform, 0, -imageH);
            //在image上畫出方框
            CGRect feaRect = feature.bounds;
            //調(diào)整后的坐標(biāo)
            CGRect newFeaRect = CGRectApplyAffineTransform(feaRect, transform);
            //調(diào)整imageView的frame
            CGFloat imageViewW = self.imageview.bounds.size.width;
            CGFloat imageViewH = self.imageview.bounds.size.height;
            CGFloat imageW = ciImage.extent.size.width;
            //顯示
            CGFloat scale = MIN(imageViewH / imageH, imageViewW / imageW);
            //縮放
            CGAffineTransform scaleTransform = CGAffineTransformMakeScale(scale, scale);
            
            //修正
            newFeaRect = CGRectApplyAffineTransform(newFeaRect, scaleTransform);
            newFeaRect.origin.x += (imageViewW - imageW * scale ) / 2;
            newFeaRect.origin.y += (imageViewH - imageH * scale ) / 2;
            NSLog(@"xxx:%f",newFeaRect.origin.x);
            
            //繪畫
            UIView *breageView = [[UIView alloc] initWithFrame:newFeaRect];
            breageView.layer.borderColor = [UIColor redColor].CGColor;
            breageView.layer.borderWidth = 2;
            [self.imageview addSubview:breageView];
        }

    }
監(jiān)測(cè)成功.png
監(jiān)測(cè)失敗.jpg

上述圖像載入的時(shí)候,采用了一個(gè)用戶頭像上傳的demo液样,順道一起研究了振亮,選取圖像可以選擇兩種途徑,第一種是拍照識(shí)別鞭莽,第二種從個(gè)人相冊(cè)中載入坊秸,并且將載入后的圖像寫入沙盒中。

選取圖像

@property(nonatomic,strong) UIPopoverController *imagePickerPopover; //

需要注意的是 UIPopoverController 澎怒,是iPad開(kāi)發(fā)中常見(jiàn)的一種控制器(在iPhone上不允許使用)
跟其他控制器不一樣的是褒搔,它直接繼承自NSObject,并非繼承自UIViewController
它只占用部分屏幕空間來(lái)呈現(xiàn)信息喷面,而且顯示在屏幕的最前面星瘾,但是在IOS9的時(shí)候已經(jīng)被廢除。

可以選用IOS8提供的新特性 UIPresentationController惧辈,UIPresentationController是提供高級(jí)視圖切換的類琳状。它讓管理present ViewController的過(guò)程變得簡(jiǎn)單。

在iPad的設(shè)置頁(yè)面盒齿,可以通過(guò)popOver彈出一個(gè)UIViewController念逞,這個(gè)彈出的,可以和用戶交互的Controller叫做PresentedViewController边翁,而后面那個(gè)被部分遮擋的UIViewController叫做PresentingViewController翎承,而在UIPresentationController中,PresentedViewController是presentation的content符匾,而PresentingViewController叫做Chrome叨咖。

  • UIPopoverPresentationController
    它在iOS8中替代了UIPopoverController,它在功能上與舊的controller完全等同啊胶,并且新增了一些內(nèi)置的適配特性芒澜,可以自動(dòng)適配iPad與iPhone。以下是新版與舊版接口的比較:

  • UIPopoverController使用方法:

UIViewController *contentController = [[UIViewController alloc] init];
UIPopoverController *poc = [UIPopoverController alloc] initWithContentViewController:contentController];
[poc presentPopoverFromBarButtonItem:item permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

但是這個(gè)是ipad的類创淡,如果要?jiǎng)?chuàng)建一個(gè)在iPad與iPhone上通用的方法痴晦,那么需要以下的代碼:

    UIViewController *contentController = [[UIViewController alloc] init];

    if([[UIDevice currentDevice] userInterfaceIdim] == UIUserInterfaceIdiomPad){
        UIPopoverController *poc = [UIPopoverController alloc] initWithContentViewController:contentController];
        [poc presentPopoverFromBarButtonItem:item permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }else{
       [self presentViewController:contentController animated:YES completion:nil];
    }

然而我們?nèi)绻褂肬IPopoverPresentationController,那么就不再需要判斷設(shè)備,例如:

    UIViewController *contentController = [[UIViewController alloc] init];

    UIPopoverPresentationController *popVC = contentController.popoverPresentationController;
    popVC.barButtonItem = item;
    popVC.permittedArrowDirections = UIPopoverArrowDirectionAny;
    popVC.delegate = self;

    [self presentViewController:contentController animated:YES completion:nil];

  • 將UIViewController的modalPresentationStyle設(shè)置成UIModalPresentationPopover琳彩,這個(gè)值用來(lái)實(shí)現(xiàn)popover效果誊酌,并且各個(gè)平臺(tái)自動(dòng)適應(yīng)部凑。第二行中,通過(guò)popoverPresentationController屬性來(lái)獲取它的popoverPresentationController碧浊,而不是創(chuàng)建一個(gè)新的涂邀。然后設(shè)置它的一些界面屬性,最后調(diào)用presentViewController方法來(lái)顯示這個(gè)controller箱锐。這樣就可以在iPad與iPhone顯示自動(dòng)適應(yīng)的popover效果了比勉。
    其中,iPhone上的自適應(yīng)是在delegate中實(shí)現(xiàn)的:
- (UIModalPresentationStyle)adaptivePresentationStyleForPresemtatopmController:(UIPresentationController * controller)
{
    return UIModalPresentationFullScreen;
}

- (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style
{ 
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller.presentedViewController];
    return navController;

}

  • UIImagePickerController

    UIImagePickerController 是系統(tǒng)提供的用來(lái)獲取圖片和視頻的接口,用UIImagePickerController 類來(lái)獲取圖片視頻驹止,大體分為以下幾個(gè)步驟:

  1. 初始化UIImagePickerController 類浩聋;
  2. 設(shè)置UIImagePickerController 實(shí)例的數(shù)據(jù)來(lái)源類型;
  3. 設(shè)置設(shè)置代理臊恋;
  4. 如果需要做圖片修改的話設(shè)置allowsEditing =yes衣洁。

數(shù)據(jù)來(lái)源類型一共有三種:

enum {
   UIImagePickerControllerSourceTypePhotoLibrary ,//來(lái)自圖庫(kù)
   UIImagePickerControllerSourceTypeCamera ,//來(lái)自相機(jī)
   UIImagePickerControllerSourceTypeSavedPhotosAlbum //來(lái)自相冊(cè)
};

在用這些來(lái)源的時(shí)候最好檢測(cè)以下設(shè)備是否支持;

 if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
        NSLog(@"支持相機(jī)");
    }
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
    {
        NSLog(@"支持圖庫(kù)");
    }
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
    {
        NSLog(@"支持相片庫(kù)");
    }

調(diào)用攝像頭來(lái)獲取資源

- (void)viewDidLoad {
    [super viewDidLoad];
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker = [[UIImagePickerController alloc]init];
    picker.view.backgroundColor = [UIColor orangeColor];
    UIImagePickerControllerSourceType sourcheType = UIImagePickerControllerSourceTypeCamera;
    picker.sourceType = sourcheType;
    picker.delegate = self;
    picker.allowsEditing = YES;
}

上面只是實(shí)例了UIImagePickerController及其屬性 在需要獲取圖片的時(shí)候需要彈出窗口調(diào)用

[self presentViewController:picker animated:YES completion:nil];

完整的選取相冊(cè)代碼如下:

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"請(qǐng)選擇打開(kāi)方式" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    [alert addAction:[UIAlertAction actionWithTitle:@"打開(kāi)相機(jī)" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
        imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
        //創(chuàng)建UIPopoverController對(duì)象前先檢查當(dāng)前設(shè)備是不是ipad
        if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
            self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
            self.imagePickerPopover.delegate = self;
            [self.imagePickerPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        }else{
            [self presentViewController:imagePicker animated:YES completion:nil];
        }
        
    }]];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"我的相冊(cè)" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
    
        imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        //創(chuàng)建UIPopoverController對(duì)象前先檢查當(dāng)前設(shè)備是不是ipad
        if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
            self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
            self.imagePickerPopover.delegate = self;
            [self.imagePickerPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
        }else{
        
            [self presentViewController:imagePicker animated:YES completion:nil];
        }
    }]];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *_Nonnull action){
        //取消
    }]];
    
    //彈出提示框
    [self presentViewController:alert animated:YES completion:nil];

本文從人臉識(shí)別出發(fā)抖仅,記錄了ios設(shè)備進(jìn)行人臉識(shí)別時(shí)坊夫,使用的CIDetector類,順帶溫習(xí)了一下拉起相冊(cè)的相關(guān)知識(shí)撤卢,由UIPopoverController到UIPresentationController环凿,詳細(xì)記錄。

附上傳送門:https://github.com/earthX/EXFaceRecognition

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末放吩,一起剝皮案震驚了整個(gè)濱河市智听,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌屎慢,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忽洛,死亡現(xiàn)場(chǎng)離奇詭異腻惠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)欲虚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門集灌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人复哆,你說(shuō)我怎么就攤上這事欣喧。” “怎么了梯找?”我有些...
    開(kāi)封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵唆阿,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我锈锤,道長(zhǎng)驯鳖,這世上最難降的妖魔是什么闲询? 我笑而不...
    開(kāi)封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮浅辙,結(jié)果婚禮上扭弧,老公的妹妹穿的比我還像新娘。我一直安慰自己记舆,他們只是感情好鸽捻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著泽腮,像睡著了一般御蒲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盛正,一...
    開(kāi)封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天删咱,我揣著相機(jī)與錄音,去河邊找鬼豪筝。 笑死痰滋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的续崖。 我是一名探鬼主播敲街,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼严望!你這毒婦竟也來(lái)了多艇?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤像吻,失蹤者是張志新(化名)和其女友劉穎峻黍,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拨匆,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡姆涩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了惭每。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骨饿。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖台腥,靈堂內(nèi)的尸體忽然破棺而出宏赘,到底是詐尸還是另有隱情,我是刑警寧澤黎侈,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布察署,位于F島的核電站,受9級(jí)特大地震影響峻汉,放射性物質(zhì)發(fā)生泄漏箕母。R本人自食惡果不足惜储藐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嘶是。 院中可真熱鬧钙勃,春花似錦、人聲如沸聂喇。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)希太。三九已至克饶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間誊辉,已是汗流浹背矾湃。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留堕澄,地道東北人邀跃。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蛙紫,于是被迫代替她去往敵國(guó)和親拍屑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)坑傅、插件僵驰、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,093評(píng)論 4 62
  • 想必大家都看過(guò)電影《鋼鐵俠》蒜茴,小編還是死忠粉呢!電影中除了非常有魅力的小羅伯特.唐尼外浆西,印象最深的就是鋼鐵俠的人工...
    神秘嘉賓方閱讀 639評(píng)論 2 2
  • 馬笛閱讀 78評(píng)論 0 0
  • 第四十六節(jié):好事不出門粉私,壞事傳千里! 杜海明的賬戶爆倉(cāng)事件在黃河期貨公司內(nèi)部成為了熱門話題室谚。人們議論紛紛毡鉴,有可惜杜...
    luozi閱讀 209評(píng)論 0 0