Отслеживание глаз с помощью Vision Framework

Как вы можете использовать новую платформу Vision в iOS 11, чтобы отслеживать глаза в видео, когда голова или камера движутся? (используя фронтальную камеру).

я обнаружил VNDetectFaceLandmarksRequest чтобы быть очень медленным на моем iPad - запросы ориентиров выполняются примерно раз в 1-2 секунды. Я чувствую, что делаю что-то не так, но на сайте Apple не так много документации.

Я уже смотрел видео WWDC 2017 на Vision:

https://developer.apple.com/videos/play/wwdc2017/506/

а также прочитайте это руководство:

https://github.com/jeffreybergier/Blog-Getting-Started-with-Vision

Мой код выглядит примерно так прямо сейчас (извините, это Objective-C):

// Capture session setup

- (BOOL)setUpCaptureSession {
    AVCaptureDevice *captureDevice = [AVCaptureDevice
                                      defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera
                                      mediaType:AVMediaTypeVideo
                                      position:AVCaptureDevicePositionFront];
    NSError *error;
    AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
    if (error != nil) {
        NSLog(@"Failed to initialize video input: %@", error);
        return NO;
    }

    self.captureOutputQueue = dispatch_queue_create("CaptureOutputQueue",
                                                    DISPATCH_QUEUE_SERIAL);

    AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc] init];
    captureOutput.alwaysDiscardsLateVideoFrames = YES;
    [captureOutput setSampleBufferDelegate:self queue:self.captureOutputQueue];

    self.captureSession = [[AVCaptureSession alloc] init];
    self.captureSession.sessionPreset = AVCaptureSessionPreset1280x720;
    [self.captureSession addInput:captureInput];
    [self.captureSession addOutput:captureOutput];

    return YES;
}

// Capture output delegate:

- (void)captureOutput:(AVCaptureOutput *)output
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
       fromConnection:(AVCaptureConnection *)connection {
    if (!self.detectionStarted) {
        return;
    }

    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    if (pixelBuffer == nil) {
        return;
    }

    NSMutableDictionary<VNImageOption, id> *requestOptions = [NSMutableDictionary dictionary];
    CFTypeRef cameraIntrinsicData = CMGetAttachment(sampleBuffer,
                                                    kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix,
                                                    nil);
    requestOptions[VNImageOptionCameraIntrinsics] = (__bridge id)(cameraIntrinsicData);

    // TODO: Detect device orientation
    static const CGImagePropertyOrientation orientation = kCGImagePropertyOrientationRight;

    VNDetectFaceLandmarksRequest *landmarksRequest =
        [[VNDetectFaceLandmarksRequest alloc] initWithCompletionHandler:^(VNRequest *request, NSError *error) {
            if (error != nil) {
                NSLog(@"Error while detecting face landmarks: %@", error);
            } else {
                dispatch_async(dispatch_get_main_queue(), ^{
                    // Draw eyes in two corresponding CAShapeLayers
                });
            }
        }];


    VNImageRequestHandler *requestHandler = [[VNImageRequestHandler alloc] initWithCVPixelBuffer:pixelBuffer
                                                                                     orientation:orientation
                                                                                         options:requestOptions];
    NSError *error;
    if (![requestHandler performRequests:@[landmarksRequest] error:&error]) {
        NSLog(@"Error performing landmarks request: %@", error);
        return;
    }
}

Это правильно называть -performRequests:.. в той же очереди, что и видеовыход? Судя по моим экспериментам, этот метод, похоже, вызывает синхронный обработчик завершения запроса. Разве я не должен вызывать этот метод на каждом кадре?

Для ускорения вещей я также пытался использовать VNTrackObjectRequest отслеживать каждый глаз отдельно после того, как в видео были обнаружены ориентиры (путем создания ограничивающего прямоугольника из точек региона ориентиров), но это не сработало очень хорошо (все еще пытаясь выяснить это).

Какова лучшая стратегия для слежения за видео? Должен ли я отслеживать прямоугольник лица, а затем выполнить запрос наземных ориентиров внутри его области (будет ли он быстрее)?

0 ответов

Другие вопросы по тегам