如何使用CoreImage创建平滑阈值过滤器?

约尔格

是否存在可以用作平滑阈值的过滤器?我的意思是,像素值应在两个值之间设定阈值,但要对中间值进行插值。

基本上,我正在尝试实现这一点:

https://www.filterforge.com/wiki/index.php/Thresholds#Interpolation_.28.22Blending.22.29

西蒙·格拉德曼

您需要使用Core Image Kernel Language和编写自己的语言CIColorKernel

我将使用smoothstep和传入两个边缘值以及当前像素的亮度。CIKL可能如下所示:

kernel vec4 color(__sample pixel, float inputEdgeO, float inputEdge1)
{
    float luma = dot(pixel.rgb, vec3(0.2126, 0.7152, 0.0722));
    float threshold = smoothstep(inputEdgeO, inputEdge1, luma);
    return vec4(threshold, threshold, threshold, 1.0);
}

您可以CIFilter使用以下代码将其包装到中

class SmoothThreshold: CIFilter
{
    var inputImage : CIImage?
    var inputEdgeO: CGFloat = 0.25
    var inputEdge1: CGFloat = 0.75

    var colorKernel = CIColorKernel(string:
        "kernel vec4 color(__sample pixel, float inputEdgeO, float inputEdge1)" +
        "{" +
        "    float luma = dot(pixel.rgb, vec3(0.2126, 0.7152, 0.0722));" +
        "    float threshold = smoothstep(inputEdgeO, inputEdge1, luma);" +
        "    return vec4(threshold, threshold, threshold, 1.0);" +
        "}"
    )

    override var outputImage: CIImage!
    {
        guard let inputImage = inputImage,
            colorKernel = colorKernel else
        {
            return nil
        }

        let extent = inputImage.extent
        let arguments = [inputImage,
                         inputEdgeO,
                         inputEdge1]

        return colorKernel.applyWithExtent(extent,
                                           arguments: arguments)
    }
}

请注意,您需要确保inputEdge0小于inputEdge1,否则smoothstep将会有些疯狂。您可能也想要saturate它们,以确保它们在0到1之间。

看一下CIFilter.registerFilterName哪一个可以使您创建SmoothThreshold具有熟悉语法的实例,尽管可以正常工作:

let image = CIImage(image: UIImage(named: "monalisa.jpg")!)!

let filter = SmoothThreshold()
filter.inputImage = image

let final = filter.outputImage

干杯!

西蒙

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章