正确使用CIDetectorTracking

苹果最近给CIDetector类添加了一个新的常量,名为CIDetectorTracking ,它似乎能够跟踪video中帧之间的面孔。 如果我能弄清楚它是如何工作的话,这将对我非常有利。

我试过把这个键添加到检测器选项字典使用每个对象,我可以认为是远程相关的,包括,我的AVCaptureStillImageOutput实例,我工作的UIImage,YES,1等

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

但是无论我尝试传递什么参数,它要么崩溃(显然我在这里猜测)或debugging器的输出:

未知的CIDetectorTracking指定。 忽略。

通常情况下,我不会猜测,但这个话题的资源几乎不存在。 苹果的类参考指出:

用于启用或禁用探测器的人脸跟踪的键。 当您想要跟踪video中的帧时,使用此选项。

除了可用性是iOS 6+和OS X 10.8+就是这样。

CIDetector.h里面的CIDetector.h

/ *用于指定特征跟踪的选项字典中的键应该被使用。 * /

如果这还不够糟糕的话, Googlesearch提供了7个结果(当他们发现这个post的时候是8个),所有这些结果都是苹果类引用,API差异,一个SOpost,询问如何在iOS 5中实现这一点,或者第三方副本的前者。

所有这一切,正确的使用CIDetectorTracking任何提示或技巧将不胜感激!

你是对的,这个关键没有很好的logging。 在API文档旁边也没有解释:

  • CIDetector.h头文件
  • 核心图像编程指南
  • WWDC 2012会议“520 – 相机捕获的新function”
  • 此会话的示例代码( StacheCam 2

我为CIDetectorTracking尝试了不同的值,唯一可接受的值似乎是@(YES)@(NO) 。 与其他值在控制台中打印此消息:

未知的CIDetectorTracking指定。 忽略。

当您将值设置为@(YES)您应该使用检测到的脸部特征来跟踪ID。


但是,如果要检测从相机捕获的内容中的脸部,您应该首选AVFoundation中的脸部检测API。 它具有内置的人脸跟踪function,并且在GPU上的背景中发生人脸检测,并且将比CoreImage人脸检测快得多。它需要iOS 6和至less一个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的示例代码 。