2015-04-07 15 views
7

Ich arbeite derzeit an der Implementierung eines Schwellenwertalgorithmus namens Bradley Adaptive Thresholding.Bradley adaptive Schwellenwertalgorithmus

Ich habe hauptsächlich zwei Links verfolgt, um herauszufinden, wie dieser Algorithmus implementiert werden kann. Ich war auch erfolgreich in der Lage, zwei andere Schwellenalgorithmen zu implementieren, hauptsächlich Otsu's Method und Balanced Histogram Thresholding.

Hier sind die zwei Links, die ich verfolgt habe, um den Bradley Adaptive Thresholding Algorithmus zu erstellen.

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.420.7883&rep=rep1&type=pdf

Bradley Adaptive Thresholding Github Example

ist hier der Abschnitt meines Quellcodes in Python, wo ich den Algorithmus leite und das Bild speichern. Ich benutze die Python Imaging Library und keine anderen Tools, um zu erreichen, was ich tun möchte.

def get_bradley_binary(inp_im): 
    w, h = inp_im.size 
    s, t = (w/8, 0.15) 

    int_im = Image.new('L', (w, h)) 
    out_im = Image.new('L', (w, h)) 

    for i in range(w): 
     summ = 0 
     for j in range(h): 
      index = j * w + i 

      summ += get_pixel_offs(inp_im, index) 

      if i == 0: 
       set_pixel_offs(int_im, index, summ) 
      else: 
       temp = get_pixel_offs(int_im, index - 1) + summ 
       set_pixel_offs(int_im, index, temp) 

    for i in range(w): 
     for j in range(h): 
      index = j * w + i 

      x1,x2,y1,y2 = (i-s/2, i+s/2, j-s/2, j+s/2) 

      x1 = 0 if x1 < 0 else x1 
      x2 = w - 1 if x2 >= w else x2 
      y1 = 0 if y1 < 0 else y1 
      y2 = h - 1 if y2 >= h else y2 

      count = (x2 - x1) * (y2 - y1) 

      a1 = get_pixel_offs(int_im, y2 * w + x2) 
      a2 = get_pixel_offs(int_im, y1 * w + x2) 
      a3 = get_pixel_offs(int_im, y2 * w + x1) 
      a4 = get_pixel_offs(int_im, y1 * w + x1) 

      summ = a1 - a2 - a3 + a4 

      temp = get_pixel_offs(inp_im, index) 
      if temp * count < summ * (1.0 - t): 
       set_pixel_offs(out_im, index, 0) 
      else: 
       set_pixel_offs(out_im, index, 255) 

    return out_im 

Hier ist der Teil meiner Code, der die Umsetzung dieser Satz und bekommen Methoden zeigt, dass Sie noch nie zuvor gesehen haben.

def get_offs(image, x, y): 
    return y * image.size[0] + x 

def get_xy(image, offs): 
    return (offs % image.size[0], int(offs/image.size[0])) 

def set_pixel_xy(image, x, y, data): 
    image.load()[x, y] = data 

def set_pixel_offs(image, offs, data): 
    x, y = get_xy(image, offs) 
    image.load()[x, y] = data 

def get_pixel_offs(image, offs): 
    return image.getdata()[offs] 

def get_pixel_xy(image, x, y): 
    return image.getdata()[get_offs(image, x, y)] 

Und schließlich, hier sind die Eingabe- und Ausgabebilder. Dies sind die gleichen Bilder, die in der ursprünglichen Forschungsarbeit im ersten Link, den ich Ihnen zur Verfügung gestellt habe, verwendet werden. Hinweis: Das Ausgabebild ist fast vollständig weiß, und es ist möglicherweise schwer zu erkennen, aber ich habe es trotzdem bereitgestellt, falls jemand es wirklich als Referenz haben möchte.

Input Image Output Image

+1

Was nicht funktioniert, um die richtige Ausgangsbilderzeugung? Haben Sie nicht-visuelle Tests? – Ashalynd

+0

Ja, die korrekte Ausgabe der Bilderzeugung funktioniert nicht, ich habe das exakt gleiche Bild verwendet, das die Forschungsarbeit für ihren Test benutzt, und das Ausgabebild ist komplett weiß und sieht nicht so aus wie das Ausgabebild der Forschungspapiere.Was die nicht-visuellen Tests betrifft, bin ich mir nicht sicher, was Sie meinen. –

Antwort

8

Sie nicht das Integral Bild mit PIL die Art und Weise erstellen können, dass Sie es tun, weil das Bild, das Sie Daten Verpackung in nicht-Wert über 255. Die Werte in der integralen Bild akzeptieren bekommt sehr groß weil sie die Summen der Pixel oben und links sind (siehe Seite 3 Ihres Whitepapers). Sie werden viel größer als 255, so dass Sie 32 Bits pro Pixel benötigen, um sie zu speichern.

Sie können dies testen, indem Sie ein PIL-Bild im "L" -Modus erstellen und dann ein Pixel auf 1000000 oder eine große Zahl setzen. Dann, wenn Sie den Wert zurückgelesen, wird er zurückkehren 255.

>>> from PIL import Image 
>>> img = Image.new('L', (100,100)) 
>>> img.putpixel((0,0), 100000) 
>>> print list(img.getdata())[0] 
255 

EDIT: Nach der PIL-Dokumentation zu lesen, können Sie in der Lage sein PIL zu verwenden, wenn Sie in „I“ Modus Ihr integrales Bild erstellen statt „L "Modus. Dies sollte 32 Bits pro Pixel bereitstellen.

Aus diesem Grund empfehle ich Numpy anstelle von PIL.

Unten ist eine Neuschreibung Ihrer Schwellenwertfunktion mit Numpy anstelle von PIL, und ich bekomme das richtige/erwartete Ergebnis. Beachten Sie, dass ich mein integrales Bild unter Verwendung eines uint32-Arrays erzeuge. Ich habe genau das gleiche C Beispiel auf Github, die Sie für Ihre Übersetzung verwendet:

import numpy as np 

def adaptive_thresh(input_img): 

    h, w = input_img.shape 

    S = w/8 
    s2 = S/2 
    T = 15.0 

    #integral img 
    int_img = np.zeros_like(input_img, dtype=np.uint32) 
    for col in range(w): 
     for row in range(h): 
      int_img[row,col] = input_img[0:row,0:col].sum() 

    #output img 
    out_img = np.zeros_like(input_img)  

    for col in range(w): 
     for row in range(h): 
      #SxS region 
      y0 = max(row-s2, 0) 
      y1 = min(row+s2, h-1) 
      x0 = max(col-s2, 0) 
      x1 = min(col+s2, w-1) 

      count = (y1-y0)*(x1-x0) 

      sum_ = int_img[y1, x1]-int_img[y0, x1]-int_img[y1, x0]+int_img[y0, x0] 

      if input_img[row, col]*count < sum_*(100.-T)/100.: 
       out_img[row,col] = 0 
      else: 
       out_img[row,col] = 255 

    return out_img 

output

+0

Ich brauchte eine Weile, um diese Antwort zu akzeptieren, da ich beschäftigt war, aber ja! Ich wusste nicht, dass sie Werte über 255 hinzufügen und dass das Integralbild nur eine abstrakte Darstellung von Daten ist, vielen Dank! –

Verwandte Themen