Core Image 人脸检测

Core Image可以对图像进行分析,并找到图片中人脸的位置。Core Image检测出人脸后,可以提供面部特性,比如眼睛和嘴的位置。它还可以跟踪视频中人脸的位置。

image

下面我们看看如何实现人脸检测。

UIImage *baby = [UIImage imageNamed:@"1.jpg"];
CGFloat scale = 320.0/baby.size.width;
CIImage *myimage = [CIImage imageWithCGImage:baby.CGImage];
CIContext *context = [CIContext contextWithOptions:nil];
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace context:context options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
NSArray *features = [detector featuresInImage:myimage];
for (CIFaceFeature *faceFeature in features){
    CGRect bounds = faceFeature.bounds;
    bounds.origin.x *= scale;
    bounds.origin.y *= scale;
    bounds.size.width *= scale;
    bounds.size.height *= scale;
    UIView *faceView = [[UIView alloc] initWithFrame:bounds];
    faceView.backgroundColor = [UIColor clearColor];
    faceView.layer.borderWidth = 1;
    faceView.layer.borderColor = [UIColor redColor].CGColor;
    [self.imageView addSubview:faceView];
}

image

此外,我们还可以拿到眼睛跟嘴巴的位置

if (faceFeature.hasLeftEyePosition)
    NSLog(@"Left eye %@",NSStringFromCGPoint(faceFeature.leftEyePosition));
if (faceFeature.hasRightEyePosition)
    NSLog(@"Right eye %@",NSStringFromCGPoint(faceFeature.rightEyePosition));
if (faceFeature.hasMouthPosition)
    NSLog(@"Mouth %@", NSStringFromCGPoint(faceFeature.mouthPosition));

利用Core Image 进行脸部打码

image 要实现这个效果,分下面几步。

像素图片

UIImage *baby = [UIImage imageNamed:@"1.jpg"];
CIImage *myimage = [CIImage imageWithCGImage:baby.CGImage];
CGFloat scale = MAX(baby.size.width, baby.size.height)/60;
CIImage *pixlImage =[CIFilter filterWithName:@"CIPixellate" keysAndValues:kCIInputImageKey,myimage,kCIInputScaleKey,@(scale),nil].outputImage;

脸部遮罩图片

CIImage *maskImage = nil;
CIContext *context = [CIContext contextWithOptions:nil];
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace context:context options:@{CIDetectorAccuracy:CIDetectorAccuracyHigh}];
NSArray *features = [detector featuresInImage:myimage];

for (CIFaceFeature *faceFeature in features){
    CGFloat centerX = faceFeature.bounds.origin.x + faceFeature.bounds.size.width / 2.0;
    CGFloat centerY = faceFeature.bounds.origin.y + faceFeature.bounds.size.height / 2.0;
    CGFloat radius = MIN(faceFeature.bounds.size.width, faceFeature.bounds.size.height) / 1.5;
    CIFilter *radialGradient = [CIFilter filterWithName:@"CIRadialGradient" keysAndValues:@"inputRadius0", @(radius),@"inputRadius1", @(radius + 1.0f),@"inputColor0", [CIColor colorWithRed:0.0 green:1.0 blue:0.0 alpha:1.0],@"inputColor1", [CIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0],kCIInputCenterKey, [CIVector vectorWithX:centerX Y:centerY],nil];
    CIImage *circleImage = [radialGradient valueForKey:kCIOutputImageKey];
    if (nil == maskImage)
        maskImage = circleImage;
    else
        maskImage = [[CIFilter filterWithName:@"CISourceOverCompositing" keysAndValues:kCIInputImageKey, circleImage,kCIInputBackgroundImageKey, maskImage,nil] valueForKey:kCIOutputImageKey];
    }
}

合成最终的图片

CIImage *resultImage =[CIFilter filterWithName:@"CIBlendWithMask" keysAndValues:kCIInputImageKey,pixlImage,@"inputMaskImage",maskImage,@"inputBackgroundImage",myimage,nil].outputImage;

image