Kapitel 6 – Schwellenwerte

Unter Schwellenwertverarbeitung versteht man das Entfernen von Pixeln, deren Pixelwerte im Bild höher oder niedriger als ein bestimmter Wert sind. Legen Sie den Schwellenwert beispielsweise auf 127 fest und gehen Sie dann wie folgt vor:

  • Legen Sie die Werte aller Pixel im Bild mit Pixelwerten größer als 127 bis 255 fest.
  • Setzen Sie die Werte aller Pixel im Bild mit Pixelwerten kleiner oder gleich 127 auf 0.

Mit der obigen Methode kann ein Binärbild erhalten werden. Wie in der Abbildung gezeigt, wird ein Graustufenbild gemäß der oben genannten Schwellenwertverarbeitungsmethode in ein Binärbild verarbeitet, wodurch die Trennung von Vordergrund und Hintergrund effektiv realisiert wird.

Bild-20211013111330415

OpenCV stellt die Funktion cv2.threshold() und die Funktion cv2.adaptiveThreshold() für die Schwellenwertbildung bereit.

one.threshold-Funktion:

OpenCV3.0 verwendet die Funktion cv2.threshold() zur Schwellenwertbildung. Die Syntax dieser Funktion lautet:

  • retval, dst = cv2.threshold(src, thresh, maxval, type)

    • retval: Stellt den zurückgegebenen Schwellenwert dar.
    • dst: stellt das Ergebnisbild der Schwellenwertsegmentierung dar, das dieselbe Größe und denselben Typ wie das Originalbild hat.
    • src: Stellt das Bild dar, für das ein Schwellenwert ermittelt werden soll. Dabei kann es sich um einen Mehrkanal-, 8-Bit- oder 32-Bit-Gleitkommawert handeln.
    • thresh: stellt den festzulegenden Schwellenwert dar.
    • maxval: Stellt den Maximalwert dar, der festgelegt werden muss, wenn der Typparameter vom Typ THRESH_BINARY oder THRESH_BINARY_INV ist.
    • Der Typ stellt den Typ der Schwellenwertsegmentierung dar. Die spezifischen Typwerte sind in der Tabelle aufgeführt:

    Bild-20211013103741015

Die obige Formel ist relativ abstrakt und kann wie folgt dargestellt werden:

Bild-20211013103854712

1. Verarbeitung des Binarisierungsschwellenwerts (cv2.THRESH_BINARY):

Bei der Binarisierungsschwellenwertbildung wird das Originalbild wie gezeigt in ein Binärbild mit nur zwei Werten verarbeitet. Seine Verarbeitungsmethode für Pixel ist:

  • Für Pixel, deren Grauwert größer als der Schwellenwert ist, legen Sie ihren Grauwert auf den Maximalwert fest.
  • Für Pixel, deren Grauwert kleiner oder gleich dem Schwellenwert ist, wird ihr Grauwert auf 0 gesetzt.

Bild-20211013104222845

Als Ausdruck ausgedrückt:

dst ( x , y ) = { maxval , src ( x , y ) > thresh 0 , in anderen Fällen dst(x, y) = \begin{cases} maxval, \quad src(x, y) >thresh \\ 0 , \quad other case\end{cases}d s t ( x ,y )={ m a x v a l ,s r c ( x ,y )>d r e s h _0 ,andere Situationen, thresh stellt einen bestimmten Schwellenwert dar.

Bei 8-Bit-Bildern beträgt der Maximalwert 255. Wenn daher bei der Binärisierung eines 8-Bit-Graustufenbilds der Schwellenwert auf 127 eingestellt ist, gilt Folgendes:

  • Alle Pixel größer als 127 werden als 255 verarbeitet.
  • Andere Werte werden als 0 behandelt.

Der Einfachheit halber nehmen wir in den folgenden Beschreibungen ein 8-Bit-Bild als Beispiel, dh der maximale Pixelwert beträgt 255.

Beispiel: Verwenden Sie die Funktion cv2.threshold(), um eine Binärisierungsschwellenwertverarbeitung für das Array durchzuführen.

import cv2
import numpy as np

img = np.random.randint(0, 256, size=[4, 5], dtype=np.uint8)
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
print('img=\n', img)
print('t', t)
print('rst=\n', rst)

# 输出结果
img=
 [[138 241 156  43   1]
 [205 128 223 143 236]
 [ 61  34 106 233 196]
 [180  81 192 210 107]]
t 127.0
rst=
 [[255 255 255   0   0]
 [255 255 255 255 255]
 [  0   0   0 255 255]
 [255   0 255 255   0]]

2. Verarbeitung des Anti-Binarisierungsschwellenwerts (cv2.THRESH_BINARY_INV)

Das Ergebnis der Anti-Binarisierungsschwellenwertverarbeitung ist ebenfalls ein Binärbild mit nur zwei Werten. Der Unterschied zur Binarisierungsschwellenwertverarbeitung besteht darin, dass die beiden Pixelwerte auf unterschiedliche Weise verarbeiten. Die Anti-Binarisierungs-Schwellenwertverarbeitungsmethode für Pixelpunkte ist:

  • Für Pixel, deren Grauwert größer als der Schwellenwert ist, legen Sie den Wert auf 0 fest.
  • Für Pixel, deren Grauwert kleiner oder gleich dem Schwellenwert ist, legen Sie den Wert auf 255 fest.

Bild-20211013111532792

Als Ausdruck ausgedrückt:

dst ( x , y ) = { 0 , src ( x , y ) > threshmaxval , in anderen Fällen dst(x, y) = \begin{cases} 0, \quad src(x, y) >thresh \\ maxval, \ quad andere Fälle\end{Fälle}d s t ( x ,y )={ 0 ,s r c ( x ,y )>d r e s h _m a x v a l ,andere Situationen, thresh stellt einen bestimmten Schwellenwert dar.

Beispiel: Verwenden Sie die Funktion cv2.threshold(), um eine Debinarisierungsschwellenwertverarbeitung für das Array durchzuführen.

import cv2
import numpy as np

img = np.random.randint(0, 256, size=[4, 5], dtype=np.uint8)
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
print('img=\n', img)
print('t', t)
print('rst=\n', rst)

# 输出结果
img=
 [[ 22 209 106 193  56]
 [218 252 109 166  47]
 [141 247  76 247 102]
 [ 42   4 217 110 199]]
t 127.0
rst=
 [[255   0 255   0 255]
 [  0   0 255   0 255]
 [  0   0 255   0 255]
 [255 255   0 255   0]]

3. Kürzungsschwellenwert (cv2.THRESH_TRUNC)

Bei der Kürzungsschwelle wird der Wert der Pixelpunkte, die größer als der Schwellenwert im Bild sind, auf den festgelegten Schwellenwert verarbeitet, und der Wert der Pixelpunkte, die kleiner oder gleich dem Schwellenwert sind, bleibt unverändert. Wie im Diagramm dargestellt:

Bild-20211013112247076

Wenn der Schwellenwert beispielsweise als 127 ausgewählt ist, gilt beim Abschneiden des Schwellenwertprozesses Folgendes:

  • Für ein Pixel mit einem Pixelwert größer als 127 wird sein Pixelwert auf 127 gesetzt.
  • Bei Pixeln, deren Pixelwert kleiner oder gleich 127 ist, ändert sich der Pixelwert ständig.

Wenn es durch einen Ausdruck dargestellt wird, lautet die Generierungsregel für seinen Zielwert:

dst ( x , y ) = { thresh , src ( x , y ) > thresh bleibt unverändert, andernfalls dst(x, y) = \begin{cases} thresh, \quad src(x, y) >thresh \\ bleiben die dasselbe, \quad other case\end{cases}d s t ( x ,y )={ d r e s h , _s r c ( x ,y )>d r e s h _Bleib gleich ,andere Situationen, thresh stellt einen bestimmten Schwellenwert dar.

import cv2
import numpy as np

img = np.random.randint(0, 256, size=[4, 5], dtype=np.uint8)
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
print('img=\n', img)
print('t=\n', t)
print('rst=\n', rst)


# 输出结果
img=
 [[ 75 169  58 247 235]
 [ 95  95 139 129 102]
 [ 93  86  97 140 200]
 [108  64 250  33 171]]
t=
 127.0
rst=
 [[ 75 127  58 127 127]
 [ 95  95 127 127 102]
 [ 93  86  97 127 127]
 [108  64 127  33 127]]

4. Super-Threshold-Null-Verarbeitung (cv2.THRESH_TOZERO_INV)

Bei der Super-Schwellenwert-Null-Verarbeitung wird der Wert der Pixelpunkte, die größer als der Schwellenwert im Bild sind, auf 0 verarbeitet, und der Wert der Pixelpunkte, die kleiner oder gleich dem Schwellenwert sind, bleibt unverändert. Das heißt, wählen Sie zunächst einen Schwellenwert aus und verarbeiten Sie das Bild dann wie folgt:

  • Für ein Pixel, dessen Pixelwert größer als der Schwellenwert ist, wird sein Pixelwert als 0 verarbeitet.
  • Bei Pixeln, deren Pixelwert kleiner oder gleich dem Schwellenwert ist, bleiben ihre Pixelwerte unverändert.

Das Funktionsprinzip der überschwelligen Nullverarbeitung ist in der Abbildung dargestellt.

Bild-20211013113055544

Wenn der Schwellenwert beispielsweise 127 beträgt, gilt Folgendes:

  • Bei Pixelwerten größer als 127 wird der Wert auf 0 gesetzt.
  • Bei Pixeln, deren Wert kleiner oder gleich 127 ist, ändert sich der Wert ständig.

Wenn es durch einen Ausdruck dargestellt wird, lautet die Generierungsregel seines Zielwerts:

dst ( x , y ) = { 0 , src ( x , y ) > threshsrc ( x , y ) , in anderen Fällen dst(x, y) = \begin{cases} 0, \quad src(x, y) > thresh \\ src(x, y), \quad other case\end{cases}d s t ( x ,y )={ 0 ,s r c ( x ,y )>d r e s h _s r c ( x ,y ) ,andere Situationen, thresh stellt einen bestimmten Schwellenwert dar.

import cv2
import numpy as np

img = np.random.randint(0, 256, size=[4, 5], dtype=np.uint8)
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
print('img=\n', img)
print('t=\n', t)
print('rst=\n', rst)


# 输出结果
img=
 [[101  38  87  65 182]
 [126 143  54  27 236]
 [233 150 144  30 206]
 [182 174 185 212 115]]
t=
 127.0
rst=
 [[101  38  87  65   0]
 [126   0  54  27   0]
 [  0   0   0  30   0]
 [  0   0   0   0 115]]

5. Null-Verarbeitung mit niedrigem Schwellenwert (cv2.THRESH_TOZERO)

Bei der Null-Schwellenwertverarbeitung wird der Wert der Pixelpunkte, die kleiner oder gleich dem Schwellenwert im Bild sind, als 0 behandelt, und der Wert der Pixelpunkte, die größer als der Schwellenwert sind, bleibt unverändert. Das heißt, wählen Sie zunächst einen Schwellenwert aus und verarbeiten Sie das Bild dann wie folgt:

  • Bei Pixeln, deren Pixelwert über dem Schwellenwert liegt, bleiben ihre Werte unverändert.
  • Für Pixel, deren Pixelwert kleiner oder gleich dem Schwellenwert ist, wird der Wert als 0 verarbeitet.

Bild-20211013114019979

Wenn der Schwellenwert beispielsweise 127 beträgt, gilt Folgendes:

  • Bei Pixeln mit Pixelwerten über 127 ändern sich ihre Pixelwerte ständig.
  • Für Pixel, deren Pixelwert kleiner oder gleich 127 ist, werden ihre Pixelwerte auf 0 gesetzt.

Wenn es durch einen Ausdruck dargestellt wird, lautet die Generierungsregel seines Zielwerts:

dst ( x , y ) = { src ( x , y ) , src ( x , y ) > thresh 0 , andere Fälle dst(x, y) = \begin{cases} src(x, y), \quad src( x, y) >thresh \\ 0, \quad other case\end{cases}d s t ( x ,y )={ s r c ( x ,y ) ,s r c ( x ,y )>d r e s h _0 ,andere Situationen, thresh stellt einen bestimmten Schwellenwert dar.

import cv2
import numpy as np

img = np.random.randint(0, 256, size=[4, 5], dtype=np.uint8)
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
print('img=\n', img)
print('t=\n', t)
print('rst=\n', rst)


# 输出结果
img=
 [[  2 202  44   8  95]
 [130 187  52 214 168]
 [153 169 199 224 155]
 [  4 232  38 244  97]]
t=
 127.0
rst=
 [[  0 202   0   0   0]
 [130 187   0 214 168]
 [153 169 199 224 155]
 [  0 232   0 244   0]]

2. Adaptive Schwellenwertbestimmung:

​ Für ein farblich ausgeglichenes Bild kann die Schwellenwertberechnung des Bildes direkt mithilfe eines Schwellenwerts erfolgen. Manchmal ist die Farbe des Bildes jedoch unausgewogen. Wenn zu diesem Zeitpunkt nur ein Schwellenwert verwendet wird, kann kein klares und effektives Schwellensegmentierungsergebnisbild erhalten werden.

Es gibt eine verbesserte Schwellenwerttechnik, die einen sich dynamisch ändernden Schwellenwert verwendet, um die Schwellenwertbildung des Bildes abzuschließen. Diese Technik wird als adaptive Schwellenwertbildung bezeichnet . Bei der Schwellenwertverarbeitung ermittelt die adaptive Schwellenwertverarbeitungsmethode einen Schwellenwert durch Berechnen des gewichteten Durchschnittswerts des angrenzenden Bereichs um jedes Pixel und verwendet den Schwellenwert zur Verarbeitung des aktuellen Pixels. Im Vergleich zu herkömmlichen Schwellenwertmethoden kann die adaptive Schwellenwertmethode Bilder mit großen Unterschieden zwischen Hell und Dunkel besser verarbeiten.

OpenCV stellt die Funktion cv2.adaptiveThreshold() zur Implementierung der adaptiven Schwellenwertverarbeitung bereit. Die Syntax dieser Funktion lautet:

  • dst=cv.adaptiveThreshold(src,maxValue,adaptiveMethod,thresholdType,blockSize,C)
    • dst: stellt das Ergebnis der adaptiven Schwellenwertverarbeitung dar.
    • src: stellt das zu verarbeitende Originalbild dar. Es ist zu beachten, dass es sich bei dem Bild um ein 8-Bit-Einkanalbild handeln muss.
    • maxValue: stellt den Maximalwert dar.
    • adaptiveMethod: Stellt eine adaptive Methode dar.
    • Schwellenwerttyp: Stellt die Schwellenwertverarbeitungsmethode dar. Der Wert muss einer von cv2.THRESH_BINARY oder cv2.THRESH_BINARY_INV sein.
    • blockSize: repräsentiert die Blockgröße. Gibt die Nachbarschaftsgröße an, die ein Pixel bei der Berechnung seines Schwellenwerts verwendet, normalerweise 3, 5, 7 usw.
    • C: ist eine Konstante.

​ Die Funktion cv2.adaptiveThreshold() bestimmt die Berechnungsmethode des adaptiven Schwellenwerts gemäß dem Parameter adaptiveMethod. Die Funktion umfasst zwei verschiedene Methoden: cv2.ADAPTIVE_THRESH_MEAN_C und cv2.ADAPTIVE_THRESH_GAUSSIAN_C. Beide Methoden berechnen den adaptiven Schwellenwert Pixel für Pixel, und der adaptive Schwellenwert ist gleich dem gewichteten Durchschnitt der Nachbarschaft jedes Pixels, der durch den Parameter blockSize angegeben wird, minus der Konstante C. Zwei unterschiedliche Methoden unterscheiden sich in der Art und Weise, wie sie den gewichteten Durchschnitt der Stadtteile berechnen:

  • cv2.ADAPTIVE_THRESH_MEAN_C: Die Gewichtswerte aller Pixel in der Nachbarschaft sind konsistent.
  • cv2.ADAPTIVE_THRESH_GAUSSIAN_C: Es bezieht sich auf den Abstand von jedem Pixelpunkt in der Nachbarschaft zum Mittelpunkt, und der Gewichtungswert jedes Punkts wird durch die Gaußsche Gleichung erhalten.
import cv2

img = cv2.imread('../sugar.tiff', 0)
print(img)
t1, thd = cv2.threshold(img, 200, 255, cv2.THRESH_BINARY)
athdMEAN = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 3, 3)
athdGAUS = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 3, 3)
cv2.imshow('img', img)
cv2.imshow('thd', thd)
cv2.imshow('athdMEAN', athdMEAN)
cv2.imshow('athdGAUS', athdGAUS)
cv2.waitKey()
cv2.destroyAllWindows()

Bild-20211013153325121

Durch den Vergleich der gewöhnlichen Schwellenwertverarbeitung mit der adaptiven Schwellenwertverarbeitung kann festgestellt werden, dass die adaptive Schwellenwertverarbeitung detailliertere Informationen behält. In einigen extremen Fällen gehen bei der herkömmlichen Schwellenwertberechnung viele Informationen verloren, bei der adaptiven Schwellwertberechnung können jedoch bessere Binärbilder erzielt werden.

3. Otsu-Verarbeitung:

​ Wenn Sie die Funktion cv2.threshold() für die Schwellenwertbildung verwenden, müssen Sie einen Schwellenwert anpassen und diesen Schwellenwert als Grundlage für die Bildschwellenwertbildung verwenden. Normalerweise weisen alle verarbeiteten Bilder einen Farbausgleich auf, und es ist sinnvoller, den Schwellenwert direkt auf 127 festzulegen. Manchmal ist die Graustufe des Bildes jedoch ungleichmäßig verteilt. Wenn der Schwellenwert zu diesem Zeitpunkt auf 127 eingestellt ist, schlägt das Ergebnis der Schwellenwertverarbeitung fehl. Zum Beispiel gibt es ein Bild img, der darin enthaltene Pixelwert ist:

Bild-20211013155455573

Wenn zu diesem Zeitpunkt 127 als Schwellenwert verwendet wird, lautet das Ergebnis der Schwellenwertverarbeitung:

Bild-20211013155549062

Offensichtlich ist dies nicht das Ergebnis, das wir wollen. Wir können beobachten, dass für img bessere Ergebnisse erzielt werden können, wenn der Schwellenwert für die Segmentierung 125 beträgt:

Bild-20211013155632125

Allerdings sind die tatsächlich verarbeiteten Bilder oft sehr komplex und es ist unmöglich, den am besten geeigneten Schwellenwert auf einen Blick zu erkennen, wie im obigen Bild. Wenn Sie es einzeln versuchen, wird die Arbeitsbelastung zweifellos enorm sein.

Die Otsu- Methode kann den besten Segmentierungsschwellenwert zwischen den Klassen basierend auf dem aktuellen Bild liefern . Kurz gesagt, die Methode von Otsu durchläuft alle möglichen Schwellenwerte, um den besten zu finden.

​In OpenCV kann durch Übergabe eines zusätzlichen Parameters „cv2.THRESH_OTSU“ an den Typ des Parametertyps in der Funktion cv2.threshold() die Schwellenwertsegmentierung der Otsu-Methode realisiert werden.

​ Es ist zu beachten, dass bei Verwendung der Otsu-Methode der Schwellenwert auf 0 gesetzt werden sollte . Die Funktion cv2.threshold () findet zu diesem Zeitpunkt automatisch den optimalen Schwellenwert und gibt den Schwellenwert zurück. Die folgende Anweisung veranlasst beispielsweise die Funktion cv2.threshold(), die Methode von Otsu für die Schwellenwertsegmentierung zu verwenden:

  • t, otsu=cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

Der Unterschied zur gewöhnlichen Schwellenwertsegmentierung besteht darin, dass:

  • Der Parametertyp fügt einen Parameterwert „cv2.THRESH_OTSU“ hinzu.
  • Der eingestellte Schwellenwert ist 0.
  • Der Rückgabewert t ist der optimale Schwellenwert, der von der Otsu-Methode berechnet und verwendet wird.

Beispiel 1:

import cv2
import numpy as np

img = np.zeros((5, 5), dtype=np.uint8)
img[0:6, 0:6] = 123
img[2:6, 2:6] = 126
t1, thd = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
t2, otsu = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

print('img=\n', img)
print('thd=\n', thd)
print('otsu=\n', otsu)

# 输出结果
img=
 [[123 123 123 123 123]
 [123 123 123 123 123]
 [123 123 126 126 126]
 [123 123 126 126 126]
 [123 123 126 126 126]]
thd=
 [[0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]
otsu=
 [[  0   0   0   0   0]
 [  0   0   0   0   0]
 [  0   0 255 255 255]
 [  0   0 255 255 255]
 [  0   0 255 255 255]]

Beispiel 2:

import cv2

img = cv2.imread('../lena.bmp', 0)
t1, thd = cv2.threshold(img, 50, 255, cv2.THRESH_BINARY)
t2, otsu = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imshow('img', img)
cv2.imshow('thd', thd)
cv2.imshow('otus', otsu)
cv2.waitKey()
cv2.destroyAllWindows()

Bild-20211013161802362

Supongo que te gusta

Origin blog.csdn.net/weixin_57440207/article/details/122646992
Recomendado
Clasificación