Core Image 滤镜实践
最近因为项目需求,接触了Core Image,实现了实时抠图,人脸贴纸。
决定把这次实践分享给大家,作为对开源社区的回馈。
相关代码上传在 GitHub
Core Image 介绍
以下是苹果官方文档给出 Core Image 的介绍:
Core Image is an image processing and analysis technology designed to provide near real-time processing for still and video images. It operates on image data types from the Core Graphics, Core Video, and Image I/O frameworks, using either a GPU or CPU rendering path. Core Image hides the details of low-level graphics processing by providing an easy-to-use application programming interface (API). You don’t need to know the details of OpenGL, OpenGL ES, or Metal to leverage the power of the GPU, nor do you need to know anything about Grand Central Dispatch (GCD) to get the benefit of multicore processing. Core Image handles the details for you.
翻译过来的大意是:
Core Image 是一个被设计用来给图片和视频提供实时的图像处理和分析技术.它可以使用 GPU 或 CPU 渲染,操作来自 Core Graphics, Core Video,以及Image I/O 框架的图片数据类型. Core Image 隐藏了底层图形处理的细节,提供简单易用的应用程序 API 接口.你不需要知道关于OpenGL, OpenGL ES,或者 Metal 的细节来利用 GPU 的能力,也不需要你知道任何关于 GCD 的知识来进行多线程处理的优化。
CIFilter
CIFilter,是用来表示 Core Image 的各种滤镜。通过提供对应的键值对,来设置滤镜的输入参数。这些值设置好,CIFilter就可以用来生成新的CIImage输出图像。
CIImage
CIImage 是 Core Image 框架中最基本代表图像的对象。可以通过以下几种方式来创建 CIImage:
1 | //通过 NSURL 创建 |
CIContext
所有Core Image的处理流程都通过 CIContext 来进行。
CIContext 可以是基于 CPU 的,也可以是基于 GPU 的,这两种渲染的区别是:
- CPU 渲染方式会采用 GCD 多线程来对图像进行渲染,这保证了 CPU 渲染在大部分情况下更可靠,他可以在后台实现渲染过程
- GPU 渲染方式可以使用 OpenGLES 或者 Metal 来渲染图像,这种方式 CPU 完全无负担,应用程序的运行循环不会受到图像渲染的影响,而且他渲染比 CPU 渲染更快。缺点是 GPU 渲染无法在后台运行。
1 | //创建基于 GPU 的 CIContext 对象 |
一般采用第一种基于GPU的,因为效率要比CPU高很多.
基础滤镜使用
你可以这样来使用它
1 | //将UIImage转换成CIImage |
滤镜链
滤镜链的使用也非常简单,将滤镜A的输出图像,当作滤镜B的输入图像,就可以把滤镜效果叠加起来。
如:
1 | //得到要处理的图片 |
实时滤镜
由于视频本身是由一帧帧的图像组成的,所以我们在添加滤镜的时候,只要处理每一帧的图片就好了。
所以在 AVCaptureVideoDataOutputSampleBufferDelegate
对应的方法里做处理就ok了:
1 | -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { |
人脸检测
Core Image 已经提供了 CIDetector 来做特征检测,里面包含了 CIDetectorTypeFace 的特征类型来做人脸识别。并且它已被优化过,使用起来也很容易。
1 | //创建一个CIDetector对象 |
数组 faces 中保存着 CIFaceFeature 类的实例。通过CIFaceFeature 的实例,不仅可以得到脸部的位置信息,也可以知道眼睛和嘴巴的位置。
1 |
|
在这里需要注意的是,Core Image 和 UIKit 使用了不同的坐标系: Core Image 是以左下角作为原点,UIKit 是以左上角为原点。需要用 仿射变换 将 Core Image 坐标转换成了 UIKit 坐标。
参考资料: