CIAdditionCompositing产生了错误的效果。

6

我正在尝试通过对多张图像进行平均来创建一张图像。为了实现这一目标,我首先需要将每个图像变暗一个因子,该因子等于我要平均的图像数量:

func darkenImage(by multiplier: CGFloat) -> CIImage? {
    let divImage = CIImage(color: CIColor(red: multiplier, green: multiplier, blue: multiplier))

    let divImageResized = divImage.cropped(to: self.extent) //Set multiplier image to same size as image to be darkened

    if let divFilter = CIFilter(name: "CIMultiplyBlendMode", parameters: ["inputImage":self, "inputBackgroundImage":divImageResized]) {

        return divFilter.outputImage
    }

    print("Failed to darken image")
    return nil
}

接下来,我会将每个暗淡的图像相加(将图像1和2相加,然后将结果再与图像3相加等等):

func blend(with image: CIImage, blendMode: BlendMode) -> CIImage? { 
    if let filter = CIFilter(name: blendMode.format) { //blendMode.format is CIAdditionCompositing
        filter.setDefaults()

        filter.setValue(self, forKey: "inputImage")
        filter.setValue(image, forKey: "inputBackgroundImage")

        let resultImage = filter.outputImage

        return resultImage
    }

    return nil
}

这段代码可以执行并生成新图片,但是我平均的图片越多,阴影部分就越暗。高光的亮度与每张单独图片差不多,但是暗部却变得越来越黑。有人知道可能出了什么问题吗?

原始图像: Original image

2张图片的平均值: 2x average

8张图片的平均值: 8x average

20张图片的平均值: 20x average

为了减少潜在问题,我也尝试过在Lightroom中预先调暗图像再应用CIAdditionCompositing滤镜。这给出了相同的结果,这让我认为CIAdditionCompositing可能不仅仅是简单相加像素,而是使用了一些稍微不同的算法,但我没有找到任何文档资料。我也尝试改变调暗乘数以查看是否有计算错误,但如果我将图像调暗得更少,则在再次添加图像时高光会过度曝光。


我怀疑你的暗化技术(无论是CI还是Lightroom)没有在线性颜色空间中运行。如果存在非线性伽马曲线,则将分量值乘以一个分数不会产生与该分数相同亮度的图像。因此,将它们加在一起不会产生您期望的效果。我建议使用已知颜色表示值的图像(即查看实际光栅位图值)进行各种颜色空间的测试,以解释这些值。看看乘法是否给出您期望的结果。同样,看看加法是否有用。 - Ken Thomases
1个回答

0

这可能有点晚了,但是还是要说一下。

第一次尝试

我怀疑问题在于色域不是线性的,就像Ken Thomases所提到的那样。不幸的是,将所有图像转换为使用"CISRGBToneCurveToLinear"滤镜的线性图像,并在所有图像叠加后再使用"CILinearToSRGBToneCurve"进行转换并不能解决问题。

解决方案

使用曝光调整来每次添加两张图像后减半曝光确实解决了问题。要减半曝光,您需要将光圈值降低1步,因此曝光值(EV)需要为-1。

此外,我还添加了中间图像,只是因为当CIImage中的滤镜堆栈太大时,有时会在我的旧手机上遇到麻烦。

if let evFilter = CIFilter(name: "CIExposureAdjust", parameters: ["inputImage":self, "inputEV":NSNumber(-1)]) {
    return evFilter.outputImage?.insertingIntermediate()
}

附注:请注意,为了创建正确的结果,需要将图像相互添加并减半曝光,以使每个图像对最终图像具有相同的权重。仅仅添加下一张图像并在之后减少曝光将始终使最新添加的图像对整体结果产生50%的影响。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接