-
使用 Core Image 增强 RAW 图像处理
运用 Core Image RAW 处理 API 版本 9 的强大功能,大幅提升你 App 的图像质量、增强锐度和色彩表现,同时利用 Apple 神经网络引擎来实现最优性能。借助 CIRAWFilter API,让用户能够通过更改曝光、降噪、锐度和对比度等参数来编辑 RAW 照片。探索全新的 CIImageProcessor API,通过对图块大小和缓冲区管理的精细控制进一步优化性能。
章节
- 0:00 - Introduction
- 0:52 - How Core Image supports RAW
- 2:48 - The evolution of RAW support
- 3:33 - RAW 9 overview
- 3:56 - RAW 9 quality improvements
- 5:50 - Enable and edit RAW 9 with CIRAWFilter API
- 8:33 - RAW 9 performance overview
- 9:19 - Interactive editing
- 10:52 - Exporting to other formats
- 11:50 - New CIImageProcessor features
资源
相关视频
WWDC22
WWDC21
-
搜索此视频…
大家好 我是David Hayward 很高兴向大家介绍 Core Image的增强功能 以及对RAW图像文件的支持
我将讨论四个主要话题 首先 我将回顾 相机RAW文件 在Apple平台上如何通过 Core Image获得支持 并展示iOS即将推出的 RAW质量重大改进 以及iPadOS macOS 和visionOS 27
之后 我将讨论渲染RAW时 如何获得最佳性能
最后 我将介绍相关功能 即Apple为RAW新增到 CIImageProcessor类的功能
首先简要回顾 Core Image如何支持RAW RAW文件来自 多种相机品牌和型号 但与HEIF和JPEG不同 它们在显示前 需要进行特殊处理
第一步 是解析文件的元数据 并解包RAW传感器数值 在此阶段 每个像素位置只有红色 绿色或蓝色值 以马赛克图案排列 此图像大幅裁剪放大 以便看清此图案 下一步是对传感器数据 进行去马赛克处理 使每个像素包含 红色 绿色和蓝色值
接下来的阶段 是对像素进行降噪 以消除图像中的光子噪声 读取噪声和热噪声 之后会进行卷积运算 以锐化边缘并增加局部对比度
最后一个主要步骤是 调整白平衡 曝光 色彩和色调以生成 令人满意的最终图像 所有这些步骤的算法 都内置于iOS iPadOS macOS和visionOS中 这意味着用户可以在Finder等 系统应用中查看RAW文件 预览和自由格式
任何使用Image IO API 的应用或框架 都会自动获得RAW支持
除了基本查看功能外 使用CIRAWFilter API的应用 还可以提供高级编辑控制
此API被照片 Pixelmator Pro等应用使用 以及Nitro Acorn等更多应用
早在2006年 系统仅包含21款相机型号 的手动调校校准参数 多年来这一数字 已增长至784款型号 涵盖所有主要相机厂商 甚至包括对iPhone相机 Apple Pro RAW文件的支持
但RAW的关键特性是 多年前拍摄的珍贵照片 可以使用最新的最先进算法 重新处理 Apple的RAW处理管线 已更新八次 每次都改进了去马赛克 降噪和色彩处理 一些旧版本得到了保留 这样用户如有需要 仍然可以使用
现在Apple带来了 最大的更新 RAW 9!
此版本大幅改进了 RAW文件的渲染效果 它基于一个分块CoreML模型构建 该模型将去马赛克 与降噪结合以获得最佳质量 该模型在设备上运行 利用Apple神经引擎核心 以实现最佳性能
让我近距离演示 这些改进效果
这是使用RAW 8渲染的 低噪点图像放大裁剪 Sony Alpha 7 II拍摄的这张 老式指针表盘图像效果相当不错 不过当你用RAW 9 查看同一图像时 图像更清晰 更明朗 细小文字也更易阅读
差异在高噪点图像中 更为显著 首先观察其实际RAW数据 这张ISO 51,200极高噪点 图像所包含的数据
这是Canon 5D Mark III的示例 是一盒蜡笔的10倍裁剪图 RAW数据中有大量的 亮度和色度噪声 以至于无法辨别 每支蜡笔的独特颜色 使用我们以前的算法 结果是这样的!
RAW 8较好地还原了 场景中的实际色彩 但如果检查RAW 9的结果 输出效果明显更好 色彩准确 定义清晰 蜡笔上的高光镜面 反射也清晰可见
最后这个示例是一张 刺绣毛线照片的裁剪 由Fujifilm X-T5以ISO 12,800拍摄 这台相机具有 非传统的传感器图案 对去马赛克处理颇具挑战 在RAW 8的结果中 毛线中存在一些色彩 伪影和细节丢失 但如果用RAW 9查看 同一图像 效果明显更好 小文字更清晰可读 毛线纹理也更加清晰
下面介绍如何在 应用中启用RAW 9 首先使用CIRAWFilter API 加载RAW文件 此API在WWDC 21中 已有详细介绍
但重要的是要知道 RAW 9默认未启用 你应该检查 supportedDecoderVersions属性 是否包含version9枚举值 如果包含 可通过将decoderVersion 属性设为version9来启用
要了解哪些相机型号支持RAW 9 现在有一个名为 supportedCameraModels的类方法 此API将为你的应用提供 一个包含指定版本所有 支持型号的数组 在iOS iPadOS macOS 和visionOS 27发布时 将有数百款型号 可以使用RAW 9 包括所有主要专业 相机厂商的产品 此相机列表将持续增长 通过操作系统的 无线更新进行扩充 RAW 9也自动支持 原生拍摄DNG格式的相机 例如Apple iPhone
CIRAWFilter API 真正的强大之处 在于应用修改其属性时 这允许用户自定义 RAW文件的显示方式
目前有20个经校准的 属性可以调整 在你的应用中采用这些调整 以释放RAW图像编辑的 全部功能 以下是编辑RAW时 最重要的控制参数 exposure 用于控制 图像的亮暗程度 luminanceNoiseReductionAmount 用于调整可见的 细微亮度颗粒量 sharpnessAmount 用于确定 边缘锐化的程度
以及contrastAmount 用于调整 边缘附近应用的局部对比度
这些控制参数在RAW 9中 的效果比以前版本更好
在RAW 9中 有些属性不再需要 colorNoiseReductionAmount属性 现在已无效果 因为CoreML模型会自动 处理色彩降噪
此外 detailAmount和 moireReductionAmount属性 在RAW 9中不再需要 也不再受支持
你可以调用is supported属性 检查属性是否对 过滤器实例有效
现在你已了解RAW 9的 外观和行为 接下来我想讨论它的性能 从根本上说 为了实现如此大的质量提升 RAW 9在性能和资源方面 比以前版本要求更高 尽管RAW 9对每张图像 运行CoreML模型数百次 当应用调整CIRAWFilter属性时 后续渲染仍然 快速且流畅响应
这是因为Core Image 会缓存中间结果 获得最佳性能的最佳实践 取决于应用使用RAW文件的方式 我将为两种最常见的用例 提供一些建议 首先是关于 交互式编辑用例的建议
交互式编辑 是指一个RAW文件 以屏幕分辨率多次渲染 通常是在应用调整 CIRAWFilter属性时发生 例如曝光或锐度 在对RAW进行交互式编辑时 使用CIRAWFilter的 scaleFactor属性 在以较小尺寸显示 图像时使用 这很重要 因为它减少了 渲染图像所需的工作量 这些图像的像素数 多于显示器所需
每个视图使用一个CIContext 并将cacheIntermediates设为true 缓存使得密集的CoreML工作 可以被跳过 当应用调整 CIRAWFilter属性时
Core Image将在渲染之间 使用更多内存进行缓存 如果你为应用添加 "扩展虚拟地址权限" Apple网站上有 关于此项的详细文档 此外 直接渲染到 Metal支持的视图 这可以提高重复渲染的性能 因为Metal可以在上一帧 完成之前 就开始处理下一帧 有关渲染到MTKView的 更多信息 请参阅"Display EDR content with Core Image, Metal, and SwiftUI" 来自WWDC 22
在介绍了交互式编辑 用例的建议之后 以下是导出文件时 最重要的技巧
导出用例 是指多个RAW文件各自 以全分辨率渲染一次 转换为HEIF或JPEG等格式
此用例的最佳实践是 使用CIContext进行导出 并将cacheIntermediates 选项设为false
此外 你可以告知Core Image 在每次导出期间使用更多内存 通过设置Context的 memoryLimit选项 在iOS上 默认限制是 保守的256兆字节 将限制设为512或1024兆字节 可以显著提高性能
你还可以通过使用 Context方法来节省额外内存 使用heifRepresentation 或jpegRepresentation代替Image IO 在最后一节 我想介绍对 CIImageProcessor API的改进
RAW 9使用了CIImageProcessor API 因为它支持将CoreML 与其他CIKernels结合使用的算法
由于这一工作 Core Image团队新增了两个功能 到CIImageProcessor API中 你可能希望在应用中使用 首先介绍的是对 显式输出分块大小的支持
这是一个典型的 CIImageProcessor类示例 它实现了感兴趣区域回调 该回调定义了对于给定输出 矩形需要多少输入
最重要的是在处理回调中 你必须注意input.region 和output.region 即处理器应操作的区域 如果内存充足 CoreImage将调用处理函数 其output.region为整个图像 但当内存有限时 output.region可能 会小很多
现在 处理器可以明确 控制输出分块大小 处理器类中的代码 与以前保持不变 但你要告知CoreImage 使用你选择的输出区域
首先创建一个数组 然后在数组中填入 覆盖图像的所有所需分块 在此示例中 分块策略 获取输入图像的范围 并将其分割为 512x512像素的分块 当你创建使用 该处理器的图像时 调用其apply方法并传入 覆盖图像的分块数组
既然我已介绍了 显式输出分块大小 最后一个话题 是临时缓冲区功能
调用CoreML的CIImageProcessor 通常会使用临时缓冲区 这是因为CoreImage 使用交错图像缓冲区 必须将其转换为 CoreML所需的平面数据 当对许多分块调用 处理器回调时 临时缓冲区将被 反复创建和销毁 这会影响性能 CIImageProcessorOutput类 现在提供了一些辅助方法 以下是具体工作原理!
这是一个简单的 CIImageProcessor类示例 使用了临时缓冲区功能 它不是直接从输入处理到输出 此回调请求一个暂存缓冲区 通过向输出对象 请求临时CVPixelBuffer
执行此操作时 提供一个标识符 这对于使用多个临时缓冲区 的处理回调至关重要
然后 此示例处理器 从输入像素缓冲区复制 到临时缓冲区 就地修改临时缓冲区的像素 最后将其复制到输出 Core Image将为你管理 临时缓冲区的生命周期 它们将被自动释放 并在正确的时间释放 并在处理器为下一个 分块调用时进行回收 以下是要点总结 在应用中试用RAW 9 这是一项重大质量提升 只需几行代码即可启用
遵循性能最佳实践 我为快速导出和 流畅编辑所概述的
为应用提供CIRAWFilter 强大编辑属性的访问权限 让用户能够精细调整 RAW图像的显示效果 最后 要在CIImageProcessor中 实现最佳性能 请使用显式分块和 临时缓冲区API 就我个人而言 我很享受重新整理我的照片库 里面有超过7000张RAW格式 家庭照片 跨越了20年 看到降噪效果的显著改善 真的很棒 我认为使用你的应用的用户 也会喜欢这些改进 感谢观看!
-
-
11:08 - Contact for exports
let exportCtx = CIContext(options : [ .cacheIntermediate : false, .memoryLimit : 512 ]) -
12:23 - CIImageProcessor with explicit output tile sizes
import CoreImage class MyProcessor: CIImageProcessorKernel { override class func roi(forInput input: Int32, arguments: [String : Any]?, outputRect: CGRect) -> CGRect { return outputRect } override class func process(with inputs: [CIImageProcessorInput]?, arguments: [String : Any]?, output: CIImageProcessorOutput) throws { guard let input = inputs?.first, let iBuffer = input.pixelBuffer, let oBuffer = output.pixelBuffer else { return } let iRegion = input.region let oRegion = output.region // controlled by Core Image // MyCopyBuffer(iBuffer,iRegion, oBuffer,oRegion) } } let extent = inImg.extent let tileSize = 512.0 // whatever tile size you want var tiles: [CIVector] = [] for y in stride(from: extent.minY, to: extent.maxY, by: tileSize) { for x in stride(from: extent.minX, to: extent.maxX, by: tileSize) { let tile = CGRect(x: x, y: y, width: min(tileSize, extent.maxX - x), height: min(tileSize, extent.maxY - y)) tiles.append(CIVector(cgRect: tile)) } } let result = try MyProcessor.apply(withTiledExtent: tiles, inputs: [inImg], arguments: [:]) -
14:24 - CIImageProcessor using temporary PixelBuffer
import CoreImage class MyProcessor: CIImageProcessorKernel { override class func process(with inputs: [CIImageProcessorInput]?, arguments: [String: Any]?, output: CIImageProcessorOutput) throws { guard let input = inputs?.first, let srcPixelBuffer = input.pixelBuffer, let dstPixelBuffer = output.pixelBuffer else { return } // Get a scratch buffer from Core Image's cache guard let scratch = output.temporaryPixelBuffer(identifier : "myScratch", format: kCVPixelFormatType_64RGBAHalf, width: Int(output.region.width), height: Int(output.region.height), pixelBufferAttributes: nil) else { return } // Step 1: copy input CVPixelBuffer → scratch // Step 2: process pixels in scratch // Step 3: copy scratch → output CVPixelBuffer } }
-
-
- 0:00 - Introduction
Enhancements to Core Image and its support for RAW image files across Apple platforms.
- 0:52 - How Core Image supports RAW
An overview of the RAW processing stages, including demosaic, denoising, convolution, and color adjustments, and their support in Apple's operating systems and developer frameworks.
- 2:48 - The evolution of RAW support
A look at how Apple's RAW processing pipeline has evolved across nine versions, now supporting 784 camera models.
- 3:33 - RAW 9 overview
Explore the new RAW 9 processing pipeline, which leverages a Core ML model to significantly improve demosaic and denoise for the highest image quality.
- 3:56 - RAW 9 quality improvements
A side-by-side comparison of RAW 8 and RAW 9 demonstrating significant improvements in sharpness, color accuracy, and noise reduction.
- 5:50 - Enable and edit RAW 9 with CIRAWFilter API
How to opt in to RAW 9 using CIRAWFilter's decoderVersion property, check which camera models are supported, and use the CIRAWFilter editing properties to give people full control over how their RAW images appear.
- 8:33 - RAW 9 performance overview
Best practices for optimizing performance when using RAW 9.
- 9:19 - Interactive editing
Best practices for rendering a RAW file repeatedly at screen resolution, including using the scaleFactor property, enabling cacheIntermediates, the Extended Virtual Addressing entitlement, and rendering to Metal-backed MTKViews.
- 10:52 - Exporting to other formats
Best practices for exporting multiple RAW files to HEIF or JPEG at full resolution, including disabling cacheIntermediates, tuning the memoryLimit option, and using Core Image's heifRepresentation and jpegRepresentation methods.
- 11:50 - New CIImageProcessor features
Discover new API features added to CIImageProcessor, including explicit output tile sizes and temporary buffers.