2012-03-26 7 views
0

Ich versuche, die Niblack Schwellwertbildung Algorithmus zu implementieren, die die Formel verwendet:Niblack Schwellwertbildung

pixel = (pixel > mean + k * standard_deviation) ? object : background 

wobei k hat Standardwert 0. Könnte mir bitte jemand sagen, wie dies in Matlab implementieren? Ich kann nicht herausfinden, wie es zu tun

Antwort

4

Die Macht des Matlab ist Matrix-Operationen, so dass Sie tun können, viel ohne eine einzige Schleife. Der Code unten tut, was Sie brauchen.

% define parameters 
imgname = 'rice.png'; % matlab's image 
filt_radius = 25; % filter radius [pixels] 
k_threshold = 0.2; % std threshold parameter 
%% load the image 
X = double(imread(imgname)); 
X = X/max(X(:)); % normalyze to [0, 1] range 
%% build filter 
fgrid = -filt_radius : filt_radius; 
[x, y] = meshgrid(fgrid); 
filt = sqrt(x .^ 2 + y .^ 2) <= filt_radius; 
filt = filt/sum(filt(:)); 
%% calculate mean, and std 
local_mean = imfilter(X, filt, 'symmetric'); 
local_std = sqrt(imfilter(X .^ 2, filt, 'symmetric')); 
%% calculate binary image 
X_bin = X >= (local_mean + k_threshold * local_std); 
%% plot 
figure; ax = zeros(4,1); 
ax(1) = subplot(2,2,1); imshow(X); title('original image'); 
ax(2) = subplot(2,2,2); imshow(X_bin); title('binary image'); 
ax(3) = subplot(2,2,3); imshow(local_mean); title('local mean'); 
ax(4) = subplot(2,2,4); imshow(local_std); title('local std'); 
linkaxes(ax, 'xy'); 

enter image description here

+0

Sind Sie sicher über das Bild für lokale Std? Ich habe versucht, meine eigene Implementierung in Java mit dem von Ihnen bereitgestellten Graustufenbild zu testen, und die Ergebnisse sind ziemlich unterschiedlich. Es sieht so aus, als ob unser Standard der gleiche ist wie der Mittelwert? – user2700896

0

Sie können das ganze Bild verarbeiten: Sie haben drei Matrizen Unter der Annahme: img_in, Objekt, Hintergrund

flag = img_in > mean + k * standard_deviation; 
img_out = flag .* object + (1 - flag) .* background; 
+0

Wie berechne ich die Standardabweichung ??? – NeedHelp

+0

Es ist sehr unklar von Ihrer Beschreibung, was Sie vorhaben zu tun. Bitte geben Sie Ihre Eingabe und die gewünschte Ausgabe an. – Serg

+0

Ich nehme ein Dokumentabbild und nach der Konvertierung in Graustufen versuche ich diesen Schwellwertalgorithmus zu implementieren. Aber ich weiß nicht, wie man es zu jedem Pixel einzeln implementiert, so dass das Endergebnis ein binarisiertes Bild ist, in dem der Text vom Hintergrund getrennt wird. Können Sie mir bitte sagen, wie das geht? – NeedHelp

2

Ich möchte im Voraus sagen, dass es nicht Niblack-Algorithmus ist, sondern eine Implementierung, die besseres Ergebnis gibt. Ich weiß nicht, wo diese Implementierung fehlschlägt, aber ich habe versucht, das obige Bild zu binarisieren und das Ergebnis ist wie folgt.

Binarized grains

teilte ich das Bild in 25 * 25 Pixel-Block und verwendet dann einen globalen Satz Mittelwert von 90 und globalen Satz Mittelwert von 20. Und dann Otsu des Digitalisierungs auf kleine Fenster angewendet.

set_mean = 90 
set_sd = 20 
mean_block = np.mean(block) 
sd_block = np.std(block) 
if sd_block > set_sd: 
    ret, block = cv2.threshold(block, 0, 255, cv2.THRESH_OTSU) 
elif sd_block < set_sd: 
    if mean_block > set_mean: 
     block[:] = 255 #white 
    else: 
     block[:] = 0 #black 
return block 

Wenn die Standardabweichung des kleinen Fensters (SD) größer ist als der Satz ein, dann otsu die Schwellwertbildung verwendet wird, sonst basierend auf, ob der Mittelwert größer oder kleiner als Satz bedeuten, werden die Pixel in dem Fenster gesetzt um schwarz oder weiß zu vervollständigen.

+0

Es wäre sehr praktisch, auch den Code zu integrieren, der das größere Bild in Blöcke aufteilt. Könntest du das bitte hinzufügen? –

+0

Hier ist ein [Link] (https://github.com/tilaprimera/scanned_images_binarization/blob/master/helper_function.py) Siehe die Funktion img_divide zum Teilen des Bildes. Es ist kein effizienter Code, ich muss hinzufügen. – tilaprimera