1,人脸检测的实现
(1)人脸检测是指在图像中寻找符合人脸特征的区域,找到后会返回该特征的信息(比如人脸的范围、眼睛和嘴巴的位置等)。不是指人脸识别,识别出是谁的脸。 (3)下面通过样例演示如何进行人脸检测,同时检测完成后会用方框把人脸给标注出来。
(3) CIBlendWithMask滤镜把马赛克图、原图、蒙版图混合起来,输出即可。
3,效果图如下
4,代码如下
(1)人脸检测是指在图像中寻找符合人脸特征的区域,找到后会返回该特征的信息(比如人脸的范围、眼睛和嘴巴的位置等)。不是指人脸识别,识别出是谁的脸。 (3)下面通过样例演示如何进行人脸检测,同时检测完成后会用方框把人脸给标注出来。
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
@H_301_293@
123
124
125
126
@H_561_301@
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
]!
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
@H_404_659@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中
404_786@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