Hallo, ich bin Ramu. Wir werden die Binärisierung von Otsu (Diskriminierungsanalysemethode) implementieren, eine Methode zur automatischen Bestimmung des für die Binärisierung verwendeten Schwellenwerts.
Bei der Binarisierung wird ein Bild in ein monochromes Bild mit nur zwei Farben umgewandelt: Schwarz und Weiß. Ersetzen Sie nach dem Bestimmen des Schwellenwerts die Pixelwerte unterhalb des Schwellenwerts durch Weiß und die Pixel durch Pixelwerte oberhalb des Schwellenwerts durch Schwarz. Bisher habe ich in der vorherigen Binarisierung erklärt. Dieses Mal werden wir uns mit der Methode zur automatischen Bestimmung dieses Schwellenwerts befassen.
Bei der Binärisierung von Otsu wird die Klasse entsprechend dem Schwellenwert in zwei Klassen unterteilt. Der Schwellenwert, wenn der Trennungsgrad in diesen beiden Klassen maximal ist, ist der Schwellenwert beim Binärisieren. Die zur Berechnung des Trennungsgrades erforderlichen Parameter können nach folgender Formel berechnet werden.
Trennung: $ X = \ dfrac {\ sigma _ {b} ^ {2}} {\ sigma _ {w} ^ {2}} $
Verteilung in der Klasse: $ \ sigma _ {b} ^ {2} = \ dfrac {\ omega _ {0} \ omega _ {1}} {(\ omega _ {0} + \ omega _ {1}) ^ 2 } (M _ {0} + M _ {1}) ^ 2 $
Verteilung zwischen Klassen: $ \ sigma _ {b} ^ {2} = \ omega _ {0} \ sigma _ {0} ^ {2} + \ omega _ {1} \ sigma _ {1} ^ {2} $
Anzahl der Pixel der Klasse 0,1: $ \ omega _0, \ omega _1 $
Verteilung der Pixelwerte der Klassen 0,1: $ \ sigma _0, \ sigma _1 $
Durchschnitt der Pixelwerte der Klasse 0,1: $ M_0, M_1 $
Durchschnittlicher Pixelwert des gesamten Bildes: $ M $
Summe der Pixelwerte der Klasse 0,1: $ P_0, P_1 $
Zusammenfassend sollte, wenn der Schwellenwert 0 bis 255 beträgt, der Trennungsgrad 256-mal berechnet werden, um den Schwellenwert zu finden, der den Trennungsgrad maximiert.
otsuBinarization.py
import numpy as np
import cv2
import matplotlib.pyplot as plt
# from statistics import variance
import statistics as st
plt.gray()
def otsuBinarization(img):
#Bildkopie
dst = img.copy()
#Graustufen
gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY)
w,h = gray.shape
Max = 0
#Durchschnittlicher Pixelwert des gesamten Bildes
M = np.mean(gray)
#Gilt für alle 256 Schwellenwerte
for th in range(256):
#Einstufung
g0,g1 = gray[gray<th],gray[gray>=th]
#Anzahl der Pixel
w0,w1 = len(g0),len(g1)
#Pixelwertverteilung
s0_2,s1_2 = g0.var(),g1.var()
#Pixelwert Durchschnitt
m0,m1 = g0.mean(),g1.mean()
#Gesamtpixelwert
p0,p1 = g0.sum(),g1.sum()
#Verteilung in der Klasse
sw_2 = w0*s0_2 + w1*s1_2
#Verteilung zwischen Klassen
sb_2 = ((w0*w1) / ((w0+w1)*(w0+w1))) * ((m0-m1)*(m0-m1))
#Trennung
if (sb_2 != 0):
X = sb_2 / sw_2
else:
X = 0
if (Max < X):
Max = X
t = th
#Binarisierung
idx = np.where(gray < t)
gray[idx] = 0
idx = np.where(gray >= t)
gray[idx] = 255
return gray
#Bild lesen
img = cv2.imread('image.jpg')
#Binarisierung von Otsu
mono = otsuBinarization(img)
#Bild speichern
cv2.imwrite('result.jpg', mono)
#Bildschirm
plt.imshow(mono)
plt.show()
Die linke Seite des Bildes ist das Eingabebild, die Mitte des Bildes ist das Ausgabebild, wenn der Schwellenwert manuell auf 128 eingestellt ist, und die rechte Seite des Bildes ist diesmal das Ausgabebild. Selbst wenn der Schwellenwert automatisch ermittelt und binärisiert wird, wird das Bild ohne große Beschwerden ausgegeben. Abgesehen davon verwendet meine Implementierung nicht den durchschnittlichen Pixelwert M für das gesamte Bild.
Wenn Sie Fragen haben, können Sie sich gerne an uns wenden. Imori_imoris Github hat die offizielle Antwort. Bitte überprüfen Sie dies ebenfalls. .. Da Python ein Anfänger ist, sollten Sie auch auf Fehler achten und diese kommentieren.
Recommended Posts