2016-03-23 5 views
6

Ich habe überall recherchiert, um einen Kernel zu finden, der adaptive Thresholding auf iOS durchführt. Leider verstehe ich die Kernelsprache oder die Logik dahinter nicht. Im Folgenden habe ich eine Routine gefunden haben, die Schwellwertoperation (https://gist.github.com/xhruso00/a3f8a9c8ae7e33b8b23d)Adaptive Schwelle CIKernel/CIFilter iOS

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" 
"}"; 

Ist es möglich, neu zu schreiben, diese in eine adaptive Schwellwertbildung Kernel führt? Das Bild, das ich ihm zuführe, wurde in B & W umgewandelt und ist bereits unscharf geworden. Gibt es irgendwelche Ressourcen, auf die Sie mich hinweisen könnten? Ich würde gerne bei CoreImage bleiben, da mein gesamter Stack darauf aufgebaut ist.

Edit: Das beste Beispiel/Referenz aus, was ich versuche in GPUImage die umgesetzt wurde GPUImageAdaptiveThresholdFilter zu erreichen - https://github.com/BradLarson/GPUImage/blob/c5f0914152419437869c35e29858773b1a06083c/framework/Source/GPUImageAdaptiveThresholdFilter.m

Antwort

2

Simons Filter ist der richtige Ansatz, um die gewünschte Wirkung zu erzielen, jedoch müssen Sie ein paar Dinge ändern.

Schalten Sie zuerst die Reihenfolge imageLuma und thresholdLuma, da wir schwarze Buchstaben schwarz bleiben wollen und nicht umgekehrt. Außerdem sollten Sie eine Konstante hinzufügen (ich wählte 0.01), um Rauschen zu entfernen.

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) 
} 

Und das ist, was Sie nur Apples Core Image bekommen verwenden, ohne externe Bibliotheken zu installieren :)

enter image description here

Natürlich können Sie sich ein wenig mit den Werten spielen von konstanter und Blockgröße.

+0

Pascal, ich danke Ihnen für Ihre Antwort. Irgendeine Idee, wie Sie dies auch in CoreImage implementieren können? https://github.com/ctodobom/OpenNoteScanner/blob/master/app/src/main/java/com/todobom/opennotescanner/ImageProcessor.java#L409 – mmackh

+0

Sie erwähnten eine Konstante von 0,01, aber Sie haben 0,001, ist dies ein Fehler? Auch wenden Sie diese Konstante auf die imageLuma oder die Schwelle Luma an (vorausgesetzt, ich wollte weiße Buchstaben mit schwarzem Hintergrund. – Pochi

+0

0,01 und 0,001 scheint nicht zu viel Unterschied zu machen. Sie können verschiedene Werte versuchen, um Ihre Bedürfnisse zu erfüllen . – triiiiista

4

Wie diese aussehen tut: ich die Coreimage CIBoxBlur verwendet haben (obwohl die dedizierten Faltungsfilter kann sei schneller) und übertrage die Ausgabe davon in meine 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) 
    } 
} 

fand ich this image einer schattigen Seite und mit diesem Code:

let page = CIImage(image: UIImage(named: "son1.gif")!) 

let filter = AdaptiveThresholdFilter() 

filter.inputImage = page 

let final = filter.outputImage 

Ich habe dieses Ergebnis:

enter image description here

Prost!

Simon

+0

Vielen Dank für den Einstieg. Ich war auf der Suche nach etwas mehr im Sinne von http://homepages.inf.ed.ac.uk/rbf/HIPR2/images/son1adp2.gif jedoch – mmackh