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
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.