blob: 790e12b37ac8a08e0594d1510ae41f15be6c2bfd [file] [log] [blame]
#import "FirebaseMlVisionPlugin.h"
@implementation FaceDetector
static FIRVisionFaceDetector *faceDetector;
+ (void)handleDetection:(FIRVisionImage *)image
options:(NSDictionary *)options
result:(FlutterResult)result {
FIRVision *vision = [FIRVision vision];
faceDetector = [vision faceDetectorWithOptions:[FaceDetector parseOptions:options]];
[faceDetector
processImage:image
completion:^(NSArray<FIRVisionFace *> *_Nullable faces, NSError *_Nullable error) {
if (error) {
[FLTFirebaseMlVisionPlugin handleError:error result:result];
return;
} else if (!faces) {
result(@[]);
return;
}
NSMutableArray *faceData = [NSMutableArray array];
for (FIRVisionFace *face in faces) {
id smileProb = face.hasSmilingProbability ? @(face.smilingProbability) : [NSNull null];
id leftProb =
face.hasLeftEyeOpenProbability ? @(face.leftEyeOpenProbability) : [NSNull null];
id rightProb =
face.hasRightEyeOpenProbability ? @(face.rightEyeOpenProbability) : [NSNull null];
NSDictionary *data = @{
@"left" : @(face.frame.origin.x),
@"top" : @(face.frame.origin.y),
@"width" : @(face.frame.size.width),
@"height" : @(face.frame.size.height),
@"headEulerAngleY" : face.hasHeadEulerAngleY ? @(face.headEulerAngleY)
: [NSNull null],
@"headEulerAngleZ" : face.hasHeadEulerAngleZ ? @(face.headEulerAngleZ)
: [NSNull null],
@"smilingProbability" : smileProb,
@"leftEyeOpenProbability" : leftProb,
@"rightEyeOpenProbability" : rightProb,
@"trackingId" : face.hasTrackingID ? @(face.trackingID) : [NSNull null],
@"landmarks" : @{
@"bottomMouth" : [FaceDetector getLandmarkPosition:face
landmark:FIRFaceLandmarkTypeMouthBottom],
@"leftCheek" : [FaceDetector getLandmarkPosition:face
landmark:FIRFaceLandmarkTypeLeftCheek],
@"leftEar" : [FaceDetector getLandmarkPosition:face
landmark:FIRFaceLandmarkTypeLeftEar],
@"leftEye" : [FaceDetector getLandmarkPosition:face
landmark:FIRFaceLandmarkTypeLeftEye],
@"leftMouth" : [FaceDetector getLandmarkPosition:face
landmark:FIRFaceLandmarkTypeMouthLeft],
@"noseBase" : [FaceDetector getLandmarkPosition:face
landmark:FIRFaceLandmarkTypeNoseBase],
@"rightCheek" : [FaceDetector getLandmarkPosition:face
landmark:FIRFaceLandmarkTypeRightCheek],
@"rightEar" : [FaceDetector getLandmarkPosition:face
landmark:FIRFaceLandmarkTypeRightEar],
@"rightEye" : [FaceDetector getLandmarkPosition:face
landmark:FIRFaceLandmarkTypeRightEye],
@"rightMouth" : [FaceDetector getLandmarkPosition:face
landmark:FIRFaceLandmarkTypeMouthRight],
},
};
[faceData addObject:data];
}
result(faceData);
}];
}
+ (id)getLandmarkPosition:(FIRVisionFace *)face landmark:(FIRFaceLandmarkType)landmarkType {
FIRVisionFaceLandmark *landmark = [face landmarkOfType:landmarkType];
if (landmark) {
return @[ landmark.position.x, landmark.position.y ];
}
return [NSNull null];
}
+ (FIRVisionFaceDetectorOptions *)parseOptions:(NSDictionary *)optionsData {
FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init];
NSNumber *enableClassification = optionsData[@"enableClassification"];
if (enableClassification.boolValue) {
options.classificationMode = FIRVisionFaceDetectorClassificationModeAll;
} else {
options.classificationMode = FIRVisionFaceDetectorClassificationModeNone;
}
NSNumber *enableLandmarks = optionsData[@"enableLandmarks"];
if (enableLandmarks.boolValue) {
options.landmarkMode = FIRVisionFaceDetectorLandmarkModeAll;
} else {
options.landmarkMode = FIRVisionFaceDetectorLandmarkModeNone;
}
NSNumber *enableTracking = optionsData[@"enableTracking"];
options.trackingEnabled = enableTracking.boolValue;
NSNumber *minFaceSize = optionsData[@"minFaceSize"];
options.minFaceSize = [minFaceSize doubleValue];
NSString *mode = optionsData[@"mode"];
if ([mode isEqualToString:@"accurate"]) {
options.performanceMode = FIRVisionFaceDetectorPerformanceModeAccurate;
} else if ([mode isEqualToString:@"fast"]) {
options.performanceMode = FIRVisionFaceDetectorPerformanceModeFast;
}
return options;
}
@end