#import #import #import "PGFaceProcessor.h" #include @interface PGRealtimeFaceTracker : NSObject - (NSDictionary *)resultForGeometry:(NSArray *)raw settings:(PGBeautySettings)s time:(CMTime)time extent:(CGRect)extent; @end @interface PGFaceProcessor (ProbeWarp) - (CIImage *)warpImage:(CIImage *)image geometry:(NSArray *)geometry settings:(PGBeautySettings)s extent:(CGRect)extent; - (NSArray *)observationsInImage:(CIImage *)image settings:(PGBeautySettings)s error:(NSError **)error; @end @interface ProbeFaceProcessor : PGFaceProcessor @property (nonatomic,copy) NSArray *authoredDetections; @end @implementation ProbeFaceProcessor - (NSArray *)observationsInImage:(CIImage *)image settings:(PGBeautySettings)s error:(NSError **)error {return self.authoredDetections?:@[];} @end #import "../tests/tracking_fixture.h" static NSDictionary *Geometry(CGRect box,double jitter,BOOL has76) { NSMutableDictionary *g=[PGTrackingTestGeometry(box,jitter) mutableCopy]; if(!has76)[g removeObjectForKey:@"points76"]; return g; } static NSDictionary *Live(PGRealtimeFaceTracker *t,NSArray *g,PGBeautySettings s,int64_t tick){return[t resultForGeometry:g settings:s time:CMTimeMake(tick,1000) extent:CGRectMake(0,0,256,256)];} static double PointX(NSDictionary *r){return[r[@"output"][0][@"points76"][69][0] doubleValue];} static NSData *Pixels(CIContext *context,CIImage *image){ CGRect e=image.extent;NSUInteger w=e.size.width,h=e.size.height;NSMutableData *d=[NSMutableData dataWithLength:w*h*4*sizeof(float)]; [context render:image toBitmap:d.mutableBytes rowBytes:w*4*sizeof(float) bounds:e format:kCIFormatRGBAf colorSpace:NULL];return d; } static NSDictionary *Difference(NSData *a,NSData *b){ const float *x=a.bytes,*y=b.bytes;NSUInteger n=a.length/sizeof(float),changed=0;double maximum=0,sum=0; for(NSUInteger i=0;i1e-6)changed++;} return@{@"maxChannelDifference":@(maximum),@"meanChannelDifference":@(sum/n),@"changedChannelsAbove1e_6":@(changed)}; } static double MeanRed(CIContext *context,CIImage *image){NSData *d=Pixels(context,image);const float *p=d.bytes;NSUInteger n=d.length/(4*sizeof(float));double sum=0;for(NSUInteger i=0;i