Правильное использование CIDetectorTracking

Apple недавно добавила новую константу в CIDetector класс называется CIDetectorTracking который, кажется, может отслеживать лица между кадрами в видео. Это было бы очень полезно для меня, если бы мне удалось выяснить, как это работает..

Я попытался добавить этот ключ в словарь опций детекторов, используя каждый объект, который, как мне кажется, имеет удаленное отношение, включая мой экземпляр AVCaptureStillImageOutput, UIImage, над которым я работаю, ДА, 1 и т. Д.

NSDictionary *detectorOptions = [[NSDictionary alloc] initWithObjectsAndKeys:CIDetectorAccuracyHigh, CIDetectorAccuracy,myAVCaptureStillImageOutput,CIDetectorTracking, nil];

Но независимо от того, какой параметр я пытаюсь передать, он либо аварийно завершает работу (очевидно, я предполагаю это здесь), либо выводит отладчик:

Указан неизвестный CIDetectorTracking. Не обращая внимания.

Обычно я бы не стал догадываться об этом, но ресурсов по этой теме практически не существует. Ссылка класса Apple утверждает:

Ключ, используемый для включения или отключения отслеживания лица для детектора. Используйте эту опцию, если вы хотите отслеживать лица между кадрами в видео.

За исключением доступности iOS 6+ и OS X 10.8+, все.

Комментарии внутри CIDetector.h:

/ * Ключ в словаре опций, используемый для указания, что следует использовать отслеживание функций. */

Если это не так уж и плохо, поиск в Google выдает 7 результатов (8, когда они находят эту запись), все из которых являются либо ссылками на классы Apple, API-ссылками, публикацией SO с вопросом, как добиться этого в iOS 5, либо сторонними копиями. из первых.

Все это, как говорится, любые намеки или советы для правильного использования CIDetectorTracking будет принята с благодарностью!

1 ответ

Решение

Вы правы, этот ключ не очень хорошо задокументирован. Кроме документации по API это также не объясняется в:

Я пробовал разные значения для CIDetectorTracking и единственные принятые значения кажутся @(YES) а также @(NO), С другими значениями он печатает это сообщение в консоли:

Указан неизвестный CIDetectorTracking. Не обращая внимания.

Когда вы устанавливаете значение в @(YES) Вы должны получить идентификаторы отслеживания с обнаруженными чертами лица.


Однако, если вы хотите обнаружить лица в контенте, снятом с камеры, вы должны предпочесть API распознавания лиц в AVFoundation. Он имеет встроенное отслеживание лица, и распознавание лица происходит в фоновом режиме на графическом процессоре и будет намного быстрее, чем распознавание лица CoreImage. Требуется iOS 6 и, по крайней мере, iPhone 4S или iPad 2.

Лицо отправляется как объекты метаданных (AVMetadataFaceObject) к AVCaptureMetadataOutputObjectsDelegate,

Вы можете использовать этот код (взятый из StacheCam 2 и слайдов сеанса WWDC, упомянутых выше), чтобы настроить распознавание лиц и получить объекты метаданных лица:

- (void) setupAVFoundationFaceDetection
{       
    self.metadataOutput = [AVCaptureMetadataOutput new];
    if ( ! [self.session canAddOutput:self.metadataOutput] ) {
        return;
    }

    // Metadata processing will be fast, and mostly updating UI which should be done on the main thread
    // So just use the main dispatch queue instead of creating a separate one
    // (compare this to the expensive CoreImage face detection, done on a separate queue)
    [self.metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    [self.session addOutput:self.metadataOutput];

    if ( ! [self.metadataOutput.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeFace] ) {
        // face detection isn't supported (via AV Foundation), fall back to CoreImage
        return;
    }

    // We only want faces, if we don't set this we would detect everything available
    // (some objects may be expensive to detect, so best form is to select only what you need)
    self.metadataOutput.metadataObjectTypes = @[ AVMetadataObjectTypeFace ];

}

// AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput
         didOutputMetadataObjects:(NSArray *)metadataObjects
         fromConnection:(AVCaptureConnection *)c
{
   for ( AVMetadataObject *object in metadataObjects ) {
     if ( [[object type] isEqual:AVMetadataObjectTypeFace] ) {
      AVMetadataFaceObject* face = (AVMetadataFaceObject*)object;
      CMTime timestamp = [face time];
      CGRect faceRectangle = [face bounds];
      NSInteger faceID = [face faceID];
      CGFloat rollAngle = [face rollAngle];
      CGFloat yawAngle = [face yawAngle];
      NSNumber* faceID = @(face.faceID); // use this id for tracking
      // Do interesting things with this face
     }
}

Если вы хотите отобразить рамки лица в слое предварительного просмотра, вам нужно получить преобразованный объект лица:

AVMetadataFaceObject * adjusted = (AVMetadataFaceObject*)[self.previewLayer transformedMetadataObjectForMetadataObject:face];

Для получения дополнительной информации ознакомьтесь с примером кода из WWDC 2012.

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