版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么在iOS中使用CoreImage实现一个人脸识别功能
这篇文章给大家介绍怎么在iOS中使用CoreImage实现一个人脸识别功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前言CoreImage是CocoaTouch中一个强大的API,也是iOSSDK中的关键部分,不过它经常被忽视。在本篇教程中,我会带大家一起验证CoreImage的人脸识别特性。在开始之前,我们先要简单了解下CoreImageframework组成CoreImageframework组成Apple已经帮我们把image的处理分类好,来看看它的结构:主要分为三个部分:1、定义部分:CoreImage和CoreImageDefines。见名思义,代表了CoreImage这个框架和它的定义。2、操作部分:滤镜(CIFliter):CIFilter产生一个CIImage。典型的,接受一到多的图片作为输入,经过一些过滤操作,产生指定输出的图片。检测(CIDetector):CIDetector检测处理图片的特性,如使用来检测图片中人脸的眼睛、嘴巴、等等。特征(CIFeature):CIFeature代表由detector处理后产生的特征。3、图像部分:画布(CIContext):画布类可被用与处理Quartz2D或者OpenGL。可以用它来关联CoreImage类。如滤镜、颜色等渲染处理。颜色(CIColor):图片的关联与画布、图片像素颜色的处理。向量(CIVector):图片的坐标向量等几何方法处理。图片(CIImage):代表一个图像,可代表关联后输出的图像。在了解上述基本知识后,我们开始通过创建一个工程来带大家一步步验证CoreImage的人脸识别特性。将要构建的应用iOS的人脸识别从iOS5(2011)就有了,不过一直没怎么被关注过。人脸识别API允许开发者不仅可以检测人脸,也可以检测到面部的一些特殊属性,比如说微笑或眨眼。首先,为了了解CoreImage的人脸识别技术我们会创建一个app来识别照片中的人脸并用一个方框来标记它。在第二个demo中,让用户拍摄一张照片,检测其中的人脸并检索人脸位置。这样一来,就充分掌握了iOS中的人脸识别,并且学会如何利用这个强大却总被忽略的API。话不多说,开搞!建立工程(我用的是Xcode8.0)这里提供了初始工程,当然你也可以自己创建(主要是为了方便大家)点我下载用Xcode打开下载后的工程,可以看到里面只有一个关联了IBOutlet和imageView的StoryBoard。使用CoreImage识别人脸在开始工程中,故事板中的imageView组件与代码中的IBOutlet已关联,接下来要编写实现人脸识别的代码部分。在ViewController.swift文件中写下如下代码:import
UIKit
import
CoreImage
//
引入CoreImage
class
ViewController:
UIViewController
{
@IBOutlet
weak
var
personPic:
UIImageView!
override
func
viewDidLoad()
{
super.viewDidLoad()
personPic.image
=
UIImage(named:
"face-1")
//
调用detect
detect()
}
//MARK:
-
识别面部
func
detect()
{
//
创建personciImage变量保存从故事板中的UIImageView提取图像并将其转换为CIImage,使用Core
Image时需要用CIImage
guard
let
personciImage
=
CIImage(image:
personPic.image!)
else
{
return
}
//
创建accuracy变量并设为CIDetectorAccuracyHigh,可以在CIDetectorAccuracyHigh(较强的处理能力)与CIDetectorAccuracyLow(较弱的处理能力)中选择,因为想让准确度高一些在这里选择CIDetectorAccuracyHigh
let
accuracy
=
[CIDetectorAccuracy:
CIDetectorAccuracyHigh]
//
这里定义了一个属于CIDetector类的faceDetector变量,并输入之前创建的accuracy变量
let
faceDetector
=
CIDetector(ofType:
CIDetectorTypeFace,
context:
nil,
options:
accuracy)
//
调用faceDetector的featuresInImage方法,识别器会找到所给图像中的人脸,最后返回一个人脸数组
let
faces
=
faceDetector?.features(in:
personciImage)
//
循环faces数组里的所有face,并将识别到的人脸强转为CIFaceFeature类型
for
face
in
faces
as!
[CIFaceFeature]
{
print("Found
bounds
are
\(face.bounds)")
//
创建名为faceBox的UIView,frame设为返回的faces.first的frame,绘制一个矩形框来标识识别到的人脸
let
faceBox
=
UIView(frame:
face.bounds)
//
设置faceBox的边框宽度为3
faceBox.layer.borderWidth
=
3
//
设置边框颜色为红色
faceBox.layer.borderColor
=
UIColor.red.cgColor
//
将背景色设为clear,意味着这个视图没有可见的背景
faceBox.backgroundColor
=
UIColor.clear
//
最后,把这个视图添加到personPic
imageView上
personPic.addSubview(faceBox)
//
API不仅可以帮助你识别人脸,也可识别脸上的左右眼,我们不在图像中标识出眼睛,只是给你展示一下CIFaceFeature的相关属性
if
face.hasLeftEyePosition
{
print("Left
eye
bounds
are
\(face.leftEyePosition)")
}
if
face.hasRightEyePosition
{
print("Right
eye
bounds
are
\(face.rightEyePosition)")
}
}
}
}编译并运行app,结果应如下图所示:根据控制台的输出来看,貌似识别器识别到了人脸:Found
bounds
are
(314.0,
243.0,
196.0,
196.0)当前的实现中没有解决的问题:人脸识别是在原始图像上进行的,由于原始图像的分辨率比imageview要高,因此需要设置imageview的contentmode为aspectfit(保持纵横比的情况下缩放图片)。为了合适的绘制矩形框,需要计算imageview中人脸的实际位置与尺寸还要注意的是,CoreImage与UIView使用两种不同的坐标系统(看下图),因此要实现一个CoreImage坐标到UIView坐标的转换。UIView坐标系:CoreImage坐标系:现在使用下面的代码替换detect()方法:func
detect1()
{
guard
let
personciImage
=
CIImage(image:
personPic.image!)
else
{
return
}
let
accuracy
=
[CIDetectorAccuracy:
CIDetectorAccuracyHigh]
let
faceDetector
=
CIDetector(ofType:
CIDetectorTypeFace,
context:
nil,
options:
accuracy)
let
faces
=
faceDetector?.features(in:
personciImage)
//
转换坐标系
let
ciImageSize
=
personciImage.extent.size
var
transform
=
CGAffineTransform(scaleX:
1,
y:
-1)
transform
=
transform.translatedBy(x:
0,
y:
-ciImageSize.height)
for
face
in
faces
as!
[CIFaceFeature]
{
print("Found
bounds
are
\(face.bounds)")
//
应用变换转换坐标
var
faceViewBounds
=
face.bounds.applying(transform)
//
在图像视图中计算矩形的实际位置和大小
let
viewSize
=
personPic.bounds.size
let
scale
=
min(viewSize.width
/
ciImageSize.width,
viewSize.height
/
ciImageSize.height)
let
offsetX
=
(viewSize.width
-
ciImageSize.width
*
scale)
/
2
let
offsetY
=
(viewSize.height
-
ciImageSize.height
*
scale)
/
2
faceViewBounds
=
faceViewBounds.applying(CGAffineTransform(scaleX:
scale,
y:
scale))
faceViewBounds.origin.x
+=
offsetX
faceViewBounds.origin.y
+=
offsetY
let
faceBox
=
UIView(frame:
faceViewBounds)
faceBox.layer.borderWidth
=
3
faceBox.layer.borderColor
=
UIColor.red.cgColor
faceBox.backgroundColor
=
UIColor.clear
personPic.addSubview(faceBox)
if
face.hasLeftEyePosition
{
print("Left
eye
bounds
are
\(face.leftEyePosition)")
}
if
face.hasRightEyePosition
{
print("Right
eye
bounds
are
\(face.rightEyePosition)")
}
}
}上述代码中,首先使用仿射变换(AffineTransform)将CoreImage坐标转换为UIKit坐标,然后编写了计算实际位置与矩形视图尺寸的代码。再次运行app,应该会看到人的面部周围会有一个框。OK,你已经成功使用CoreImage识别出了人脸。但是有的童鞋在使用了上面的代码运行后可能会出现方框不存在(即没有识别人脸)这种情况,这是由于忘记关闭AutoLayout以及SizeClasses了。选中storyBoard中的ViewController,选中view下的imageView。然后在右边的面板中的第一个选项卡中找到useAutoLayout,将前面的✔️去掉就可以了经过上面的设置后我们再次运行App,就会看到图三出现的效果了。构建一个人脸识别的相机应用想象一下你有一个用来照相的相机app,照完相后你想运行一下人脸识别来检测一下是否存在人脸。若存在一些人脸,你也许想用一些标签来对这些照片进行分类。我们不会构建一个保存照片后再处理的app,而是一个实时的相机app,因此需要整合一下UIImagePicker类,在照完相时立刻进行人脸识别。在开始工程中已经创建好了CameraViewController类,使用如下代码实现相机的功能:class
CameraViewController:
UIViewController,
UIImagePickerControllerDelegate,
UINavigationControllerDelegate
{
@IBOutlet
var
imageView:
UIImageView!
let
imagePicker
=
UIImagePickerController()
override
func
viewDidLoad()
{
super.viewDidLoad()
imagePicker.delegate
=
self
}
@IBAction
func
takePhoto(_
sender:
AnyObject)
{
if
!UIImagePickerController.isSourceTypeAvailable(.camera)
{
return
}
imagePicker.allowsEditing
=
false
imagePicker.sourceType
=
.camera
present(imagePicker,
animated:
true,
completion:
nil)
}
func
imagePickerController(_
picker:
UIImagePickerController,
didFinishPickingMediaWithInfo
info:
[String
:
Any])
{
if
let
pickedImage
=
info[UIImagePickerControllerOriginalImage]
as?
UIImage
{
imageView.contentMode
=
.scaleAspectFit
imageView.image
=
pickedImage
}
dismiss(animated:
true,
completion:
nil)
self.detect()
}
func
imagePickerControllerDidCancel(_
picker:
UIImagePickerController)
{
dismiss(animated:
true,
completion:
nil)
}
}前面几行设置UIImagePicker委托为当前视图类,在didFinishPickingMediaWithInfo方法(UIImagePicker的委托方法)中设置imageView为在方法中所选择的图像,接着返回上一视图调用detect函数。还没有实现detect函数,插入下面代码并分析一下:func
detect()
{
let
imageOptions
=
NSDictionary(object:
NSNumber(value:
5)
as
NSNumber,
forKey:
CIDetectorImageOrientation
as
NSString)
let
personciImage
=
CIImage(cgImage:
imageView.image!.cgImage!)
let
accuracy
=
[CIDetectorAccuracy:
CIDetectorAccuracyHigh]
let
faceDetector
=
CIDetector(ofType:
CIDetectorTypeFace,
context:
nil,
options:
accuracy)
let
faces
=
faceDetector?.features(in:
personciImage,
options:
imageOptions
as?
[String
:
AnyObject])
if
let
face
=
faces?.first
as?
CIFaceFeature
{
print("found
bounds
are
\(face.bounds)")
let
alert
=
UIAlertController(title:
"提示",
message:
"检测到了人脸",
preferredStyle:
UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title:
"确定",
style:
UIAlertActionStyle.default,
handler:
nil))
self.present(alert,
animated:
true,
completion:
nil)
if
face.hasSmile
{
print("face
is
smiling");
}
if
face.hasLeftEyePosition
{
print("左眼的位置:
\(face.leftEyePosition)")
}
if
face.hasRightEyePosition
{
print("右眼的位置:
\(face
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年各工种交接班制度(2篇)
- 瓷砖安装购销合同
- 温馨可靠托儿所育儿合同
- 钢结构工程分包合同解析
- 造纸厂购销合同的签订注意事项
- 外架工程人工分包合同样本
- 天津分包合同备案指南
- 房屋买卖合同应注意什么
- 分包合同审批表操作手册
- 技术服务合同印花税的案例解析
- 人教版高一地理必修一期末试卷
- 山东省临沂市2023-2024学年高二上学期1月期末地理试题 附答案
- 2024-2025学年北师大版九年级上册数学期末测试综合练习题(原卷版)-A4
- 2025北京语言大学新编长聘人员招聘21人笔试备考试题及答案解析
- 博鳌机场控制区证件培训专项测试卷
- 珠宝鉴赏智慧树知到期末考试答案章节答案2024年同济大学
- 国家开放大学《中文学科论文写作》形考任务1-4参考答案
- 《中国近现代史纲要(2023版)》课后习题答案合集汇编
- GB/T 9065.2-2010液压软管接头第2部分:24°锥密封端软管接头
- 中国美食英文介绍ppt课件
- 语文课外阅读兴趣小组活动记录
评论
0/150
提交评论