-
Core Image를 사용하여 RAW 이미지 처리 향상하기
Core Image RAW 처리 API 버전 9의 강력한 기능을 활용하여 향상된 선명도와 더 뚜렷한 색상으로 앱의 이미지 품질을 크게 높이는 동시에, Apple Neural Engine으로 최적 성능을 구현하세요. CIRAWFilter API를 활용하여 사용자가 노출, 노이즈 감소, 선명도, 대비 등을 변경해 RAW 사진을 편집할 수 있도록 해 보세요. 또한 새로운 CIImageProcessor API를 살펴보세요. 이 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이 CIImageProcessor 클래스에 추가한 RAW 기능을 소개하겠습니다
Core Image의 RAW 지원에 대해 간략히 요약해 드리겠습니다 RAW 파일은 다양한 카메라 메이커와 모델에서 만들어지지만 HEIF나 JPEG와 달리 표시하기 전에 특별한 처리가 필요합니다
첫 번째 단계는 파일의 메타데이터를 파싱하는 것입니다 그리고 RAW 센서 값을 언팩합니다 이 단계에서 각 픽셀 위치에는 빨간색만 있거나 녹색 또는 파란색 값이 모자이크 패턴으로 배열됩니다 이 패턴이 보이도록 이미지를 크게 확대했습니다 다음 단계는 센서 데이터를 디모자이크하여 각 픽셀에 빨간색, 녹색, 파란색 값을 포함시킵니다
그 다음 단계는 픽셀을 노이즈 제거하여 광자 노이즈, 읽기 노이즈, 열 노이즈를 없애는 것입니다 이후 컨볼루션이 적용됩니다 윤곽을 선명하게 하고 로컬 대비를 추가합니다
마지막 주요 단계는 화이트 밸런스, 노출을 조정하고 색상과 톤을 조절하여 보기 좋은 최종 이미지를 만드는 것입니다 이 모든 단계의 알고리즘은 iOS에 내장되어 있습니다 iPadOS, macOS, visionOS도 마찬가지입니다 덕분에 Finder 같은 시스템 앱에서 RAW 파일을 볼 수 있습니다 Preview와 Freeform도 포함됩니다
Image IO API를 사용하는 앱이나 프레임워크라면 자동으로 RAW 지원을 받습니다
기본 보기 외에도 CIRAWFilter API를 사용하는 앱에서는 고급 편집 컨트롤을 제공할 수 있습니다
이 API는 Photos, Pixelmator Pro 같은 앱에서 사용됩니다 Nitro, Acorn 등 많은 앱도 포함됩니다
2006년에 시작하여 21개 카메라 모델에 대한 수동 조정 캘리브레이션이 포함되었습니다 그 이후로 784개 모델로 늘어났습니다 모든 주요 카메라 제조사를 포함합니다 iPhone 카메라의 Apple Pro RAW 파일도 지원합니다
RAW의 핵심 기능은 수년 전에 찍은 소중한 사진을 최신 알고리즘으로 재처리할 수 있다는 점입니다 Apple의 RAW 처리 파이프라인은 여덟 번 업데이트되었습니다 매번 디모자이크, 노이즈 제거, 색상이 개선되었습니다 일부 이전 버전은 유지되었습니다 원하는 경우 계속 사용할 수 있습니다
이제 Apple이 가장 큰 업데이트인 RAW 9를 내놓았습니다!
이 버전은 RAW 파일 렌더링을 크게 향상시킵니다 타일 기반 CoreML 모델 위에 구축되었으며 최고의 품질을 위해 디모자이크와 노이즈 제거를 결합합니다 이 모델은 Apple Neural Engine 코어로 기기에서 실행됩니다 최적의 성능을 위해서입니다
가까이서 개선 사항을 시연해 보겠습니다
이것은 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 파일을 로드하세요 WWDC 21의 "Capture and process ProRAW images"에 잘 설명되어 있습니다
하지만 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는 렌더링 사이의 캐싱을 위해 더 많은 메모리를 사용합니다 "Extended Virtual Addressing entitlement"를 앱에 추가하면 됩니다 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를 사용합니다 다른 CIKernel과 함께 CoreML을 사용하는 알고리즘을 활성화하기 때문입니다
이 작업의 결과로 Core Image 팀이 두 가지 기능을 추가했습니다 CIImageProcessor API에 앱에서 사용할 수 있는 기능입니다 첫 번째는 명시적 출력 타일 크기 지원입니다
전형적인 CIImageProcessor 클래스의 예입니다 region of interest 콜백을 구현합니다 주어진 출력 사각형에 필요한 입력의 양을 정의합니다
가장 중요한 것은 process 콜백 내에서 input.region과 output.region을 반드시 인식해야 합니다 프로세서가 처리해야 하는 영역입니다 메모리가 충분하다면 CoreImage는 process 함수를 호출합니다 전체 이미지에 대한 output.region으로 호출됩니다 하지만 메모리가 제한될 때는 output.region이 상당히 작아질 수 있습니다
이제 프로세서가 출력 타일 크기를 명시적으로 제어할 수 있습니다 프로세서 클래스의 코드는 이전과 동일합니다 하지만 원하는 출력 영역을 사용하도록 CoreImage에 지시합니다
먼저 배열을 생성하세요 그런 다음 이미지를 덮을 원하는 타일로 배열을 채웁니다 이 예에서 타일링 전략은 입력 이미지 범위를 가져옵니다 512x512 픽셀 타일로 분할합니다 프로세서를 사용하는 이미지를 만들 때는 apply 메서드를 호출하고 이미지를 덮는 타일 배열을 전달하세요
명시적 출력 타일 크기에 대해 설명했으니 마지막 주제는 임시 버퍼 기능입니다
CoreML을 호출하는 CIImageProcessor에서 임시 버퍼를 사용하는 것은 일반적입니다 CoreImage가 인터리브된 이미지 버퍼를 사용하기 때문입니다 CoreML을 위해 플레이너 데이터로 변환해야 합니다 프로세서 콜백이 여러 타일에 대해 호출되면 임시 버퍼가 반복적으로 생성되고 소멸됩니다 이는 성능에 영향을 줄 수 있습니다 CIImageProcessorOutput 클래스에 이제 도움이 되는 메서드가 있습니다 작동 방식은 다음과 같습니다!
간단한 CIImageProcessor 클래스의 예입니다 임시 버퍼 기능을 사용합니다 입력에서 출력으로 직접 처리하는 대신 이 콜백은 스크래치 버퍼를 요청합니다 출력 객체에 임시 CVPixelBuffer를 요청하여 얻습니다
이때 식별자를 제공하세요 두 개 이상의 임시 버퍼를 사용하는 process 콜백에 매우 중요합니다
그런 다음 이 예시 프로세서는 입력 픽셀 버퍼에서 임시 버퍼로 복사합니다 임시 버퍼 픽셀을 제자리에서 변경하고 최종적으로 출력에 복사합니다 Core Image가 임시 버퍼의 수명 주기를 관리해 드립니다 올바른 시점에 자동으로 해제됩니다 다음 타일에 대해 프로세서가 호출될 때 재활용됩니다 핵심 내용을 정리해 드리겠습니다 앱에서 RAW 9를 사용해 보세요 주요 품질 개선이며 몇 줄의 코드만으로 활성화할 수 있습니다
성능 모범 사례를 따르세요 빠른 내보내기와 반응적인 편집을 위해 설명한 내용입니다
앱에서 CIRAWFilter의 강력한 편집 속성을 활용하세요 RAW 이미지의 표시 방식을 세밀하게 조정할 수 있습니다 마지막으로 CIImageProcessor의 최적 성능을 위해 명시적 타일링 및 임시 버퍼 API를 사용하세요 저는 개인적으로 제 사진 라이브러리를 다시 살펴보는 것을 즐겼습니다 지난 20년간 RAW로 촬영한 7000장 이상의 가족 사진입니다 향상된 노이즈 감소 품질을 보니 정말 좋았습니다 앱을 사용하시는 분들도 이 개선 사항을 즐기실 것으로 생각합니다 시청해 주셔서 감사합니다!
-
-
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.