【问题标题】:Using iOS CIDetector face detection to trigger function使用iOS CIDetector人脸检测触发功能
【发布时间】:2015-03-14 00:41:30
【问题描述】:

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

【问题讨论】:

  • 你检查过 AVCaptureMetadataOutput 委托方法了吗? - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection 这个应该在检测到人脸后调用。这里有更多信息:stackoverflow.com/questions/18995236/…
  • 我已经添加了建议的功能,但它似乎什么也没做..
  • @BiancaIoana 您可能必须在 UI 线程上执行 self.retakeButton.hidden = NO;
  • @MateuszSzlosek 进入函数但 self.retakeButton.hidden = NO;不叫
  • 请在委托方法中添加NSLog(@"%@",metadataObjects);并粘贴输出。

标签: ios avfoundation face-detection


【解决方案1】:

在您的故事板中,您应该向主视图添加一个新视图并创建出口:

@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;

【讨论】:

  • 当它检测到人脸时,它会在屏幕上显示按钮。但是,当脸部从相机的框架中消失时,它并没有被隐藏。我该如何解决?
  • 我是否应该使用完成处理程序将按钮设置为 hidden=no 当它完成运行 captureOutput 时?如果是这样,我该怎么做?
猜你喜欢
  • 2012-06-24
  • 2015-12-23
  • 2013-05-02
  • 1970-01-01
  • 2017-09-04
  • 2019-01-30
  • 2013-07-16
  • 2012-08-25
  • 1970-01-01
相关资源
最近更新 更多