CIDetectorTracking 正确使用方法

时间:2022-08-31 08:39:16

苹果最近添加到新的常量 CIDetector 类称为 CIDetectorTracking 的出现,以便能够在视频帧之间跟踪的面孔。如果我能设法弄清楚它是如何工作,这会是非常有益的我...

我试过将此项添加到选项字典使用我能想到的每个对象是远程有关包括我的 AVCaptureStillImageOutput 实例,我的工作,UIImage 的探测器 1,等等。

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

但不管什么我尝试传递的参数,它要么崩溃 (很明显我猜它在这里) 或调试器输出:

指定了未知的 CIDetectorTracking。忽略。

通常情况下,我不会猜测在此,但关于这一主题的资源是几乎不存在。苹果公司的类引用国家:

密钥被用来启用或禁用跟踪的探测器的脸。当你想要跨帧在视频跟踪的面孔时,请使用此选项。

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

里面的评论 CIDetector.h :

/ * 应使用用于指定跟踪该功能的选项字典中的键。*/

如果还不够糟糕,在谷歌上搜索提供 7 结果 (8 时他们发现这篇文章) 所有这些都是苹果类引用,API 差异,询问如何实现这一目标在 iOS 5,第三方的或副本前的等职位。

这样说,任何提示或正确使用方法的提示 CIDetectorTracking 将不胜感激 !

解决方法 1:

你说得对,这把钥匙没有很好记录。在旁边也是 API 文档中没有解释:

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

指定了未知的 CIDetectorTracking。忽略。

当您将值设置为 @(YES) 你应该得到跟踪 id 与检测到的面部特征。


然而当你想要检测的面孔中从相机捕获的内容,您应该更喜欢在 AVFoundation 中的人脸检测的 API。它有内置的脸跟踪和人脸检测在后台发生的 gpu 和将会远远超过 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];