Правильное использование 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 это также не объясняется в:
- заголовочный файл CIDetector.h
- Руководство по программированию Core Image
- сессия WWDC 2012 "520 - что нового в захвате камеры"
- пример кода для этого сеанса (StacheCam 2)
Я пробовал разные значения для 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.