【IOS】人脸检测简单搭建

1.引入头文件

#import  <AVFoundation/AVFoundation.h>

代理 <AVCaptureVideoDataOutputSampleBufferDelegate>


2.新建属性

@property(strong,nonatomic)AVCaptureSession*captureSession;//数据传递

@property(strong,nonatomic)AVCaptureDeviceInput*captureDeviceInput;//输入数据

@property(strong,nonatomic)AVCaptureVideoDataOutput*captureVideoDataOutput;//视频输出

@property(strong,nonatomic)AVCaptureVideoPreviewLayer*captureVideoPreviewLayer;//相机拍摄预览图层 连接一个view.layer显示


3.初始化配置


//(1)初始化Session


_captureSession= [[AVCaptureSessionalloc]init];

if([_captureSessioncanSetSessionPreset:AVCaptureSessionPreset1280x720]) {

_captureSession.sessionPreset=AVCaptureSessionPreset1280x720;

}

//(2)初始化输入取得后置摄像头ios10之前


AVCaptureDevice*captureDevice = [selfgetCameraDeviceWithPosition:AVCaptureDevicePositionBack];

if(!captureDevice) {

NSLog(@"取得后置摄像头时出现问题.");

return;

}

/*

-(AVCaptureDevice*)getCameraDeviceWithPosition:(AVCaptureDevicePosition)position{

NSArray*cameras= [AVCaptureDevicedevicesWithMediaType:AVMediaTypeVideo];

for(AVCaptureDevice*cameraincameras) {

if([cameraposition]==position) {

returncamera;

}

}

returnnil;

}

*/

//根据输入设备初始化设备输入对象,用于获得输入数据

NSError*error=nil;

_captureDeviceInput= [[AVCaptureDeviceInputalloc]initWithDevice:captureDeviceerror:&error];

if(error) {

NSLog(@"取得设备输入对象时出错,错误原因:%@",error.localizedDescription);

return;

}

if([_captureSessioncanAddInput:_captureDeviceInput]) {

[_captureSessionaddInput:_captureDeviceInput];

}

//(3)初始化输出


_captureVideoDataOutput= [[AVCaptureVideoDataOutputalloc]init];

if([_captureSessioncanAddOutput:_captureVideoDataOutput]) {

[_captureSessionaddOutput:_captureVideoDataOutput];

//指定代理 增加并行线程

dispatch_queue_tqueue =dispatch_queue_create("myQueue",DISPATCH_QUEUE_CONCURRENT);

[_captureVideoDataOutputsetSampleBufferDelegate:selfqueue:queue];

_captureVideoDataOutput.videoSettings=

[NSDictionarydictionaryWithObject:

[NSNumbernumberWithInt:kCVPixelFormatType_32BGRA]

forKey:(id)kCVPixelBufferPixelFormatTypeKey];

AVCaptureConnection*captureConnection = [_captureVideoDataOutputconnectionWithMediaType:AVMediaTypeVideo];

NSError*error;

CMTimeframeDuration =CMTimeMake(1,15);//指定帧数

NSArray*supportedFrameRateRanges = [captureDevice.activeFormatvideoSupportedFrameRateRanges];

BOOLframeRateSupported =NO;

for(AVFrameRateRange*rangeinsupportedFrameRateRanges) {

if(CMTIME_COMPARE_INLINE(frameDuration, >=, range.minFrameDuration) &&

CMTIME_COMPARE_INLINE(frameDuration, <=, range.maxFrameDuration)) {

frameRateSupported =YES;

}

}

if(frameRateSupported && [captureDevicelockForConfiguration:&error]) {

[captureDevicesetActiveVideoMaxFrameDuration:frameDuration];

[captureDevicesetActiveVideoMinFrameDuration:frameDuration];

[captureDeviceunlockForConfiguration];

}

//防抖

if([captureConnectionisVideoStabilizationSupported]) {

captureConnection.preferredVideoStabilizationMode=AVCaptureVideoStabilizationModeAuto;

}

}

// (4)初始化显示界面


_captureVideoPreviewLayer= [[AVCaptureVideoPreviewLayeralloc]initWithSession:self.captureSession];

CALayer*layer =self.showView.layer;

layer.masksToBounds=YES;

_captureVideoPreviewLayer.frame=layer.bounds;

_captureVideoPreviewLayer.videoGravity=AVLayerVideoGravityResizeAspect;

[layeraddSublayer:_captureVideoPreviewLayer];

/*

//更新界面布局

- (void)viewDidLayoutSubviews{

CALayer*layer =self.showView.layer;

_captureVideoPreviewLayer.frame=layer.bounds;

}

*/


4.代理处理数据


- (void)captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection

{

CVImageBufferRefimageBuffer =CMSampleBufferGetImageBuffer(sampleBuffer);

CVPixelBufferLockBaseAddress(imageBuffer,0);

uint8_t*baseAddress = (uint8_t*)CVPixelBufferGetBaseAddress(imageBuffer);

size_tbytesPerRow =CVPixelBufferGetBytesPerRow(imageBuffer);

size_twidth =CVPixelBufferGetWidth(imageBuffer);

size_theight =CVPixelBufferGetHeight(imageBuffer);

CVPixelBufferUnlockBaseAddress(imageBuffer,0);

CGColorSpaceRefcolorSpace =CGColorSpaceCreateDeviceRGB();

CGContextRefnewContext =CGBitmapContextCreate(baseAddress, width, height,8, bytesPerRow, colorSpace,kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);

CGImageRefnewImage =CGBitmapContextCreateImage(newContext);

UIImage*image= [UIImageimageWithCGImage:newImagescale:1.0orientation:UIImageOrientationRight];//当前的图像

//人脸检测

CIDetector*faceDetector = [CIDetectordetectorOfType:CIDetectorTypeFacecontext:niloptions:@{CIDetectorAccuracy:CIDetectorAccuracyLow}];

NSArray*features = [faceDetectorfeaturesInImage:[CIImageimageWithCGImage:image.CGImage]options:@{CIDetectorImageOrientation:[NSNumbernumberWithInt:6]}];

CIFaceFeature*feature = [featuresfirstObject];

if(feature) {

CGFloatx =0;

CGFloaty =0;

CGFloatx1 =0;

CGFloaty1 =0;

CGFloathwidth =40;

CGFloathheight =40;

CGFloatoffSetY =0;

CGFloatoffSetX =0;

CGFloatoffSetHeight =0;

if(feature.hasLeftEyePosition){

CGPointleftEyePos = feature.leftEyePosition;

NSLog(@"leftX = %f  leftY = %f",leftEyePos.x,leftEyePos.y);

x1 = leftEyePos.x;

y1 = leftEyePos.y;

}

if(feature.hasRightEyePosition){

CGPointrightEyePos = feature.rightEyePosition;

NSLog(@"rightX = %f  rightY = %f",rightEyePos.x,rightEyePos.y);

x = rightEyePos.x;

y = rightEyePos.y;

hheight = (y - y1);

}

if(feature.hasMouthPosition){

CGPointmouthPos = feature.mouthPosition;

NSLog(@"mouthX = %f mouthY = %f",mouthPos.x,mouthPos.y);

hwidth = mouthPos.x- x;

offSetHeight = hheight/4.0;

offSetY = offSetHeight;

offSetX = hwidth/2.0;

}

CGRectrect =CGRectMake(x, image.size.width- y, hwidth, hheight);

CGImageRefsubImageRef =CGImageCreateWithImageInRect(image.CGImage, rect);

UIImage*smallImage= [UIImageimageWithCGImage:subImageRefscale:1.0orientation:UIImageOrientationRight];//获取到的脸部图像

dispatch_async(dispatch_get_main_queue(), ^{

self.headImage.image= smallImage;

self.yuanImage.image= image;

});

CGImageRelease(subImageRef);

}

CGContextRelease(newContext);

CGColorSpaceRelease(colorSpace);

CGImageRelease(newImage);

}





最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 1、禁止手机睡眠[UIApplication sharedApplication].idleTimerDisabl...
    DingGa阅读 1,116评论 1 6
  • 1、设置UILabel行间距 NSMutableAttributedString* attrString = [[...
    十年一品温如言1008阅读 1,630评论 0 3
  • 1、设置UILabel行间距 NSMutableAttributedString* attrString = [[...
    FF_911阅读 1,361评论 0 3
  • 在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新。 UITableView的Group样式下顶部...
    管你爱不爱阅读 425评论 0 1
  • 从清晨的朝阳,到月色朦胧,伴随着焦躁的知了声的停停歇歇,这又是所谓的一天…… 素颜的S就像用HB铅笔简画的素描,五...
    巧遇XxX阅读 349评论 2 4