1// 2// EXFaceDetectorUtils.m 3// Exponent 4// 5// Created by Stanisław Chmiela on 22.11.2017. 6// Copyright © 2017 650 Industries. All rights reserved. 7// 8 9#import <EXFaceDetector/EXFaceDetectorUtils.h> 10#import <EXFaceDetector/EXCSBufferOrientationCalculator.h> 11 12NSString *const EXGMVDataOutputWidthKey = @"Width"; 13NSString *const EXGMVDataOutputHeightKey = @"Height"; 14 15static const NSString *kModeOptionName = @"mode"; 16static const NSString *kDetectLandmarksOptionName = @"detectLandmarks"; 17static const NSString *kRunClassificationsOptionName = @"runClassifications"; 18static const NSString *kTrackingEnabled = @"tracking"; 19 20@implementation EXFaceDetectorUtils 21 22+ (NSDictionary *)constantsToExport 23{ 24 return @{ 25 @"Mode" : @{ 26 @"fast" : @(MLKFaceDetectorPerformanceModeFast), 27 @"accurate" : @(MLKFaceDetectorPerformanceModeAccurate) 28 }, 29 @"Landmarks" : @{ 30 @"all" : @(MLKFaceDetectorLandmarkModeAll), 31 @"none" : @(MLKFaceDetectorLandmarkModeNone) 32 }, 33 @"Classifications" : @{ 34 @"all" : @(MLKFaceDetectorClassificationModeAll), 35 @"none" : @(MLKFaceDetectorClassificationModeNone) 36 } 37 }; 38} 39 40+ (BOOL)didOptionsChange:(MLKFaceDetectorOptions *)options 41 comparingTo:(MLKFaceDetectorOptions *)other 42{ 43 return options.performanceMode == other.performanceMode && 44 options.classificationMode == other.classificationMode && 45 options.contourMode == other.contourMode && 46 options.minFaceSize == other.minFaceSize && 47 options.landmarkMode == other.landmarkMode && 48 options.trackingEnabled == other.trackingEnabled; 49} 50 51+ (MLKFaceDetectorOptions *)createCopy:(MLKFaceDetectorOptions *)from 52{ 53 MLKFaceDetectorOptions *options = [MLKFaceDetectorOptions new]; 54 options.performanceMode = from.performanceMode; 55 options.classificationMode = from.classificationMode; 56 options.contourMode = from.contourMode; 57 options.minFaceSize = from.minFaceSize; 58 options.landmarkMode = from.landmarkMode; 59 options.trackingEnabled = from.trackingEnabled; 60 return options; 61} 62 63 64+ (MLKFaceDetectorOptions *) mapOptions:(NSDictionary*)options { 65 return [self newOptions:[MLKFaceDetectorOptions new] withValues:options]; 66} 67 68+ (MLKFaceDetectorOptions *) newOptions:(MLKFaceDetectorOptions*)options withValues:(NSDictionary *)values 69{ 70 MLKFaceDetectorOptions *result = [self createCopy:options]; 71 if([values objectForKey:kModeOptionName]) { 72 result.performanceMode = [values[kModeOptionName] longValue]; 73 } 74 if([values objectForKey:kDetectLandmarksOptionName]) { 75 result.landmarkMode = [values[kDetectLandmarksOptionName] longValue]; 76 } 77 if([values objectForKey:kRunClassificationsOptionName]) { 78 result.classificationMode = [values[kRunClassificationsOptionName] longValue]; 79 } 80 if([values objectForKey:kTrackingEnabled]) { 81 result.trackingEnabled = [values[kTrackingEnabled] boolValue]; 82 } 83 return result; 84} 85 86+ (BOOL)areOptionsEqual:(MLKFaceDetectorOptions *)first to:(MLKFaceDetectorOptions*)second { 87 return [self didOptionsChange:first comparingTo:second]; 88} 89 90+ (NSDictionary *)defaultFaceDetectorOptions 91{ 92 return @{ 93 kModeOptionName: @(MLKFaceDetectorPerformanceModeFast), 94 kDetectLandmarksOptionName: @(MLKFaceDetectorLandmarkModeNone), 95 kRunClassificationsOptionName: @(MLKFaceDetectorClassificationModeNone) 96 }; 97} 98 99+ (int)toCGImageOrientation:(UIImageOrientation)imageOrientation 100{ 101 switch (imageOrientation) { 102 case UIImageOrientationUp: 103 return kCGImagePropertyOrientationUp; 104 case UIImageOrientationUpMirrored: 105 return kCGImagePropertyOrientationUpMirrored; 106 case UIImageOrientationDown: 107 return kCGImagePropertyOrientationDown; 108 case UIImageOrientationDownMirrored: 109 return kCGImagePropertyOrientationDownMirrored; 110 case UIImageOrientationRight: 111 return kCGImagePropertyOrientationRight; 112 case UIImageOrientationRightMirrored: 113 return kCGImagePropertyOrientationRightMirrored; 114 case UIImageOrientationLeft: 115 return kCGImagePropertyOrientationLeft; 116 case UIImageOrientationLeftMirrored: 117 return kCGImagePropertyOrientationLeftMirrored; 118 } 119}; 120 121# pragma mark - Encoder helpers 122 123+ (EXFaceDetectionAngleTransformBlock)angleTransformerFromTransform:(CGAffineTransform)transform 124{ 125 return ^(float angle) { 126 return (float)(angle - (atan2(transform.b, transform.a) * (180 / M_PI))); 127 }; 128} 129 130@end 131