Ответ 1
Вы правы, этот ключ не очень хорошо документирован. Помимо документов API, это также не объясняется в:
- заголовочный файл CIDetector.h
- Руководство по программированию основных изображений
- сессия 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.