当前位置: 代码迷 >> 综合 >> [iOS]检测图片上是否有人脸
  详细解决方案

[iOS]检测图片上是否有人脸

热度:81   发布时间:2024-02-08 08:01:11.0

这识别人脸这功能在很多地方都能使用到。比如在APP中需要用户使用人脸识别时,这种肯定要在用户上传头像时先判断图片中是否有人脸。

[使用]

1、已经拿到UIImage后直接检测

UIImage *editedImage = imgModel.previewPhoto?:imgModel.thumbPhoto;
/// 检测图片上是否有人脸
if ([IWCheckImageHaveFace checkHaveFaceWithImage:editedImage]) {[self uploadImages:editedImage];
} else {[MBProgressHUD showError:@"使用的照片中不包含人脸,请重新选择"];
}

2、从相机输出数据中拿到UIImage,再去检测。

#import "IWFaceCompareCheckController.h"
#import "CommonHeader.h"
#import "IWCheckImageHaveFace.h"
#import <AVFoundation/AVFoundation.h>@interface IWFaceCompareCheckController () <AVCaptureVideoDataOutputSampleBufferDelegate>@property (nonatomic, assign) BOOL isDelay;
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureDevice *captureDevice;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;@end@implementation IWFaceCompareCheckController- (AVCaptureSession *)captureSession {if (!_captureSession) {_captureSession = [[AVCaptureSession alloc] init];}return _captureSession;
}- (void)viewDidLoad {[super viewDidLoad];[self beginSessionIsFront:NO];[self performSelector:@selector(startCheckAction) withObject:nil afterDelay:1.0];
}- (void)viewWillDisappear:(BOOL)animated {[super viewWillDisappear:animated];[self.captureSession stopRunning];
}- (void)returnPresVcAction {[self.captureSession stopRunning];[self.navigationController popViewControllerAnimated:NO];
}- (void)startCheckAction {_isDelay = YES;
}- (AVCaptureDevice *)videoDeviceWithPosition:(AVCaptureDevicePosition)position {NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];for (AVCaptureDevice *device in devices) {if ([device position] == position) {return device;}}return nil;
}- (void)beginSessionIsFront:(BOOL)isFront {self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;AVCaptureDevice *videoDevice;if (isFront) {videoDevice = [self videoDeviceWithPosition:AVCaptureDevicePositionFront];} else {videoDevice = [self videoDeviceWithPosition:AVCaptureDevicePositionBack];}NSError *error;AVCaptureDeviceInput *deviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:videoDevice error:&error];if ([self.captureSession canAddInput:deviceInput]) {[self.captureSession addInput:deviceInput];} else {NSLog(@"add input error");}AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];dispatch_queue_t cameraQueue = dispatch_queue_create("cameraQueue", DISPATCH_QUEUE_SERIAL);[output setSampleBufferDelegate:self queue:cameraQueue];output.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInteger:kCVPixelFormatType_32BGRA],kCVPixelBufferPixelFormatTypeKey,nil];[self.captureSession addOutput:output];if (error) {NSLog(@"error:%@",error.description);}AVCaptureConnection *videoConnection = [output connectionWithMediaType:AVMediaTypeVideo];if (isFront) {if (videoConnection.supportsVideoMirroring) {[videoConnection setVideoMirrored:true];}} else {if (videoConnection.supportsVideoMirroring) {[videoConnection setVideoMirrored:false];}}self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];self.previewLayer.videoGravity = @"AVLayerVideoGravityResizeAspect";self.previewLayer.frame = self.view.bounds;[self.view.layer addSublayer:self.previewLayer];[self.captureSession startRunning];
}- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {// 识别太快,设置1秒钟的延迟if (!_isDelay) {return;}UIImage *resultImage = [IWCheckImageHaveFace sampleBufferToImage:sampleBuffer];// 检测图片上是否有人脸if ([IWCheckImageHaveFace checkHaveFaceWithImage:resultImage]) {[self uploadImage:resultImage];} else {}
}@end

[检测]

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>@interface IWCheckImageHaveFace : NSObject+ (UIImage *)sampleBufferToImage:(CMSampleBufferRef)sampleBuffer;/// 检测图片上是否有人脸
+ (BOOL)checkHaveFaceWithImage:(UIImage *)resultImage;@end
#import "IWCheckImageHaveFace.h"@interface IWCheckImageHaveFace ()@end@implementation IWCheckImageHaveFace+ (UIImage *)sampleBufferToImage:(CMSampleBufferRef)sampleBuffer {CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);CIImage *ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer];CIContext *temporaryContext = [CIContext contextWithOptions:nil];CGImageRef videoImage = [temporaryContext createCGImage:ciImage fromRect:CGRectMake(0, 0, CVPixelBufferGetWidth(imageBuffer), CVPixelBufferGetHeight(imageBuffer))];UIImage *result = [[UIImage alloc] initWithCGImage:videoImage scale:1.0 orientation:UIImageOrientationLeftMirrored];CGImageRelease(videoImage);return result;
}+ (BOOL)checkHaveFaceWithImage:(UIImage *)resultImage {BOOL result = NO;resultImage = [self fixOrientation:resultImage];CGFloat scale = [UIScreen mainScreen].bounds.size.width / resultImage.size.width;//CGFloat topMargin = ([UIScreen mainScreen].bounds.size.height - resultImage.size.height * scale) * 0.5;CIImage *ciImage = [[CIImage alloc] initWithImage:resultImage];CIDetector *detector = [CIDetector  detectorOfType:CIDetectorTypeFace context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh,CIDetectorMinFeatureSize:[[NSNumber alloc] initWithFloat:0.2],CIDetectorTracking:[NSNumber numberWithBool:YES]}];NSArray<CIFaceFeature *> *results = (NSArray<CIFaceFeature *> *) [detector featuresInImage:ciImage options:@{CIDetectorImageOrientation:[[NSNumber alloc]initWithInt:1]}];if (results.count > 0) {result = YES;}return result;
}/// 图片方向调整
- (UIImage *)fixOrientation:(UIImage *)aImage {// No-op if the orientation is already correctif (aImage.imageOrientation == UIImageOrientationUp)return aImage;// We need to calculate the proper transformation to make the image upright.// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.CGAffineTransform transform = CGAffineTransformIdentity;switch (aImage.imageOrientation) {case UIImageOrientationDown:case UIImageOrientationDownMirrored:transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);transform = CGAffineTransformRotate(transform, M_PI);break;case UIImageOrientationLeft:case UIImageOrientationLeftMirrored:transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);transform = CGAffineTransformRotate(transform, M_PI_2);break;case UIImageOrientationRight:case UIImageOrientationRightMirrored:transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);transform = CGAffineTransformRotate(transform, -M_PI_2);break;default:break;}switch (aImage.imageOrientation) {case UIImageOrientationUpMirrored:case UIImageOrientationDownMirrored:transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);transform = CGAffineTransformScale(transform, -1, 1);break;case UIImageOrientationLeftMirrored:case UIImageOrientationRightMirrored:transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);transform = CGAffineTransformScale(transform, -1, 1);break;default:break;}// Now we draw the underlying CGImage into a new context, applying the transform// calculated above.CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,CGImageGetBitsPerComponent(aImage.CGImage), 0,CGImageGetColorSpace(aImage.CGImage),CGImageGetBitmapInfo(aImage.CGImage));CGContextConcatCTM(ctx, transform);switch (aImage.imageOrientation) {case UIImageOrientationLeft:case UIImageOrientationLeftMirrored:case UIImageOrientationRight:case UIImageOrientationRightMirrored:// Grr...CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);break;default:CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);break;}// And now we just create a new UIImage from the drawing contextCGImageRef cgimg = CGBitmapContextCreateImage(ctx);UIImage *img = [UIImage imageWithCGImage:cgimg];CGContextRelease(ctx);CGImageRelease(cgimg);return img;
}@end



  相关解决方案