Umbral adaptativo CIKernel / CIFilter iOS

He investigado por todas partes para encontrar un kernel que realice umbrales adaptativos en iOS. Lamentablemente, no entiendo el lenguaje del kernel ni la lógica detrás de él. A continuación, he encontrado una rutina que realiza umbrales ( https://gist.github.com/xhruso00/a3f8a9c8ae7e33b8b23d )

static NSString * const kKernelSource = @"kernel vec4 thresholdKernel(sampler image)\n" "{\n" " float inputThreshold = 0.05;\n" " float pass = 1.0;\n" " float fail = 0.0;\n" " const vec4 vec_Y = vec4( 0.299, 0.587, 0.114, 0.0 );\n" " vec4 src = unpremultiply( sample(image, samplerCoord(image)) );\n" " float Y = dot( src, vec_Y );\n" " src.rgb = vec3( compare( Y - inputThreshold, fail, pass));\n" " return premultiply(src);\n" "}"; 

¿Es posible reescribir esto en un kernel de umbral adaptativo? La image que le estoy proporcionando se ha convertido en blanco y negro y ya se ha difuminado. ¿Hay algún recurso al que puedas apuntarme? Me gustaría seguir con CoreImage ya que mi stack completa está construida a su alnetworkingedor.

Editar: El mejor ejemplo / reference de lo que estoy tratando de lograr se implementó en GPUImage's GPUImageAdaptiveThresholdFilter – https://github.com/BradLarson/GPUImage/blob/c5f0914152419437869c35e29858773b1a06083c/framework/Source/GPUImageAdaptiveThresholdFilter.m

Solutions Collecting From Web of "Umbral adaptativo CIKernel / CIFilter iOS"

Simon's Filter es el enfoque correcto para lograr el efecto deseado, sin embargo, debe modificar algunas cosas.

En primer lugar, cambia el order de imageLuma y thresholdLuma , ya que queremos que las letras negras permanezcan negras y no al revés. Además, debe agregar una constante (escojo 0.01 ) para eliminar el ruido.

  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 blurnetworking = inputImage.applyingFilter("CIBoxBlur", withInputParameters: [kCIInputRadiusKey: 5]) // block size let extent = inputImage.extent let arguments = [inputImage, blurnetworking] return thresholdKernel.apply(withExtent: extent, arguments: arguments) } 

Y esto es, lo que obtienes Solo con la image principal de Apple, sin tener que instalar ninguna biblioteca externa 🙂

introduzca la descripción de la imagen aquí

Por supuesto, puedes jugar un poco con los valores de tamaño constante y de bloque.

¿Cómo se ve esto? He usado el CoreImage CIBoxBlur (aunque los filters de convolución dedicados pueden ser más rápidos) y pasé el resultado de eso a mi filter de umbral existente .

 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 blurnetworking = inputImage.imageByApplyingFilter("CIBoxBlur", withInputParameters: [kCIInputRadiusKey: 9]) let extent = inputImage.extent let arguments = [inputImage, blurnetworking] return thresholdKernel.applyWithExtent(extent, arguments: arguments) } } 

Encontré esta image de una página sombreada y con este código:

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

Tengo este resultado:

introduzca la descripción de la imagen aquí

¡Aclamaciones!

Simon