使用iOS CIDetector面部检测来触发功能

时间:2015-01-15 15:11:08

标签: ios avfoundation face-detection

我正在尝试使用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

1 个答案:

答案 0 :(得分:2)

在故事板中,您应该向主视图添加新视图并创建插座:

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

您添加的按钮应与新创建的子视图位于同一层次结构中。 此按钮也应位于新创建的子视图的前面。

在您的代码更改中:

[self.view.layer addSublayer:_previewLayer];

为:

[self.containerView.layer addSublayer:_previewLayer];

希望这些帮助

更新

如果你有手势识别器而没有用户界面,那么你可以使用这个快速简单的解决方法:

 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;