2016-04-21 6 views
5

Ich bin Aufgabe des Scannens Frontkamera Eingang für Gesichter, erkennen sie und bekommen sie als UIImage-Objekte. Ich verwende AVFoundation zum Scannen und Erkennen von Gesichtern.(howto) Holen Gesicht von Eingang zu Frontkamera als UIImage

Like this:

let input = try AVCaptureDeviceInput(device: captureDevice) 
captureSession = AVCaptureSession() 
captureSession!.addInput(input) 

output = AVCaptureMetadataOutput() 
captureSession?.addOutput(output) 

output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue()) 
output.metadataObjectTypes = [AVMetadataObjectTypeFace] 


videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 
videoPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill 
videoPreviewLayer?.frame = view.layer.bounds 
view.layer.addSublayer(videoPreviewLayer!) 

captureSession?.startRunning() 

In Delegatmethode didOutputMetadataObjects Ich erhalte Gesicht, als AVMetadataFaceObject und es mit rotem Rahmen wie folgt highliting:

let metadataObj = metadataObjects[0] as! AVMetadataFaceObject 
let faceObject = videoPreviewLayer?.transformedMetadataObjectForMetadataObject(metadataObj) 
faceFrame?.frame = faceObject!.bounds 

Frage ist: Wie kann Ich bekomme Gesichter als UIImagices?

Ich habe versucht, über die 'didOutputSampleBuffer' zu tanzen, aber es überhaupt nicht aufgerufen wird: c

Antwort

1
- (UIImage *) screenshot { 

CGSize size = CGSizeMake(faceFrame.frame.size.width, faceFrame.frame.size.height); 

UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen  mainScreen].scale); 

CGRect rec = CGRectMake(faceFrame.frame.origin.x, faceFrame.frame.orogin.y, faceFrame.frame.size.width, faceFrame.frame.size.height); 
[_viewController.view drawViewHierarchyInRect:rec afterScreenUpdates:YES]; 

UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
return image; 
} 

von etwas Cue Nehmen oben

let contextImage: UIImage = <<screenshot>>! 
let cropRect: CGRect = CGRectMake(x, y, width, height) 
let imageRef: CGImageRef =  CGImageCreateWithImageInRect(contextImage.CGImage, cropRect) 
let image: UIImage = UIImage(CGImage: imageRef, scale: originalImage.scale, orientation: originalImage.imageOrientation)! 
+0

viel mit Ihrem Vorschlag versucht. 'screenshot' gibt ein leeres Bild zurück, so wie ich es verstanden habe, der nächste Teil des Codes - woher kam 'originalImage'? Hier ist der Code, den ich habe: http://pastebin.com/M2CFPzDj (Gesicht = screenshot()). Es hat immer unterschiedliche Größe und Länge, aber als Bild ist es leer: c – SwiftStudier

+0

und welche Koordinaten und Größe muss in cropRect sein? Herkunft.x/y und size.width/height von FaceFrameView? – SwiftStudier

+0

stürzt ab auf lassen Sie ImageRef = CGImageCreateWithImageInRect (contextImage.CGImage, cropRect)! – SwiftStudier

0

ich werde vorschlagen Verwenden Sie die Klasse UIImagePickerController, um Ihre benutzerdefinierte Kamera zur Auswahl mehrerer Bilder für die Gesichtserkennung zu implementieren. Bitte überprüfen Sie Apples Beispielcode PhotoPicker.

Um einige zu verwenden UIImagePickerController für den Start der Kamera als sourceType. Und behandeln Sie ihren Delegaten , um Bild zu erfassen + Sie können auch überprüfen, takePicture Funktion, wenn es hilft

3

Ich tat das gleiche mit didOutputSampleBuffer und Objective-C. Es sieht aus wie:

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { 
    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
    CFDictionaryRef attachments = CMCopyDictionaryOfAttachments(kCFAllocatorDefault, sampleBuffer, kCMAttachmentMode_ShouldPropagate); 
    CIImage *ciImage = [[CIImage alloc] initWithCVPixelBuffer:pixelBuffer options:(__bridge NSDictionary *)attachments]; 
    if (attachments) 
    CFRelease(attachments); 

    NSNumber *orientation = (__bridge NSNumber *)(CMGetAttachment(imageDataSampleBuffer, kCGImagePropertyOrientation, NULL)); 
    NSArray *features = [[CIDetector detectorOfType:CIDetectorTypeFace context:nil options:@{ CIDetectorAccuracy: CIDetectorAccuracyHigh }] featuresInImage:ciImage options:@{ CIDetectorImageOrientation: orientation }]; 
    if (features.count == 1) { 
    CIFaceFeature *faceFeature = [features firstObject]; 
    CGRect faceRect = faceFeature.bounds; 

    CGImageRef tempImage = [[CIContext contextWithOptions:nil] createCGImage:ciImage fromRect:ciImage.extent]; 
    UIImage *image = [UIImage imageWithCGImage:tempImage scale:1.0 orientation:orientation.intValue]; 
    UIImage *face = [image extractFace:faceRect]; 
    } 
} 

wo extractFace ist eine Erweiterung von UIImage:

- (UIImage *)extractFace:(CGRect)rect { 
    rect = CGRectMake(rect.origin.x * self.scale, 
        rect.origin.y * self.scale, 
        rect.size.width * self.scale, 
        rect.size.height * self.scale); 
    CGImageRef imageRef = CGImageCreateWithImageInRect(self.CGImage, rect); 
    UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation]; 
    CGImageRelease(imageRef); 
    return result; 
} 

Erstellen von Video-Ausgang:

AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init]; 
videoOutput.videoSettings = @{ (id)kCVPixelBufferPixelFormatTypeKey: [NSNumber numberWithInt:kCMPixelFormat_32BGRA] }; 
videoOutput.alwaysDiscardsLateVideoFrames = YES; 
self.videoOutputQueue = dispatch_queue_create("OutputQueue", DISPATCH_QUEUE_SERIAL); 
[videoOutput setSampleBufferDelegate:self queue:self.videoOutputQueue]; 
[self.session addOutput:videoOutput]; 
+0

, aber wie didOutputSampleBuffer von didOutputMetadataObjects Methode aufrufen? – Arti

+0

Sie müssen nicht. Wenn die Videoausgabe wie oben beschrieben zu der Sitzung hinzugefügt wird, wird nur didOutputSampleBuffer automatisch in der erstellten Warteschlange aufgerufen. – azzie