Die Binärisierung von Otsu ist ein Algorithmus, der automatisch den Schwellenwert für die Binärisierung eines Bildes ermittelt. Es wurde bereits in Bibliotheken wie OpenCV implementiert, aber ich habe eine Implementierung in Python gefunden und sie berührt. Es gibt ein Problem mit dem Titel, aber ich denke, es wurde wahrscheinlich durch meine schlechte Ausführungsumgebung verursacht.
Der Code selbst wurde nicht von mir geschrieben, sondern aus einem Blog [1], das von anderen erstellt wurde. ist.
ots.py
#Binarisierung von Otsu (graues Argument ist ein Graustufenbild)
def threshold_otsu(gray, min_value=0, max_value=255):
#Berechnung des Histogramms
hist = [np.sum(gray == i) for i in range(256)]
s_max = (0,-10)
for th in range(256):
#Berechnen Sie die Anzahl der Pixel in Klasse 1 und Klasse 2
n1 = sum(hist[:th])
n2 = sum(hist[th:])
#Berechnen Sie den Durchschnitt der Pixelwerte der Klassen 1 und 2
if n1 == 0 : mu1 = 0
else : mu1 = sum([i * hist[i] for i in range(0,th)]) / n1
if n2 == 0 : mu2 = 0
else : mu2 = sum([i * hist[i] for i in range(th, 256)]) / n2
#Berechnen Sie das Molekül der Dispersion zwischen den Klassen
s = n1 * n2 * (mu1 - mu2) ** 2
#Notieren Sie das Dispersionsmolekül zwischen den Klassen und den Schwellenwert, wenn das Dispersionsmolekül zwischen den Klassen maximal ist
if s > s_max[1]:
s_max = (th, s)
#Ermitteln Sie den Schwellenwert, wenn die Verteilung zwischen den Klassen maximal ist
t = s_max[0]
#Binarisierungsverarbeitung mit dem berechneten Schwellenwert
gray[gray < t] = min_value
gray[gray >= t] = max_value
return gray
Ich habe eine Überlaufwarnung erhalten, als ich die Fotos unten polarisiert habe.
RuntimeWarning: overflow encountered in long_scalars
s = n1 * n2 * ((mu1 - mu2) ** 2)
Zu diesem Zeitpunkt wird der Schwellenwert 137, was weit von dem Wert 78 entfernt ist, der erhalten wird, wenn Otsu mit OpenCV binärisiert wird.
Das Ausführen von Typ (n1) und Typ (n2) für n1 und n2 führte zu \ <class'numpy.int32 '>. Daher wird angenommen, dass die Ursache darin besteht, dass das Berechnungsergebnis den Bereich des Typs int32 (-2147483648 bis 2147483647) [2] überschreitet Verständnis-Datentypen.html).
Ich dachte über zwei Maßnahmen nach. Die erste besteht darin, die Typen von n1 und n2 schweben zu lassen. Durch Hinzufügen einer Zeile wie unten gezeigt ändert sich der Typ von hist, und infolgedessen ändern sich auch die Typen von n1 und n2.
python
#Berechnung des Histogramms
hist = [np.sum(gray == i) for i in range(256)]
hist = np.array(hist, dtype=np.float64)
Die zweite ist die Verwendung von Protokoll. Da die relative Größe von s wichtiger ist als der Wert selbst, wird das Protokoll auf beiden Seiten von s erstellt und die rechte Seite wird zerlegt (das Ergebnis der Protokollierung ist vom Typ float). Sofern der Inhalt nicht 1 und minus ist, ändert sich die Reihenfolge auch dann nicht, wenn Sie das Protokoll erstellen.
python
import math
...
#Berechnen Sie das Molekül der Dispersion zwischen den Klassen
#s = float(n1 * n2 * ((mu1 - mu2) ** 2))
if n1 == 0 or n2 == 0:
continue
if mu2 >= mu1:
s = math.log(n1)+math.log(n2)+2*math.log(mu2-mu1)
elif mu1 < mu2:
s = math.log(n1)+math.log(n2)+2*math.log(mu1-mu2)
...
Ich konnte es sicher lösen. Das Bild unten ist das Ergebnis der Ausführung des Programms.
Außerdem betrug der Schwellenwert 79 (OpenCV liegt unter dem Schwellenwert, und dieses Programm wird unterhalb des Schwellenwerts binärisiert), was bestätigt, dass die Programmierung normal funktioniert. Im ersten und zweiten ist das erstere überwältigend einfacher, aber da es interessant schien, habe ich auch das letztere gepostet.
Es wird angenommen, dass die Ursache des Problems darin besteht, dass die Form nicht in Form ist. Es war eine gute Studie, da ich bei der Bildverarbeitung mit Python häufig unter Tippen leide.
Danke, dass du bis zum Ende zugesehen hast. Wenn Sie Kommentare oder Vorschläge haben, zögern Sie bitte nicht, uns zu kontaktieren.
[1]https://algorithm.joho.info/programming/python/opencv-otsu-thresholding-py/ [2]https://jakevdp.github.io/PythonDataScienceHandbook/02.01-understanding-data-types.html
Recommended Posts