2015-01-15 39 views
1

我試圖使用CIDetector製作面部檢測器,只要檢測到面部就啓用按鈕。我搜索和找不到的部分是如何在代碼檢測到人臉時觸發一個函數。當臉部離開相機框時禁用它。使用iOS CIDetector面部檢測功能觸發功能

這裏是我到現在爲止代碼:

.h文件中:

#import <UIKit/UIKit.h> 

@interface ViewController : UIViewController 

@property (weak, nonatomic) IBOutlet UIButton *actionButton; 
//Update 2: 
@property (weak, nonatomic) IBOutlet UIView *containerView; 

- (IBAction)actionButton:(id)sender; 

@end 

.m文件:

#import "ViewController.h" 
@import AVFoundation; 

@interface ViewController() <AVCaptureMetadataOutputObjectsDelegate> { 
    AVCaptureVideoPreviewLayer *_previewLayer; 
    AVCaptureSession *_session; 
    CIDetector *_faceDetector; 
    CIContext *_ciContext; 
} 

@end 

@implementation SCViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 


    // Create a new AVCaptureSession 
    _session = [[AVCaptureSession alloc] init]; 
    [_session setSessionPreset:AVCaptureSessionPreset640x480]; 
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    NSError *error = nil; 


    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; 

    if(input) { 
     // Add the input to the session 
     [_session addInput:input]; 
    } else { 
     NSLog(@"error: %@", error); 
     return; 
    } 

    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init]; 
    // Have to add the output before setting metadata types 
    [_session addOutput:output]; 

    // Restrict the output metadata to faces 
    [output setMetadataObjectTypes:@[AVMetadataObjectTypeFace]]; 
    // This VC is the delegate. Please call us on the main queue 
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; 


    // Display on screen 
    _previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session]; 
    _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
    _previewLayer.bounds = self.view.bounds; 
    _previewLayer.position = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds)); 
    // Update 2 change 
    [self.containerView.layer addSublayer:_previewLayer]; 
    // Hide the button 
    self.actionButton.hidden = YES; 
    // Start the AVSession running 
    [_session startRunning]; 
} 



// Update 1: 

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputMetadataObjects:(NSArray *)metadataObjects 
     fromConnection:(AVCaptureConnection *)connection 
{ 
    for(AVMetadataObject *metadataObject in metadataObjects) { 
     if([metadataObject.type isEqualToString:AVMetadataObjectTypeFace]) { 

      self.retakeButton.hidden = NO; 
     } 
    } 
} 

- (IBAction)actionButton:(id)sender { 

}  
@end 
+0

你檢查AVCaptureMetadataOutput委託方法? ' - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)來自連接的元數據對象:(AVCaptureConnection *)連接'這個sohuld會在檢測到face後調用。這裏有更多的信息:http://stackoverflow.com/questions/18995236/ios-7-avcapturemetadataoutput-delegate-qrcode-scanner – 2015-01-15 15:25:57

+0

我已經添加了建議的功能,但它似乎什麼都不做。 – 2015-01-15 15:40:12

+0

@BiancaIoana你可能不得不做'self.retakeButton.hidden = NO;'在UI線程上。 – Kiran 2015-01-15 15:43:04

回答

2

在你的故事板,你應該添加一個新的視圖主視圖並創建出口:

@property (weak, nonatomic) IBOutlet UIView *containerView; 

您添加的按鈕應該與新創建的子視圖具有相同的層次結構。 此按鈕應該在新創建的子視圖的前面。

而在你的代碼更改:

[self.view.layer addSublayer:_previewLayer]; 

到:

[self.containerView.layer addSublayer:_previewLayer]; 

希望這些幫助

更新:

如果你有手勢識別和不超過UI吧你可以使用這個快速簡單的修復:

NSTimer *timer = [NSTimer timerWithTimeInterval:0.2f target:self selector:@selector(hideButton) userInfo:nil repeats:YES]; 
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 

其中:

-(void)hideButton{ 

    if(counterSeconds==2){ 
     if (counterCaptureOutput==0) { 
      NSLog(@"hide button"); 
      [self.retakeButton setHidden:YES]; 
     } 
     counterCaptureOutput=0; 
     counterSeconds=0; 
    } 
    counterSeconds++; 
} 

和:

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputMetadataObjects:(NSArray *)metadataObjects 
     fromConnection:(AVCaptureConnection *)connection 
{ 
    for(AVMetadataObject *metadataObject in metadataObjects) { 
     if([metadataObject.type isEqualToString:AVMetadataObjectTypeFace]) { 
      self.retakeButton.hidden = NO; 
      counterCaptureOutput++; 
      NSLog(@"ENTER FUNCTION"); 
     } 
    } 
} 

也包括在.M:

int counterCaptureOutput; 
int counterSeconds; 
+0

我的答案已更新我的代碼。謝謝! – 2015-01-15 17:17:18

+0

它接縫做,欺騙按鈕顯示在屏幕上時,它檢測到一個面孔。但是,當臉部從相機的框架中消失時,它不會隱藏。我該如何解決它? – 2015-01-15 17:25:19

+0

當它完成運行captureOutput時,我應該使用完成處理程序將按鈕設置爲hidden = no嗎?如果是這樣,我該怎麼做? – 2015-01-15 17:32:29