我想在iOS中进行面部特征检测。我已经能够使用OpenCV检测到一张脸,但现在想要检测所有的功能'在这张脸上,我可以在以后对它们进行识别。
我找到了一个名为flandmark的库,但它并不喜欢它有一个我可以在iOS上使用的框架。
有没有人知道如何做到这一点?
由于 Nikhil Mehta
答案 0 :(得分:3)
我建议你尽量保持简单,在这种情况下,如果足够的话,只需使用原生iOS的可能性。
主要类是CIDetector
框架的 CoreImage
。
以下是主要方法
// create CIDetector object with CIDetectorTypeFace type
CIDetector* detector = [CIDetector detectorOfType:CIDetectorTypeFace
context:nil
options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
// give it CIImage and receive an array with CIFaceFeature objects
NSArray *features = [detector featuresInImage:newImage];
根据 Apple 文档 CIFaceFeature
包含下一个属性
@interface CIFaceFeature : CIFeature
@property (readonly, assign) CGRect bounds;
@property (readonly, assign) BOOL hasLeftEyePosition;
@property (readonly, assign) CGPoint leftEyePosition;
@property (readonly, assign) BOOL hasRightEyePosition;
@property (readonly, assign) CGPoint rightEyePosition;
@property (readonly, assign) BOOL hasMouthPosition;
@property (readonly, assign) CGPoint mouthPosition;
@property (readonly, assign) BOOL hasTrackingID;
@property (readonly, assign) int trackingID;
@property (readonly, assign) BOOL hasTrackingFrameCount;
@property (readonly, assign) int trackingFrameCount;
@property (readonly, assign) BOOL hasFaceAngle;
@property (readonly, assign) float faceAngle;
@property (readonly, assign) BOOL hasSmile;
@property (readonly, assign) BOOL leftEyeClosed;
@property (readonly, assign) BOOL rightEyeClosed;
@end
还有一个很棒的Raywenderlich article关于GCD,它实现了脸部特征检测,这里是它的Final project。它找到了人们的眼睛位置,并用一些有趣的眼睛覆盖它。
最后是项目中的部分代码和截图。
- (UIImage *)faceOverlayImageFromImage:(UIImage *)image
{
CIDetector* detector = [CIDetector detectorOfType:CIDetectorTypeFace
context:nil
options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
// Get features from the image
CIImage* newImage = [CIImage imageWithCGImage:image.CGImage];
NSArray *features = [detector featuresInImage:newImage];
UIGraphicsBeginImageContext(image.size);
CGRect imageRect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height);
//Draws this in the upper left coordinate system
[image drawInRect:imageRect blendMode:kCGBlendModeNormal alpha:1.0f];
CGContextRef context = UIGraphicsGetCurrentContext();
for (CIFaceFeature *faceFeature in features) {
CGRect faceRect = [faceFeature bounds];
CGContextSaveGState(context);
// CI and CG work in different coordinate systems, we should translate to
// the correct one so we don't get mixed up when calculating the face position.
CGContextTranslateCTM(context, 0.0, imageRect.size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
if ([faceFeature hasLeftEyePosition]) {
CGPoint leftEyePosition = [faceFeature leftEyePosition];
CGFloat eyeWidth = faceRect.size.width / kFaceBoundsToEyeScaleFactor;
CGFloat eyeHeight = faceRect.size.height / kFaceBoundsToEyeScaleFactor;
CGRect eyeRect = CGRectMake(leftEyePosition.x - eyeWidth/2.0f,
leftEyePosition.y - eyeHeight/2.0f,
eyeWidth,
eyeHeight);
[self drawEyeBallForFrame:eyeRect];
}
if ([faceFeature hasRightEyePosition]) {
CGPoint leftEyePosition = [faceFeature rightEyePosition];
CGFloat eyeWidth = faceRect.size.width / kFaceBoundsToEyeScaleFactor;
CGFloat eyeHeight = faceRect.size.height / kFaceBoundsToEyeScaleFactor;
CGRect eyeRect = CGRectMake(leftEyePosition.x - eyeWidth / 2.0f,
leftEyePosition.y - eyeHeight / 2.0f,
eyeWidth,
eyeHeight);
[self drawEyeBallForFrame:eyeRect];
}
CGContextRestoreGState(context);
}
UIImage *overlayImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return overlayImage;
}
- (void)drawEyeBallForFrame:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddEllipseInRect(context, rect);
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextFillPath(context);
CGFloat x, y, eyeSizeWidth, eyeSizeHeight;
eyeSizeWidth = rect.size.width * kRetinaToEyeScaleFactor;
eyeSizeHeight = rect.size.height * kRetinaToEyeScaleFactor;
x = arc4random_uniform((rect.size.width - eyeSizeWidth));
y = arc4random_uniform((rect.size.height - eyeSizeHeight));
x += rect.origin.x;
y += rect.origin.y;
CGFloat eyeSize = MIN(eyeSizeWidth, eyeSizeHeight);
CGRect eyeBallRect = CGRectMake(x, y, eyeSize, eyeSize);
CGContextAddEllipseInRect(context, eyeBallRect);
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
CGContextFillPath(context);
}
希望它会有所帮助