【问题标题】:CIDetector give wrong position on facial featuresCIDetector 在面部特征上给出错误的位置
【发布时间】:2013-05-09 02:26:39
【问题描述】:

现在我知道坐标系搞砸了。我试过颠倒视图和imageView,什么都没有。然后我尝试反转特征上的坐标,但我仍然遇到同样的问题。我知道它会检测到人脸、眼睛和嘴巴,但是当我尝试从示例代码中放置覆盖框时,它们不在位置上(准确地说,它们在屏幕外的右侧)。我很难理解为什么会这样。

我会发布一些代码,因为我知道你们中的一些人喜欢这种特殊性:

-(void)faceDetector
{
    // Load the picture for face detection
//    UIImageView* image = [[UIImageView alloc] initWithImage:mainImage];
    [self.imageView setImage:mainImage];
    [self.imageView setUserInteractionEnabled:YES];

    // Draw the face detection image
//    [self.view addSubview:self.imageView];

    // Execute the method used to markFaces in background
//    [self performSelectorInBackground:@selector(markFaces:) withObject:self.imageView];

    // flip image on y-axis to match coordinate system used by core image
//    [self.imageView setTransform:CGAffineTransformMakeScale(1, -1)];

    // flip the entire window to make everything right side up
//    [self.view setTransform:CGAffineTransformMakeScale(1, -1)];

//    [toolbar setTransform:CGAffineTransformMakeScale(1, -1)];
    [toolbar setFrame:CGRectMake(0, 0, 320, 44)];

    // Execute the method used to markFaces in background
    [self performSelectorInBackground:@selector(markFaces:) withObject:_imageView];
//    [self markFaces:self.imageView];
}

-(void)markFaces:(UIImageView *)facePicture
{
    // draw a CI image with the previously loaded face detection picture
    CIImage* image = [CIImage imageWithCGImage:facePicture.image.CGImage];

    // create a face detector - since speed is not an issue we'll use a high accuracy
    // detector
    CIDetector* detector = [CIDetector detectorOfType:CIDetectorTypeFace
                                              context:nil options:[NSDictionary dictionaryWithObject:CIDetectorAccuracyHigh forKey:CIDetectorAccuracy]];

//    CGAffineTransform transform = CGAffineTransformMakeScale(1, -1);
    CGAffineTransform transform = CGAffineTransformMakeScale(self.view.frame.size.width/mainImage.size.width, -self.view.frame.size.height/mainImage.size.height);
    transform = CGAffineTransformTranslate(transform, 0, -self.imageView.bounds.size.height);

    // create an array containing all the detected faces from the detector
    NSDictionary* imageOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:6] forKey:CIDetectorImageOrientation];
    NSArray* features = [detector featuresInImage:image options:imageOptions];
//    NSArray* features = [detector featuresInImage:image];

    NSLog(@"Marking Faces: Count: %d", [features count]);

    // we'll iterate through every detected face.  CIFaceFeature provides us
    // with the width for the entire face, and the coordinates of each eye
    // and the mouth if detected.  Also provided are BOOL's for the eye's and
    // mouth so we can check if they already exist.
    for(CIFaceFeature* faceFeature in features)
    {


        // create a UIView using the bounds of the face
//        UIView* faceView = [[UIView alloc] initWithFrame:faceFeature.bounds];
        CGRect faceRect = CGRectApplyAffineTransform(faceFeature.bounds, transform);

        // get the width of the face
//        CGFloat faceWidth = faceFeature.bounds.size.width;
        CGFloat faceWidth = faceRect.size.width;

        // create a UIView using the bounds of the face
        UIView *faceView = [[UIView alloc] initWithFrame:faceRect];

        // add a border around the newly created UIView
        faceView.layer.borderWidth = 1;
        faceView.layer.borderColor = [[UIColor redColor] CGColor];

        // add the new view to create a box around the face
        [self.imageView addSubview:faceView];
        NSLog(@"Face -> X: %f, Y: %f, W: %f, H: %f",faceRect.origin.x, faceRect.origin.y, faceRect.size.width, faceRect.size.height);

        if(faceFeature.hasLeftEyePosition)
        {

            // create a UIView with a size based on the width of the face
            CGPoint leftEye = CGPointApplyAffineTransform(faceFeature.leftEyePosition, transform);
            UIView* leftEyeView = [[UIView alloc] initWithFrame:CGRectMake(leftEye.x-faceWidth*0.15, leftEye.y-faceWidth*0.15, faceWidth*0.3, faceWidth*0.3)];
            // change the background color of the eye view
            [leftEyeView setBackgroundColor:[[UIColor blueColor] colorWithAlphaComponent:0.3]];
            // set the position of the leftEyeView based on the face
            [leftEyeView setCenter:leftEye];
            // round the corners
            leftEyeView.layer.cornerRadius = faceWidth*0.15;
            // add the view to the window
            [self.imageView addSubview:leftEyeView];
            NSLog(@"Has Left Eye -> X: %f, Y: %f",leftEye.x, leftEye.y);
        }

        if(faceFeature.hasRightEyePosition)
        {

            // create a UIView with a size based on the width of the face
            CGPoint rightEye = CGPointApplyAffineTransform(faceFeature.rightEyePosition, transform);
            UIView* leftEye = [[UIView alloc] initWithFrame:CGRectMake(rightEye.x-faceWidth*0.15, rightEye.y-faceWidth*0.15, faceWidth*0.3, faceWidth*0.3)];
            // change the background color of the eye view
            [leftEye setBackgroundColor:[[UIColor yellowColor] colorWithAlphaComponent:0.3]];
            // set the position of the rightEyeView based on the face
            [leftEye setCenter:rightEye];
            // round the corners
            leftEye.layer.cornerRadius = faceWidth*0.15;
            // add the new view to the window
            [self.imageView addSubview:leftEye];
            NSLog(@"Has Right Eye -> X: %f, Y: %f", rightEye.x, rightEye.y);
        }

//        if(faceFeature.hasMouthPosition)
//        {
//            // create a UIView with a size based on the width of the face
//            UIView* mouth = [[UIView alloc] initWithFrame:CGRectMake(faceFeature.mouthPosition.x-faceWidth*0.2, faceFeature.mouthPosition.y-faceWidth*0.2, faceWidth*0.4, faceWidth*0.4)];
//            // change the background color for the mouth to green
//            [mouth setBackgroundColor:[[UIColor greenColor] colorWithAlphaComponent:0.3]];
//            // set the position of the mouthView based on the face
//            [mouth setCenter:faceFeature.mouthPosition];
//            // round the corners
//            mouth.layer.cornerRadius = faceWidth*0.2;
//            // add the new view to the window
//            [self.imageView addSubview:mouth];
//        }
    }
}

我知道代码段有点长,但这就是它的主要内容。他们唯一与此相关的另一件事是我有一个 UIImagePickerController 让用户可以选择选择现有图像或拍摄新图像。然后将图像设置到屏幕的 UIImageView 中,与各种框和圆圈一起显示,但没有运气显示它们:/

任何帮助将不胜感激。谢谢~

更新:

我添加了一张它现在所做的照片,所以你们可以有一个想法,我应用了新的缩放,它工作得更好一些,但远不及我想要的。

【问题讨论】:

  • 顺便说一句漂​​亮的图片:)
  • 你找到解决办法了吗?

标签: ios face-recognition


【解决方案1】:

除非您的图像视图与您的图像具有完全相同的大小,否则您的变换缺少比例。开始

   CGAffineTransformMakeScale( viewWidth / imageWidth, - viewHeight / imageHeight )

其中viewWidthviewHeight 是视图的大小,imageWidthimageHeight 是图像的大小。

【讨论】:

  • 效果更好,现在它不再向右(屏幕外),而是在实际面部正上方绘制面部框。这让我很困惑,因为我只是采用了一个有效的示例代码并进行了更改以允许在旧图像或新图像上进行选择。
  • 同样通过视图,我不确定您是指 UIImageView 还是常规 UIView,但在比较原始图像(我的代码中的 mainImage)和控制器的视图时效果更好
  • 按照您的建议,这些是我的转换值:Transform -> A: 0.291667, B: 0.000000, C: 0.000000, D: -0.378125, Tx: 81.666664, Ty: 183.012512
【解决方案2】:

只需使用 Apple 的 SquareCam 应用中的代码即可。它可以在前后摄像头的任何方向上正确对齐正方形。沿 faceRect 插值以获得正确的眼睛和嘴巴位置。注意:您必须将 x 位置与面部特征的 y 位置交换。不知道为什么你必须进行交换,但这会给你正确的位置。

【讨论】:

    【解决方案3】:

    所以在玩过之后,在@Sven 的帮助下,我想通了。

    CGAffineTransform transform = CGAffineTransformMakeScale(self.imageView.bounds.size.width/mainImage.size.width, -self.imageView.bounds.size.height/mainImage.size.height);
        transform = CGAffineTransformRotate(transform, degreesToRadians(270));
    

    我不得不调整要按图像大小和图像视图大小缩放的变换,然后由于某种原因我不得不旋转它,但它现在可以正常工作了

    【讨论】:

      猜你喜欢
      • 2013-08-22
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      • 2016-09-21
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多