關(guān)于AVFoundation介紹"http://www.reibang.com/p/8c5c150dba65"
Unknown.jpeg
導(dǎo)入頭文件
#import <AVFoundation/AVFoundation.h>
遵循代理協(xié)議
<AVCaptureMetadataOutputObjectsDelegate>
//捕捉會話
@property(nonatomic,strong)AVCaptureSession *captureSession;
//展示layer
@property (nonatomic,strong)AVCaptureVideoPreviewLayer *videoPreviewLayer;
//保存屏幕中離開的人臉
@property(nonatomic,strong)NSMutableArray *leaveFaceArray;
//保存屏幕檢測到臉對應(yīng)的layer faceID 作為字典 key
@property(nonatomic,strong)NSMutableDictionary *faceLayerDic;
-(NSMutableDictionary *)faceLayerDic{
if (!_faceLayerDic) {
_faceLayerDic = [NSMutableDictionary dictionaryWithCapacity:10];
}
return _faceLayerDic;
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self startReading];
}
檢測攝像頭數(shù)量
- (NSUInteger)cameraCounts {
return [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count];
}
獲取前置攝像頭
- (AVCaptureDevice *)inactiveCamera {
AVCaptureDevice *deviceSelect = nil;
if (self.cameraCounts > 1) {
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices) {
if (device.position == AVCaptureDevicePositionFront) {
deviceSelect = device;
}
}
}
return deviceSelect;
}
開始識別
-(void)startReading{
//讀取攝像頭授權(quán)狀態(tài)
NSString *mediaType = AVMediaTypeVideo;//讀取媒體類型
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];//讀取設(shè)備授權(quán)狀態(tài)
if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied){
// 提示開啟權(quán)限
return;
}
NSError *error;
//1.初始化捕捉設(shè)備(AVCaptureDevice)害幅,類型為AVMediaTypeVideo
AVCaptureDevice *captureDevice = [self inactiveCamera];
//2.用captureDevice創(chuàng)建輸入流,輸入設(shè)備轉(zhuǎn)換成AVCaptureDeviceInput對象
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
if (!input) {
NSLog(@"%@", [error localizedDescription]);
return ;
}
//3.創(chuàng)建媒體數(shù)據(jù)輸出流
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
//4.實例化捕捉會話
self.captureSession = [[AVCaptureSession alloc] init];
self.captureSession.sessionPreset = AVCaptureSessionPresetHigh;
//4.1.將輸入設(shè)備添加到會話
if ([self.captureSession canAddInput:input]) {
[self.captureSession addInput:input];
}
//4.2.將媒體輸出設(shè)備添加到會話
if ([self.captureSession canAddOutput:captureMetadataOutput]) {
[self.captureSession addOutput:captureMetadataOutput];
}
NSArray *metaDataObjectTypes = @[AVMetadataObjectTypeFace];
//4.3.攝像頭在捕捉數(shù)據(jù)時,只會對人臉元數(shù)據(jù)感興趣
captureMetadataOutput.metadataObjectTypes = metaDataObjectTypes;
//獲得主隊列,因為人臉檢測用到硬件加速,而且很多任務(wù)都在主線程執(zhí)行
dispatch_queue_t mainQueue = dispatch_get_main_queue();
//設(shè)置代理 主隊列
[captureMetadataOutput setMetadataObjectsDelegate:self queue:mainQueue];
//5.實例化預(yù)覽圖層
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
//6.設(shè)置預(yù)覽圖層填充方式
[_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
//7.設(shè)置圖層的frame
[_videoPreviewLayer setFrame:self.view.bounds];
[UIView animateWithDuration:2 animations:^{
[self.view.layer addSublayer:_videoPreviewLayer];
}];
//開啟會話
[self.captureSession startRunning];
}
代理方法 獲取捕獲的數(shù)據(jù)
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputMetadataObjects:(NSArray *)metadataObjects
fromConnection:(AVCaptureConnection *)connection {
NSMutableArray *faceArray = [NSMutableArray arrayWithCapacity:10];
//獲取的人臉放到數(shù)組中
for (AVMetadataFaceObject *face in metadataObjects) {
//NSLog(@"faceID:%li",(long)face.faceID);
// NSLog(@"face.bounds:%@",NSStringFromCGRect(face.bounds));
//將攝像頭捕捉的人臉位置轉(zhuǎn)換到屏幕位置
AVMetadataObject *tranformFace = [_videoPreviewLayer transformedMetadataObjectForMetadataObject:face];
[faceArray addObject:tranformFace];
}
//將獲取的人臉數(shù)據(jù)進(jìn)行處理
[self faceOperation:faceArray];
}
-(void)faceOperation:(NSArray *)faceArray{
NSMutableArray *leaveFaceArray = [self.faceLayerDic.allKeys mutableCopy];
for (AVMetadataFaceObject *face in faceArray) {
NSNumber *faceID = @(face.faceID);
[leaveFaceArray removeObject:faceID];
CALayer *layer = self.faceLayerDic[faceID];
if(!layer){
//makeFacelayer :新建一個人臉圖層
layer = [self makeFaceLayer];
//將人臉圖層添加到videoPreviewLayer
[self.videoPreviewLayer addSublayer:layer];
//將 layer加入字典中
self.faceLayerDic[faceID] = layer;
}
//指定圖層的位置
layer.frame = face.bounds;
}
for (NSNumber *faceID in leaveFaceArray) {
CALayer *layer = self.faceLayerDic[faceID];
[layer removeFromSuperlayer];
[self.faceLayerDic removeObjectForKey:faceID];
}
}
- (CALayer *)makeFaceLayer {
CALayer *layer = [CALayer layer];
layer.borderWidth = 2.0f;
layer.borderColor = [UIColor redColor].CGColor;
return layer;
}