-
[swift] Chroma key filterSwift 개발 2021. 4. 30. 14:53
Overview
- chroma key 효과는 greenscreening이나 bluescreening으로도 알려져 있는데, 투명하게 만들 색상을 정해서 target image에서 해당 색상 부분의 alpha value를 0으로 변경하고 background image와 합치는 것을 의미한다.
- 과정 (filter 두번 먹여주면 끝이다!!!!)
- Cube map 생성 : CIColorCube filter를 생성해서 투명하게 설정할 대상이 되는 색상을 결정한다
- CIColorFilter 적용 : source image의 모든 pixel에 대해서 CIColorCube filter를 적용한다
- source + background : CISourceOverCompositing filter를 사용해서 source와 background image를 합친다
Step1. Create a Cube Map
- Color cube란?
- RGB 색상에 투명도를 할당하는 3D color-loopup table이다
- 예를 들어 위의 사진처럼 input image에서 녹색을 제거하기 위해서, 녹색 부분에 대해 value를 0으로 설정하는 custom color cube를 생성하면 된다.
- HSC (hue-saturation-brightness) representation
- 특정한 색상의 범주를 정하기 위해서 HSV 표현법으로 모델링 한다.
- HSV는 hue(색상)을 각도로 나타내는데, screening color에 해당하는 영역에 대한 lookup table value를 0으로 설정하면 된다.
- 녹색에 해당하는 영역은 108도~144도로, greenscreening을 위해서는 color cube에서 이 범위에 투명도 값을 0으로 설정하면 된다.
func chromaKeyFilter(fromHue: CGFloat, toHue: CGFloat) -> CIFilter? { // 1. 3차원 Memory 할당해주기 (각 element는 RGBA로 구성됨) let size = 64 var cubeRGB = [Float]() // 2. RGB color combinatoin 만들기 for z in 0 ..< size { let blue = CGFloat(z) / CGFloat(size-1) for y in 0 ..< size { let green = CGFloat(y) / CGFloat(size-1) for x in 0 ..< size { let red = CGFloat(x) / CGFloat(size-1) // 3. RGB를 HSV로 변환하기. (getHue 함수를 활용) let hue = getHue(red: red, green: green, blue: blue) // green 영역에 해당하는 hue의 transparency 설정하기 (108~144) let alpha: CGFloat = (hue >= fromHue && hue <= toHue) ? 0: 1 // 4. CIColorCube filter는 미리 alpah value와 곱해져 있어야함 // (그래서 transparency 포함한 lookup table)이라고 함) cubeRGB.append(Float(red * alpha)) cubeRGB.append(Float(green * alpha)) cubeRGB.append(Float(blue * alpha)) cubeRGB.append(Float(alpha)) } } } let data = Data(buffer: UnsafeBufferPointer(start: &cubeRGB, count: cubeRGB.count)) // 5. cube data로부터 Color image filter 생성하기 let colorCubeFilter = CIFilter(name: "CIColorCube", withInputParameters: ["inputCubeDimension": size, "inputCubeData": data]) return colorCubeFilter }
// RGB representation -> HSV representation 을 위한 함수 func getHue(red: CGFloat, green: CGFloat, blue: CGFloat) -> CGFloat { let color = UIColor(red: red, green: green, blue: blue, alpha: 1) var hue: CGFloat = 0 color.getHue(&hue, saturation: nil, brightness: nil, alpha: nil) return hue }
Step2. Remove Green from the Source Image
- source image에 step1에서 생성한 colorCubeFilter를 먹여서 모든 green pixel이 투명해진 output image를 얻는다.
- 이때 108도가 0.3에 해당하고 144도가 0.4에 해당한다고 한다. (왜인지는 잘 모르겠다)
let chromaCIFilter = self.chromaKeyFilter(fromHue: 0.3, toHue: 0.4) chromaCIFilter?.setValue(foregroundCIImage, forKey: kCIInputImageKey) let sourceCIImageWithoutBackground = chromaCIFilter?.outputImage
Step3. Composite over a Background Image
- step2의 결과로 얻은 output image에 CISourceOverCompositing filter를 먹여서 background image를 greenscreened output image와 합성한다.
let compositor = CIFilter(name:"CISourceOverCompositing") compositor?.setValue(sourceCIImageWithoutBackground, forKey: kCIInputImageKey) compositor?.setValue(backgroundCIImage, forKey: kCIInputBackgroundImageKey) let compositedCIImage = compositor?.outputImage
참고 사이트 : developer.apple.com/documentation/coreimage/applying_a_chroma_key_effect
Apple Developer Documentation
developer.apple.com
'Swift 개발' 카테고리의 다른 글
CoreML overview 정리 (0) 2020.10.30 [swift] 3탄 : Button Object 선언해서 click action 취하기 (0) 2020.07.12 [swift] 2탄 : AutoLayout UI 그리기 (0) 2020.07.12 [swift] 1탄 : xcode로 프로젝트 만들기 (0) 2020.07.11