Adaptive Threshold CIKernel/CIFilter iOS

后端 未结 3 1522
萌比男神i
萌比男神i 2021-02-06 07:05

I have researched all over in order to find a kernel that performs adaptive thresholding on iOS. Unfortunately I do not understand the kernel language or the logic behind it. Be

相关标签:
3条回答
  • 2021-02-06 07:25

    Simon's Filter is the right approach to achieve the desired effect, however, you have to modify a couple of things.

    First of all, switch the order of imageLuma and thresholdLuma, since we want black letters to remain black and not the other way around. Also, you should add a constant (I chose 0.01) to remove noise.

        var thresholdKernel =  CIColorKernel(string:
        "kernel vec4 thresholdFilter(__sample image, __sample threshold)" +
            "{" +
            "   float imageLuma = dot(image.rgb, vec3(0.2126, 0.7152, 0.0722));" +
            "   float thresholdLuma = dot(threshold.rgb, vec3(0.2126, 0.7152, 0.0722));" +
            "   return vec4(vec3(step(thresholdLuma, imageLuma+0.001)), 1);"     
        "}"
    
    override var outputImage: CIImage! {
        guard let inputImage = inputImage,
            let thresholdKernel = thresholdKernel else {
            return nil
        }
        let blurred = inputImage.applyingFilter("CIBoxBlur", withInputParameters: [kCIInputRadiusKey: 5]) // block size
        let extent = inputImage.extent
        let arguments = [inputImage, blurred]
        return thresholdKernel.apply(withExtent: extent, arguments: arguments)
    }
    

    And this is, what you get Only using Apple's Core Image, without having to install any external libraries :)

    Of course, you can play around a little with the values of constant and block size.

    0 讨论(0)
  • 2021-02-06 07:38

    How does this look: I've used the CoreImage CIBoxBlur (although the dedicated convolution filters may be faster) and passed the output of that into my existing threshold filter.

    class AdaptiveThresholdFilter: CIFilter
    {
        var inputImage : CIImage?
    
    
        var thresholdKernel =  CIColorKernel(string:
        "kernel vec4 thresholdFilter(__sample image, __sample threshold)" +
        "{" +
        "   float imageLuma = dot(image.rgb, vec3(0.2126, 0.7152, 0.0722));" +
        "   float thresholdLuma = dot(threshold.rgb, vec3(0.2126, 0.7152, 0.0722));" +
    
        "   return vec4(vec3(step(imageLuma, thresholdLuma)), 1.0);" +
        "}"
        )
    
    
        override var outputImage: CIImage!
        {
            guard let inputImage = inputImage,
                thresholdKernel = thresholdKernel else
            {
                return nil
            }
    
            let blurred = inputImage.imageByApplyingFilter("CIBoxBlur",
                   withInputParameters: [kCIInputRadiusKey: 9])
    
            let extent = inputImage.extent
            let arguments = [inputImage, blurred]
    
            return thresholdKernel.applyWithExtent(extent, arguments: arguments)
        }
    }
    

    I found this image of a shaded page and with this code:

    let page = CIImage(image: UIImage(named: "son1.gif")!)
    
    let filter = AdaptiveThresholdFilter()
    
    filter.inputImage = page
    
    let final = filter.outputImage
    

    I got this result:

    Cheers!

    Simon

    0 讨论(0)
  • 2021-02-06 07:41

    You can use CIColorThresholdOtsu core image filter

    0 讨论(0)
提交回复
热议问题