2016-04-21 14 views
5

Я решаю задачу сканирования фронтального входа камеры для лиц, обнаруживая их и получая их как UIImage -объекты. Я использую AVFoundation для сканирования и обнаружения лиц.(howto) Получите лицо от входных данных до передней камеры как UIImage

Как это:

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() 

В методе делегата didOutputMetadataObjects я получаю лицо, как AVMetadataFaceObject и highliting его с красной рамкой, как это:

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

Вопрос: Как может Я получаю лица как UIImages?

Я пытался танцевать над «didOutputSampleBuffer», но это не называется вообще: с

ответ

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

Возьмите некоторый намек сверху

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

пробовал много с вашим предложением. «скриншот» возвращает пустое изображение, как я понял, следующую часть кода - откуда взялось «originalImage»? вот код, который у меня есть: http://pastebin.com/M2CFPzDj (face = screenshot()). Он всегда имеет разные размеры и длину, но как изображение пуст: c – SwiftStudier

+0

и какие координаты и размер должны быть в cropRect? изначальный.x/y и размер.width/высота из faceFrameView? – SwiftStudier

+0

аварии на let imageRef = CGImageCreateWithImageInRect (contextImage.CGImage, cropRect)! – SwiftStudier

0

Я предлагаю используйте класс UIImagePickerController для реализации вашей пользовательской камеры для выбора нескольких изображений для распознавания лиц. Пожалуйста, проверьте пример кода Apple PhotoPicker.

Для некоторых используйте UIImagePickerController для запуска камеры в качестве источника. И обработайте его делегата imagePickerController:didFinishPickingMediaWithInfo: для захвата изображения + вы также можете проверить takePicture, если это помогает

3

Я сделал то же самое, используя didOutputSampleBuffer и Objective-C. Это выглядит следующим образом:

- (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]; 
    } 
} 

где extractFace является продолжением 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; 
} 

Создание видео выход:

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

, но как позвонить didOutputSampleBuffer из метода didOutputMetadataObjects? – Arti

+0

Вам не обязательно. Если в сеанс добавлен видеовыход, как я описал выше, в созданной очереди будет автоматически вызываться только командаOutputSampleBuffer. – azzie