Swift-技巧(二)模糊脸部功能
摘要
本文介绍模糊脸部的功能逻辑和实现方式,实现方式会尽可能的使用苹果提供的 API,保证功能高效率和简洁。
逻辑
模糊脸部的逻辑主要有两个流程,就是先找到脸部,然后模糊脸部,那么就引申出这两个实现问题:
- 如何正确找到脸部区域?
- 如何只模糊脸部区域?
依次解决这两个问题,那么这个功能就已经轻松实现了。
实现
实现功能方式有很多,这里只是分享一下自己的实现方式。主要借鉴 Core Image 中的方法。
找脸部区域
使用 CIDetector 类来查找图片中的脸部,虽然文档中说明可以找到比如鼻子更具体的部位,但是一直没有找到实现方式,它的识别成功率相对比较高,不是百分之百。
代码逻辑归纳为:
- 通过
CIDetector类获取图片中的所有脸部区域 - 通过
CIFilter.sourceOverCompositing函数绘制出存在所有脸部区域的 mask 图
// MARK: - 获取图像中面部区域数据
func getFaceData(from image: UIImage?) -> CIImage? {
guard image != nil, let image = CIImage(image: image!) else { return nil }
// CIDetectorTypeFace
let detector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: nil)
guard let faceArray = detector?.features(in: image, options: nil) else { return nil}
var maskImage: CIImage? = nil
for face in faceArray {
let bounds = face.bounds
let centerX = bounds.origin.x + bounds.size.width * 0.4
let centerY = bounds.origin.y + bounds.size.height * 0.5
let radius = min(bounds.size.width, bounds.size.height) * 0.5
let gaussion = CIFilter.radialGradient(inputCenter: CIVector(x: centerX, y: centerY),
inputRadius0: NSNumber(value: Int(radius)),
inputRadius1: NSNumber(value: Int(radius+1)),
inputColor0: CIColor(red: 0, green: 1, blue: 0, alpha: 1),
inputColor1: CIColor(red: 0, green: 0, blue: 0, alpha: 0))
guard let gaussianImage = gaussion?.outputImage else { continue }
if maskImage == nil {
maskImage = gaussianImage
} else {
maskImage = CIFilter.sourceOverCompositing(inputImage: gaussianImage, inputBackgroundImage: maskImage!)?.outputImage
}
}
return maskImage
}
模糊脸部区域
上面步骤获取到有脸部区域的 mask 图,下面就对脸部进行模糊。这里使用 使用 CISourceOverCompositing 处理脸部模糊。
使用 blendWithMask 函数时,会发现要传入 3 张 image 对象,但是到目前只有一张原图和一张脸部的 mask 图,那么第三张图是什么呢?
这里使用的第三张图是一张将原图通过 gaussianBlur 之后的图片。然后在使用 blendWithMask 合成后获得,那么这三张图放置有什么讲究呢?下面简单总结一下:
inputImage: 放置整体被高斯模糊后的图inputBackgroundImage: 放置原图inputMaskImage: 放置获取到脸部的 mask 图
通过效果看这三张图是这样处理,inputBackgroundImage 和 inputMaskImage 组合获得到脸部区域被扣去的图片,然后在这张图下面放置 inputImage 图,就能得到脸部被高斯模糊的图片了。
// MARK: - 模糊人脸
func blurVariable(inputImage: UIImage?, maskInputImage: CIImage) -> UIImage? {
guard let image = inputImage, let ciImg = CIImage(image: image) else { return nil }
let blur = CIFilter.gaussianBlur(inputImage: ciImg, inputRadius: 8)
guard let blurImage = blur?.outputImage else { return nil}
let maskedVariableFilter = CIFilter.blendWithMask(inputImage: blurImage, inputBackgroundImage: ciImg, inputMaskImage: maskInputImage)
if let outputImg = maskedVariableFilter?.outputImage {
return UIImage(ciImage: outputImg.oriented(image.imageOrientation))
}
return nil
}
题外话
时间仓促,说的东西可能不全面,在你实现过程中遇到什么问题,评论区给我留言,我会尽快回复
Swift-技巧(二)模糊脸部功能的更多相关文章
- Eclipse用法和技巧二十八:Eclipse插件Easy Explore的今世
先说明一下easyexplore插件的功能,easyexplore是一个类似于 Windows Explorer的Eclipse插件,它可以帮助你在不退出Eclipse的环境下迅速浏览本地文件系统. ...
- Eclipse用法和技巧二十七:定义自己的快速联想词
某天在调试代码的时候,虽然是android的project还是习惯的输入syso,然后在ALT+/一下.旁边的同事就问了一下,这个log打印输出的tag是什么.接着又问了为什么syso能够智能联想出这 ...
- Eclipse使用方法和技巧二十七:定义自己的高速联想词
某天在调试代码的时候.尽管是android的project还是习惯的输入syso.然后在ALT+/一下. 旁边的同事就问了一下,这个log打印输出的tag是什么. 接着又问了为什么syso可以智能联想 ...
- SQL开发技巧(二)
本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列文章基于SQLServer系列,且版本为SQLServer2005及以上-- 文章系列目录 SQL开发技巧(一) SQL开 ...
- Android二维码功能实现,在程序内嵌入ZXing项目
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9526247 最近二维码真是越来越火了,随便电视上.网络上.商场里,到处都是二维码. ...
- FastReport 中添加二维码功能.(Delphi)
http://www.cnblogs.com/fancycloud/archive/2011/07/24/2115240.html FastReport 中添加二维码功能.(Delphi) 在实际 ...
- SQL开发技巧(二) 【转】感觉他写的很好
本文转自: http://www.cnblogs.com/marvin/p/DevelopSQLSkill_2.html 本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列 ...
- iOS开发——高级技术&二维码功能的实现
二维码功能的实现 ZBarSDK,一个比较优秀的开源项目,使用起来也很简单. ZBarSDK是一个开源的SDK,可从这里下载到源码,该SDK实现了识别和读取各种条形码,包括EAN-13/UPC-A, ...
- iOS--iOS7摄像头识别二维码功能
iOS–iOS7摄像头识别二维码功能 属性介绍: AVFoundation 框架基于以下几个类实现图像捕捉 ,通过这些类可以访问来自相机设备的原始数据并控制它的组件. AVCaptureDevice ...
随机推荐
- python matplotlib.pyplot 散点图详解(2)
python matplotlib.pyplot 散点图详解(2) 上期资料 一.散点图叠加 可以用多个scatter函数叠加散点图 代码如下: import matplotlib.pyplot as ...
- Vue3的新特性及相关的Composition API使用
首先 创建项目 Vue3 Vue3 相较于Vue2 的6大亮点: 1 性能快. 2 按需编译 体积更小 3 提供了组合API 类似于react 的React Hooks 4 更好的Ts支持 5 暴露了 ...
- 美团分布式定时调度框架XXL-Job基本使用
一:XXL JOB 基本使用 1.官方中文文档:https://www.xuxueli.com/xxl-job/ 2.基本环境: 2.1:git下载项目, 执行xxl-job数据库初始化脚本 2.2: ...
- Linux档案权限篇(一)
查看档案的属性"ls-al". 即列出所有的档案的详细权限与属性(包括隐藏文件) 权限 第一个字符代表档案的类型: d:代表是目录 -:代表是文件 l:代表是连接文件(相当于win ...
- CI框架 模糊查询,链表查询
$data = $this->db->from('flash_news') ->select('xx,xx,xx,xx') ->limit(2) ->like('tags ...
- Appium 自动化测试改造思路
流水账脚本 从头到尾编写测试脚本 PO封装 业务行为与操作具体页面元素分离 basepage封装 如封装find方法,目的时增强稳定性 数据驱动封装 将常用的数据改为配置文件 为构建测试平台打基础
- c++ 的学习 构造函数1
1. 构造函数(也叫构造器),在对象创建的时候自动调用,一般用于完成对象的初始化工作 2.一旦自定义了构造函数,必须用其中一个自定义的构造函数来初始化对象 就是有多个的话 根据参数编译器自行选 ...
- 讲师征集| .NET Conf China 2021正式启动
最近社区小伙伴们一直在为11月即将在武汉举办的 第三届.NET中国峰会而忙碌,社区活动官网设计和开发工作还在进行,我们在国庆节的前一天晚上向社区正式启动了活动的序幕,也就是我们确定好了举办地点.时间, ...
- 由于坏块导致DG的mrp0进程中断
由于坏块导致DG的mrp0进程中断1.Environment11.2.0.4 ADG 2.SymptomsDG的mrp0进程中断,重启后,还是卡住.查看alert,在1.47存在报错,进一步查看trc ...
- Sentry 监控 - Snuba 数据中台架构(Data Model 简介)
系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...