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

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

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

3,效果图如下
原文:Swift - 人脸检测,以及人脸打码的功能实现(附样例)


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
import  ImageIO
 
class  ViewController UIViewController  {
     
     @IBOutlet  weak  var  imageView:  UIImageView !
     
     //原图
     lazy  var  originalImage:  UIImage  = {
         return  UIImage (named:  "d1.jpg" )
         }()!
     
     lazy  var  context:  CIContext  = {
         return  CIContext (options:  nil )
         }()
 
     override  func  viewDidLoad() {
         super .viewDidLoad()
     }
     
     //恢复原图
     @IBAction  func  resetImg(sender:  AnyObject ) {
         imageView.image = originalImage
     }
     
     //检测人脸并框出
     @IBAction  func  detectFace(sender:  AnyObject ) {
         imageView.image = originalImage
         let  inputImage =  CIImage (image: originalImage)!
         //人脸检测器
         //CIDetectorAccuracyHigh:检测的精度高,但速度更慢些
         let  detector =  CIDetector (ofType:  CIDetectorTypeFace ,
             context: context,
             options: [ CIDetectorAccuracy CIDetectorAccuracyHigh ])
         var  faceFeatures: [ CIFaceFeature ]!
         //人脸检测需要图片方向(有元数据的话使用元数据,没有就调用featuresInImage)
         if  let  orientation:  AnyObject  = inputImage
             .properties[kCGImagePropertyOrientation  as  String ] {
             faceFeatures = detector.featuresInImage(inputImage,
                 options: [ CIDetectorImageOrientation : orientation])  as ! [ CIFaceFeature ]
         else  {
             faceFeatures = detector.featuresInImage(inputImage)  as ! [ CIFaceFeature ]
         }
         
         //打印所有的面部特征
         print (faceFeatures)
         
         let  inputImageSize = inputImage.extent.size
         var  transform =  CGAffineTransformIdentity
         transform =  CGAffineTransformScale (transform, 1, -1)
         transform =  CGAffineTransformTranslate (transform, 0, -inputImageSize.height)
         
         //遍历所有的面部,并框出
         for  faceFeature  in  faceFeatures {
             var  faceViewBounds =  CGRectApplyAffineTransform (faceFeature.bounds, transform)
             
             // 由于检测的原图放在imageView中缩放的原因,我们还要考虑缩放比例和x,y轴偏移
             let  scale =  min (imageView.bounds.size.width / inputImageSize.width,
                 imageView.bounds.size.height / inputImageSize.height)
             let  offsetX = (imageView.bounds.size.width - inputImageSize.width * scale) / 2
             let  offsetY = (imageView.bounds.size.height - inputImageSize.height * scale) / 2
             
             faceViewBounds =  CGRectApplyAffineTransform (faceViewBounds,
                 CGAffineTransformMakeScale (scale, scale))
             faceViewBounds.origin.x += offsetX
             faceViewBounds.origin.y += offsetY
             
             //每个人脸对应一个UIView方框
             let  faceView =  UIView (frame: faceViewBounds)
             faceView.layer.borderColor =  UIColor .orangeColor(). CGColor
             faceView.layer.borderWidth = 2
             
             imageView.addSubview(faceView)
         }
     }
     
     //检测人脸并打马赛克
     @IBAction  func  detectAndPixFace(sender:  AnyObject ) {
         // 用CIPixellate滤镜对原图先做个完全马赛克
         let  filter  CIFilter (name:  "CIPixellate" )!
         print ( filter .attributes)
         let  inputImage =  CIImage (image: originalImage)!
         filter .setValue(inputImage, forKey: kCIInputImageKey)
         let  inputScale =  max (inputImage.extent.size.width, inputImage.extent.size.height) / 80
         filter .setValue(inputScale, forKey: kCIInputScaleKey)
         let  fullPixellatedImage =  filter .outputImage
 
         // 检测人脸,并保存在faceFeatures中
         let  detector =  CIDetector (ofType:  CIDetectorTypeFace ,
             context: context,
             options:  nil )
         let  faceFeatures = detector.featuresInImage(inputImage)
         // 初始化蒙版图,并开始遍历检测到的所有人脸
         var  maskImage:  CIImage !
         for  faceFeature  in  faceFeatures {
             print (faceFeature.bounds)
             // 基于人脸的位置,为每一张脸都单独创建一个蒙版,所以要先计算出脸的中心点,对应为x、y轴坐标,
             // 再基于脸的宽度或高度给一个半径,最后用这些计算结果初始化一个CIRadialGradient滤镜
             let  centerX = faceFeature.bounds.origin.x + faceFeature.bounds.size.width / 2
             let  centerY = faceFeature.bounds.origin.y + faceFeature.bounds.size.height / 2
             let  radius =  min (faceFeature.bounds.size.width, faceFeature.bounds.size.height)
             let  radialGradient =  CIFilter (name:  "CIRadialGradient" ,
                 withInputParameters: [
                     "inputRadius0"  : radius,
                     "inputRadius1"  : radius + 1,
                     "inputColor0"  CIColor (red: 0, green: 1, blue: 0, alpha: 1),
                     "inputColor1"  CIColor (red: 0, green: 0, blue: 0, alpha: 0),
                     kCIInputCenterKey :  CIVector (x: centerX, y: centerY)
                 ])!
             print (radialGradient.attributes)
             // 由于CIRadialGradient滤镜创建的是一张无限大小的图,所以在使用之前先对它进行裁剪
             let  radialGradientOutputImage = radialGradient.outputImage!
                 .imageByCroppingToRect(inputImage.extent)
             if  maskImage ==  nil  {
                 maskImage = radialGradientOutputImage
             else  {
                 print (radialGradientOutputImage)
                 maskImage =  CIFilter (name:  "CISourceOverCompositing" ,
                     withInputParameters: [
                         kCIInputImageKey : radialGradientOutputImage,
                         kCIInputBackgroundImageKey : maskImage
                     ])!.outputImage
             }
         }
         // 用CIBlendWithMask滤镜把马赛克图、原图、蒙版图混合起来
         let  blendFilter =  CIFilter (name:  "CIBlendWithMask" )!
         blendFilter.setValue(fullPixellatedImage, forKey: kCIInputImageKey)
         blendFilter.setValue(inputImage, forKey: kCIInputBackgroundImageKey)
         blendFilter.setValue(maskImage, forKey: kCIInputMaskImageKey)
         // 输出,在界面上显示
         let  blendOutputImage = blendFilter.outputImage
         let  blendCGImage = context.createCGImage(blendOutputImage!,
             fromRect: blendOutputImage!.extent)
         imageView.image =  UIImage ( CGImage : blendCGImage)
 
     }
     
     override  func  didReceiveMemoryWarning() {
         super .didReceiveMemoryWarning()
     }
}

原文出自: www.hangge.com   转载请保留原文链接: http://www.hangge.com/blog/cache/detail_907.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值