加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift - 人脸检测,以及人脸打码

发布时间:2020-12-14 07:13:02 所属栏目:百科 来源:网络整理
导读:1,人脸检测的实现 (1)人脸检测是指在图像中寻找符合人脸特征的区域,找到后会返回该特征的信息(比如人脸的范围、眼睛和嘴巴的位置等)。不是指人脸识别,识别出是谁的脸。 (2) Core Image 框架中的的 CIDetector 对象提供了对图像检测的功能。创建 CID
1,人脸检测的实现
(1)人脸检测是指在图像中寻找符合人脸特征的区域,找到后会返回该特征的信息(比如人脸的范围、眼睛和嘴巴的位置等)。不是指人脸识别,识别出是谁的脸。
(2) Core Image框架中的的 CIDetector对象提供了对图像检测的功能。创建 CIDetector对象时使用 CIDetectorTypeFace表示检测人脸。
(3)下面通过样例演示如何进行人脸检测,同时检测完成后会用方框把人脸给标注出来。
(注意:由于方框是一个个UIView添加到imageView中,而人脸检测出来的位置是相对于原图的。所以方框放置的位置要考虑图片在imageView里的缩放大小,x轴,y轴的偏移量)

2,给人脸打上马赛克的功能实现
(1)使用用 CIPixellate滤镜对原图先做个完全马赛克
(2)检测人脸,以人脸为中心,脸的宽度或高度为半径。做一个包含一个一个圆形区域的蒙板。
(3) CIBlendWithMask滤镜把马赛克图、原图、蒙版图混合起来,输出即可。

3,效果图如下


4,代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import UIKit
ImageIO
class ViewController : UIViewController {
@IBOutlet weak var imageView: UIImageView !
//原图
lazy originalImage: UIImage = {
return (named: "d1.jpg" )
}()!
context: CIContext = {
return CIContext (options: nil )
}()
override func viewDidLoad() {
super .viewDidLoad()
}
//恢复原图
@IBAction resetImg(sender: AnyObject ) {
imageView.image = originalImage
}
//检测人脸并框出
detectFace(sender: AnyObject ) {
imageView.image = originalImage
let inputImage = CIImage (image: originalImage)!
//人脸检测器
//CIDetectorAccuracyHigh:检测的精度高,但速度更慢些
detector = CIDetector (ofType: CIDetectorTypeFace ,
context: context,
options: [ CIDetectorAccuracy : CIDetectorAccuracyHigh ])
faceFeatures: [ CIFaceFeature ]!
//人脸检测需要图片方向(有元数据的话使用元数据,没有就调用featuresInImage)
if orientation: = inputImage
.properties[kCGImagePropertyOrientation as String ] {
faceFeatures = detector.featuresInImage(inputImage,
options: [ CIDetectorImageOrientation : orientation]) as ! [ CIFaceFeature ]
} else {
faceFeatures = detector.featuresInImage(inputImage) ]
}
//打印所有的面部特征
print (faceFeatures)
inputImageSize = inputImage.extent.size
transform = CGAffineTransformIdentity
CGAffineTransformScale (transform,1,-1)
transform = CGAffineTransformTranslate
//遍历所有的面部,并框出
for faceFeature in faceFeatures {
faceViewBounds = CGRectApplyAffineTransform (faceFeature.bounds,transform)
// 由于检测的原图放在imageView中缩放的原因,我们还要考虑缩放比例和x,y轴偏移
scale = min (imageView.bounds.size.width / inputImageSize.width,
imageView.bounds.size.height / inputImageSize.height)
offsetX = (imageView.bounds.size.width - inputImageSize.width * scale) / 2
offsetY = (imageView.bounds.size.height - inputImageSize.height * scale) / 2
faceViewBounds = CGRectApplyAffineTransform (faceViewBounds,
CGAffineTransformMakeScale (scale,scale))
faceViewBounds.origin.x += offsetX
faceViewBounds.origin.y += offsetY
//每个人脸对应一个UIView方框
faceView = UIView (frame: faceViewBounds)
faceView.layer.borderColor = UIColor .orangeColor(). CGColor
faceView.layer.borderWidth = 2
imageView.addSubview(faceView)
}
}
//检测人脸并打马赛克
detectAndPixFace(sender: ) {
// 用CIPixellate滤镜对原图先做个完全马赛克
let filter = CIFilter (name: "CIPixellate" )!
( .attributes)
(image: originalImage)!
.setValue(inputImage,forKey: kCIInputImageKey)
inputScale = max (inputImage.extent.size.width,inputImage.extent.size.height) / 80
.setValue(inputScale,forKey: kCIInputScaleKey)
fullPixellatedImage = .outputImage
// 检测人脸,并保存在faceFeatures中
options: )
faceFeatures = detector.featuresInImage(inputImage)
// 初始化蒙版图,并开始遍历检测到的所有人脸
maskImage: !
faceFeatures {
(faceFeature.bounds)
// 基于人脸的位置,为每一张脸都单独创建一个蒙版,所以要先计算出脸的中心点,对应为x、y轴坐标,
// 再基于脸的宽度或高度给一个半径,最后用这些计算结果初始化一个CIRadialGradient滤镜
centerX = faceFeature.bounds.origin.x + faceFeature.bounds.size.width / 2
centerY = faceFeature.bounds.origin.y + faceFeature.bounds.size.height / 2
radius = (faceFeature.bounds.size.width,faceFeature.bounds.size.height)
radialGradient = CIFilter "CIRadialGradient" withInputParameters: [
"inputRadius0" : radius,
"inputRadius1" : radius + 1,
"inputColor0" CIColor (red: 0,green: 1,blue: 0,alpha: 1),
"inputColor1" kCIInputCenterKey : CIVector (x: centerX,y: centerY)
])!
(radialGradient.attributes)
// 由于CIRadialGradient滤镜创建的是一张无限大小的图,所以在使用之前先对它进行裁剪
radialGradientOutputImage = radialGradient.outputImage!
.imageByCroppingToRect(inputImage.extent)
if maskImage == {
maskImage = radialGradientOutputImage
{
(radialGradientOutputImage)
maskImage = "CISourceOverCompositing" withInputParameters: [
kCIInputImageKey : radialGradientOutputImage,
kCIInputBackgroundImageKey : maskImage
])!.outputImage
}
}
// 用CIBlendWithMask滤镜把马赛克图、原图、蒙版图混合起来
blendFilter = "CIBlendWithMask" )!
blendFilter.setValue(fullPixellatedImage,forKey: kCIInputImageKey)
blendFilter.setValue(inputImage,forKey: kCIInputBackgroundImageKey)
blendFilter.setValue(maskImage,forKey: kCIInputMaskImageKey)
// 输出,在界面上显示
blendOutputImage = blendFilter.outputImage
blendCGImage = context.createCGImage(blendOutputImage!,
fromRect: blendOutputImage!.extent)
imageView.image = ( CGImage : blendCGImage)
}
didReceiveMemoryWarning() {
.didReceiveMemoryWarning()
}
}

原文出自: www.hangge.com 转载请保留原文链接: http://www.hangge.com/blog/cache/detail_907.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读