当前位置: 首页 > news >正文

探索iOS之CoreImage框架

CoreImage提供图像处理、人脸识别、图像增强、图像滤镜、图像转场。它操作的数据来自Core Graphics、Core Video、Image IO,使用CPU或GPU进行渲染。CoreImage对底层实现进行封装,为上层提供简单易用的API。

一、CoreImage框架

CoreImage框架分为:渲染层、处理层、API层。其中,渲染层包括GPU渲染(OpenGL和Metal)、CPU渲染(Grand Central Dispatch);处理层有Built-in Filters内建滤镜;API层有Core Graphics、Core Video、Image IO。如下图所示:

二、图像处理

1、图像处理流程

图像处理主要包括三个类:CIContext、CIFilter、CIImage。处理流程示例如下:

import CoreImage// 1、创建CIContext
let context = CIContext()
// 2、创建CIFilter
let filter = CIFilter(name: "CISepiaTone")!
filter.setValue(0.8, forKey: kCIInputIntensityKey)
// 3、创建CIImage
let image = CIImage(contentsOfURL: mURL)
// 4、image应用到filter滤镜
filter.setValue(image, forKey: kCIInputImageKey)
let result = filter.outputImage!
// 5、使用context创建CGImage(用于管理image以及对象复用)
let cgImage = context.createCGImage(result, from: result.extent)
// 6、显示滤镜结果
imageView.image = UIImage(CIImage: result)

2、图像数据类型

图像作为输入输出的Filter,包括数据类型如下:

图像文件的URL或图像数据的NSData;

CGImageRef、UIImage、NSBitmapImageRep对象;

Metal、OpenGl纹理;

CVImageBufferRef、CVPixelBufferRef;

跨进程共享数据的IOSurfaceRef;

内存的Bitmap数据或CIImageProvider;

3、创建Filter Chain

Filter Chain滤镜链的创建,示例代码如下:

func applyFilterChain(to image: CIImage) -> CIImage {// 创建CIFilter,并且设置color滤镜let colorFilter = CIFilter(name: "CIPhotoEffectProcess", withInputParameters:[kCIInputImageKey: image])!// 应用bloom滤镜let bloomImage = colorFilter.outputImage!.applyingFilter("CIBloom",withInputParameters: [kCIInputRadiusKey: 10.0,kCIInputIntensityKey: 1.0])// 图像裁剪let cropRect = CGRect(x: 350, y: 350, width: 150, height: 150)let croppedImage = bloomImage.cropping(to: cropRect)return croppedImage
}

4、应用滤镜到视频

以高斯模糊滤镜应用到视频为例,相关代码如下:

// 创建高斯模糊filter
let filter = CIFilter(name: "CIGaussianBlur")!
let composition = AVVideoComposition(asset: asset, applyingCIFiltersWithHandler: { request inlet source = request.sourceImage.clampingToExtent()filter.setValue(source, forKey: kCIInputImageKey)// 根据时间戳设置模糊系数let seconds = CMTimeGetSeconds(request.compositionTime)filter.setValue(seconds * 10.0, forKey: kCIInputRadiusKey)// 裁剪let output = filter.outputImage!.cropping(to: request.sourceImage.extent)// 应用滤镜结果到视频request.finish(with: output, context: nil)
})

5、使用Metal实时滤镜

首先创建Metal view用于图像渲染:

class ViewController: UIViewController, MTKViewDelegate {// Metal设备、纹理、队列var device: MTLDevice!var commandQueue: MTLCommandQueue!var sourceTexture: MTLTexture!// 高斯模糊var context: CIContext!let filter = CIFilter(name: "CIGaussianBlur")!let colorSpace = CGColorSpaceCreateDeviceRGB()override func viewDidLoad() {super.viewDidLoad()// 创建设备、命令队列device = MTLCreateSystemDefaultDevice()commandQueue = device.newCommandQueue()let view = self.view as! MTKViewview.delegate = selfview.device = deviceview.framebufferOnly = false// 创建CIContextcontext = CIContext(mtlDevice: device)}
}

实时滤镜渲染流程,示例代码如下:

public func draw(in view: MTKView) {if let currentDrawable = view.currentDrawable {let commandBuffer = commandQueue.commandBuffer()// 1、使用纹理创建UIImage,并且进行滤镜let inputImage = CIImage(mtlTexture: sourceTexture)!filter.setValue(inputImage, forKey: kCIInputImageKey)filter.setValue(20.0, forKey: kCIInputRadiusKey)// 2、使用context进行渲染context.render(filter.outputImage!,to: currentDrawable.texture,commandBuffer: commandBuffer,bounds: inputImage.extent,colorSpace: colorSpace)// 3、使用buffer显示结果commandBuffer.present(currentDrawable)commandBuffer.commit()}
}

三、人脸识别

iOS提供CIDetector进行人脸识别,示例代码如下:

// 1、创建CIContext
CIContext *context = [CIContext context];
// 2、创建options,指定识别精度
NSDictionary *opts = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh };
// 3、创建检测器,指定识别类型
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFacecontext:contextoptions:opts];
// 4、指定图像方向
opts = @{ CIDetectorImageOrientation :[[mImage properties] valueForKey:kCGImagePropertyOrientation] };
// 5、获取识别结果
NSArray *features = [detector featuresInImage:mImage options:opts];

人脸识别结果包含:左眼、右眼、嘴巴的位置,结果判断如下:

for (CIFaceFeature *f in features) {NSLog(@"%@", NSStringFromRect(f.bounds));if (f.hasLeftEyePosition) {NSLog(@"Left eye x=%g y=%g", f.leftEyePosition.x, f.leftEyePosition.y);}if (f.hasRightEyePosition) {NSLog(@"Right eye x=%g y=%g", f.rightEyePosition.x, f.rightEyePosition.y);}if (f.hasMouthPosition) {NSLog(@"Mouth x=%g y=%g", f.mouthPosition.x, f.mouthPosition.y);}
}

我们来看下人脸识别效果:

四、图像增强

iOS提供的图像增强包括:红眼矫正、脸部平衡、色彩增强、阴影突出,如下表所示:

Filter描述
CIRedEyeCorrection修复摄像头闪光引起的红眼
CIFaceBalance根据肤色调整脸部颜色
CIVibrance增强饱和度
CIToneCurve调整对比度
CIHighlightShadowAdjust调整阴影细节

图像增强的使用示例如下:

NSDictionary *options = @{ CIDetectorImageOrientation :[[image properties] valueForKey:kCGImagePropertyOrientation] };
NSArray *adjustments = [image autoAdjustmentFiltersWithOptions:options];
for (CIFilter *filter in adjustments) {[filter setValue:image forKey:kCIInputImageKey];myImage = filter.outputImage;
}

相关文章:

探索iOS之CoreImage框架

CoreImage提供图像处理、人脸识别、图像增强、图像滤镜、图像转场。它操作的数据来自Core Graphics、Core Video、Image IO,使用CPU或GPU进行渲染。CoreImage对底层实现进行封装,为上层提供简单易用的API。 一、CoreImage框架 CoreImage框架分为&#…...

qml 使用Shape 画图形

最近在做项目的时候想这实现一个能够根据相对位置动态改变大小的进度条提示框,偶尔发现了一个很有用的组件Shape这个控件里面可以画各种线条,实线虚线矩形三角形圆角的三角形或者各种自定义形状。下面提供一个2条虚线加上一个矩形的小栗子。更多的自定义形状还是请自…...

MySQL数据库修改root账户密码

博主今天登录数据库遇到了一个问题,通过这篇文章(http://t.csdn.cn/58ECT)解决了。文中关于修改root账户密码的部分,博主觉得有必要写一篇文章总结下。 第一步:用管理员账户打开CMD 第二步:开启mysql服务 …...

基于springboot+Vue+ Element-Plus+mysql实现学生宿舍管理系统

基于springbootVue Element-Plusmysql实现学生宿舍管理系统 一、系统介绍二、功能展示1.登陆2、主页--学生3、主页--宿舍管理员4.学生管理--管理员5.宿管信息--管理员6.宿舍管理--管理员7.信息管理--管理员8.申请管理--管理员9.访客管理--管理员10.水电费管理--管理员11.卫生管…...

中国人才选拔制度演变

1、世官制 是西周时人们仍保持着牢固的宗族血缘联系,人群基本以族区分,并得到宗法封建制的制度上的保证,从而自然形成了各级宗族长同时也就是各级官长,家国一体、家国同构的统治模式、格局。换句话来讲就是我们所说的世袭制。 其…...

【JavaSE】Java基础语法(十六):抽象类

文章目录 1. 抽象类的概述2. 抽象类的特点3. 抽象类的实用价值4. 抽象类的案例 1. 抽象类的概述 当我们在做子类共性功能抽取时,有些方法在父类中并没有具体的体现,这个时候就需要抽象类了! 在Java中,一个没有方法体的方法应该定义…...

【Kafka】超详细介绍

文章目录 概念部署方案磁盘网络CPUpartition的数量 命令查看版本找kafka和zookeeper的ip/porttopic创建 topic查看get topic 列表get topic 详情 修改topic修改分区级别参数(如增加partition) 删除topic设置消息大小上限 生产查看生产生产消息 查看消费server 查看 offset查看积…...

2023 华为 Datacom-HCIE 真题题库 07/12--含解析

多项选择题 1.[试题编号:190187] (多选题)如图所示的拓扑采用了VXLAN分布式网关,SW1上的VBDIF10配置了:arp-proxy local enable命令,则以下描述中正确的有哪些项? A、SW1收到PC1发往PC2的报文&…...

Spring的作用域和生命周期

目录 1.Bean的作用域 2.Bean的作用域的分类 3.设置作用域 4.Spring的执行流程(生命周期) 5.Bean的生命周期 1.Bean的作用域 lombok (dependency依赖) 是为了解决代码的冗余(比如说get和set方法)那些构造…...

岭回归有看点:正则化参数解密,显著性不再成问题!

一、概述 「L2正则化(也称为岭回归)」 是一种用于线性回归模型的正则化方法,它通过在模型的损失函数中添加一个惩罚项来防止过拟合。L2正则化的惩罚项是模型参数的平方和,乘以一个正则化参数λ,即: L2正则化…...

Android 12.0修改recovery 菜单项字体大小

1.概述 在Android 12.0进入recovery模式后,界面会g_menu_actions 菜单选项和 提示文字,而这些文字的大小不像上层一样是通过设置属性来表示大小的 而它确是通过字体png图片的大小来计算文字的宽和高的,然后可以修改字体大小 2. 修改recovery 菜单项字体大小的核心类 buil…...

【计算机网络】 7、websocket 概念、sdk、实现

文章目录 一、背景二、简介三、client3.1 ws 构造函数3.2 ws.readyState3.3 ws.onopen3.4 ws.onclose3.5 ws.onmessage3.6 ws.send3.7 ws.bufferedAmount3.8 ws.onerror 四、server4.1 go4.1.1 apifox client4.1.2 js client 五、范式 一、背景 已经有了 http 协议&#xff0c…...

python中的常见运算符

文章目录 算数运算符赋值运算关系运算符逻辑运算符非布尔值的与或非运算条件运算符(也叫三元运算符)运算符的优先级 算数运算符 加法运算符(如果两个字符串之间进行加法运算,则会进行拼串操作) - 减法运算符 * 乘法运算符(如果将字…...

TypeScript类型

TypeScript 是什么? 是以avaScript为基础构建的语言个一JavaScript的超集。可以在任何支持JavaScript的平台中执行。TypeScript扩展了JavaScript,并添加了类型。TS不能被JS解析器直接执行,需要编译成js。 基本类型 声明完变量直赴进行赋值 let c: boo…...

Integer源码

介绍 Integer是int类型的包装类,继承自Number抽象类,实现了Comparable接口。提供了一些处理int类型的方法,比如int到String类型的转换方法或String类型到int类型的转换方法,当然也包含与其他类型之间的转换方法。 Comparable提供…...

【四】设计模式~~~创建型模式~~~建造者模式(Java)

【学习难度:★★★★☆,使用频率:★★☆☆☆】 4.1. 模式动机 无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮、方向盘、发送机等各种部件…...

MarkDown的基本使用方法

为了给官方的文档知识总结:Markdown 基本语法 | Markdown 官方教程 #空格内容:‘#’表示标题的等级,越少表示标题级别越高(字越大) 在一行的末尾加两个或多个空格再回车,就是我们普通的文本回车。【还有一…...

IDEA 安装配置步骤详解

引言 IntelliJ IDEA 是一款功能强大的集成开发环境,它具有许多优势,适用于各种开发过程。本文将介绍 IDEA 的主要优势,并提供详细的安装配置步骤。 介绍 IntelliJ IDEA(以下简称 IDEA)之所以被广泛使用,…...

【网络】· 路由器中配置单臂路由和DHCP,VTP原理

目录 🍉单臂路由的工作原理 🥝交换机配置 🥝路由器配置 🍉路由器配置DHCP 🥝配置实例 🥝路由器配置 🥝验证 🍉VTP工作原理 🥝VTP模式 🥝VTP通告 &#x1f95d…...

Python 子域名扫描工具:使用多线程优化

部分数据来源:ChatGPT 本文仅用于信息安全的学习,请遵守相关法律法规,严禁用于非法途径。若观众因此作出任何危害网络安全的行为,后果自负,与本人无关。 摘要:子域名扫描是一个重要的安全工作,它可以发现目标网站的更多威胁和漏洞。本文介绍了如何使用 Python 来编写一…...

心脏数字孪生:计算建模与机器学习融合重塑精准医疗

1. 项目概述:当计算心脏遇见数据智能在心血管医学的前沿,一场静默的革命正在进行。我们不再仅仅依赖传统的临床试验和群体统计数据来理解疾病、测试药物或规划手术。取而代之的,是一个融合了计算物理学、生物学和人工智能的崭新范式&#xff…...

AI社交对话设计:如何避免商业场景中的期望违背与尴尬感

1. 项目概述:当AI的“聪明”变成商业场景的“尴尬”最近几年,AI驱动的社交对话机器人,从智能客服到虚拟销售助理,几乎成了商业互动的标配。我们总在谈论它们如何提升效率、降低成本、提供7x24小时服务。但作为一名在数字化营销和客…...

保姆级教程:在Ubuntu 20.04上从源码编译安装SUMO 1.19.0(含环境变量配置避坑指南)

从源码构建SUMO 1.19.0:Ubuntu 20.04深度编译指南与排错实战在交通仿真领域,SUMO(Simulation of Urban MObility)作为开源微观仿真工具链的核心,其源码编译安装能为研究者带来三大不可替代的优势:定制化模块…...

Unity手游Mono堆泄漏:80MB硬限下的静默崩溃真相

1. 这不是GC没跑,是Mono堆在 silently 溢出——一个被90% Unity手游团队忽视的“假稳定”现象你有没有遇到过这样的情况:游戏在编辑器里跑得飞快,Profiler显示GC调用次数极少,内存曲线平滑得像湖面;但一打包到Android真…...

洛谷 B4361:[GESP202506 四级] 排序

【题目来源】 https://www.luogu.com.cn/problem/B4361 【题目描述】 体育课上有 n 名同学排成一队,从前往后数第 i 位同学的身高为 hi,体重为 wi​。目前排成的队伍看起来参差不齐,老师希望同学们能按照身高从高到低的顺序排队,…...

Python之enc-dotenv包语法、参数和实际应用案例

Python enc-dotenv 包完整详解 enc-dotenv 是加密版 python-dotenv 核心增强包,专门解决明文存储环境变量(密钥、密码、Token) 的安全风险。它能将 .env 文件加密存储,运行时自动解密加载,彻底避免敏感配置明文泄露。 …...

跨境社媒运营真正难的 不是内容不够而是账号越来越没有“主线感”

很多团队做跨境社媒时,前期最容易把注意力放在内容数量上。 今天发没发,明天补几条,哪个平台还没铺,哪种形式最近更容易起量。 这些当然重要,因为账号在起步阶段,首先得先“动起来”。但真正做一段时间之后…...

CANN-昇腾NPU长序列训练-128K上下文怎么不OOM

Llama 3 支持 128K 上下文长度。训练时 128K 序列的 Attention 显存是 O(N):128K 128K fp16 32GB 每层,32 层 1TB。显然放不下。FlashAttention 把显存从 O(N) 降到 O(N),但在训练场景下还有额外挑战。 FlashAttention 的显存节省 标准 At…...

新手学习Linux系统的11点建议

随着Linux应用的扩展许多朋友开始接触Linux,根据学习Windwos的经验往往有一些茫然的感觉:不知从何处开始学起。这里介绍学习Linux的一些建议。一、从基础开始:常常有些朋友在Linux论坛问一些问题,不过,其中大多数的问题…...

AI大模型学习顺序_七步掌握大模型精髓:从入门到精通的进阶秘籍!

本文以“七层关系”为框架,系统地阐述了学习大模型的最佳路径。从基础概念入手,逐步深入到模型架构、训练技巧、应用场景等核心内容,旨在帮助读者构建完整的知识体系,最终实现从入门到精通的全面提升。按“七层关系”学大模型&…...