Klicken Sie hier für den Zhang-Suen-Algorithmus Wie Sie beim Lesen des verknüpften Codes sehen können, ist er sehr langsam, da er in einer doppelten for-Schleife gedreht wird. Also habe ich es möglich gemacht, die gleiche Verarbeitung nur mit der universellen Funktion von Numpy durchzuführen.
Numpy bietet eine Funktion, die als universelle Funktion bezeichnet wird und ein Array der Ergebnisse der Ausführung wichtiger Operationen für jedes Element des Arrays zurückgibt. Wenn Sie dies verwenden, müssen Sie nicht jedes Element einzeln extrahieren und verarbeiten. Es ist schnell. Es wird ungefähr 20 bis 30 Mal schneller sein.
#Eine Methode, um 1 Pixel um ein Binärbild mit False zu füllen.
def padding(binary_image):
row, col = np.shape(binary_image)
result = np.zeros((row+2,col+2))
result[1:-1, 1:-1] = binary_image[:, :]
return result
def generate_mask(image):
row, col = np.shape(image)
p2 = np.zeros((row, col)).astype(bool)
p3 = np.zeros((row, col)).astype(bool)
p4 = np.zeros((row, col)).astype(bool)
p5 = np.zeros((row, col)).astype(bool)
p6 = np.zeros((row, col)).astype(bool)
p7 = np.zeros((row, col)).astype(bool)
p8 = np.zeros((row, col)).astype(bool)
p9 = np.zeros((row, col)).astype(bool)
#Oben
p2[1:row-1, 1:col-1] = image[0:row-2, 1:col-1]
#Oben rechts
p3[1:row-1, 1:col-1] = image[0:row-2, 2:col]
#richtig
p4[1:row-1, 1:col-1] = image[1:row-1, 2:col]
#Rechts unten
p5[1:row-1, 1:col-1] = image[2:row, 2:col]
#unter
p6[1:row-1, 1:col-1] = image[2:row, 1:col-1]
#Unten links
p7[1:row-1, 1:col-1] = image[2:row, 0:col-2]
#links
p8[1:row-1, 1:col-1] = image[1:row-1, 0:col-2]
#Oben links
p9[1:row-1, 1:col-1] = image[0:row-2, 0:col-2]
return (p2, p3, p4, p5, p6, p7, p8, p9)
** schwarz ** Das ursprüngliche Array ist so wie es ist.
condition1 = np.copy(image)
** Wenn die Pixel um das Zielpixel in der richtigen Reihenfolge angeordnet sind, gibt es genau eine Stelle, an der Weiß → Schwarz ** Diese Bedingung bedeutet, dass beim Betrachten einer Adresse in der Reihenfolge P2, P3, P4, P5, P6, P7, P8, P9, P2 genau zwei Richtig-Falsch-Änderungen vorgenommen werden.
#Es ist eine Methode, um zu beurteilen, ob es genau ein Weiß → Schwarz gibt, wenn die umgebenden Pixel in der richtigen Reihenfolge angeordnet sind.
def is_once_change(p_tuple):
number_change = np.zeros_like(p_tuple[0])
# P2~P9,Zählen Sie für P2 die Anzahl der Trues, wenn die exklusive logische Summe benachbarter Elemente verwendet wird.
for i in range(len(p_tuple) - 1):
number_change = np.add(number_change, np.logical_xor(p_tuple[i], p_tuple[i+1]).astype(int))
number_change = np.add(number_change, np.logical_xor(p_tuple[7], p_tuple[0]).astype(int))
array_two = np.ones_like(p_tuple[0]) * 2
return np.equal(number_change, array_two)
condition2 = is_once_change(p_tuple)
** 2 oder mehr und 6 oder weniger Schwarz um das Zielpixel ** Diese Bedingung bedeutet, dass die Anzahl der Trues von P2, P3, P4, P5, P6, P7, P8, P9 2 oder mehr und 6 oder weniger für eine bestimmte Adresse beträgt.
#Diese Methode zählt die Anzahl der schwarzen Pixel um sie herum und bestimmt, ob es 2 oder mehr und 6 oder weniger ist.
def is_black_pixels_appropriate(p_tuple):
number_of_black_pxels = np.zeros_like(p_tuple[0])
array_two = np.ones_like(p_tuple[0]) * 2
array_six = np.ones_like(p_tuple[0]) * 6
for p in p_tuple:
number_of_black_pxels = np.add(number_of_black_pxels, p.astype(int))
greater_two = np.greater_equal(number_of_black_pxels, array_two)
less_six = np.less_equal(number_of_black_pxels, array_six)
return np.logical_and(greater_two, less_six)
condition3 = is_black_pixels_appropriate(p_tuple)
** Mindestens eines der oberen, unteren, linken und rechten Pixel des Zielpixels ist weiß ** Überprüfen Sie, ob mindestens einer der entsprechenden P2-, P4-, P6- und P8-Werte für das Zielpixel False ist.
#Eine Methode, die das logische Produkt für alle angegebenen Argumente zurückgibt.
def multi_logical_and(*args):
result = np.copy(args[0])
for arg in args:
result = np.logical_and(result, arg)
return result
condition4 = np.logical_not(multi_logical_and(p_tuple[0], p_tuple[2], p_tuple[4]))
Ich werde den Code des gesamten Prozesses setzen.
ZhangSuen.py
import numpy as np
#Eine Methode, die das logische Produkt für alle angegebenen Argumente zurückgibt.
def multi_logical_and(*args):
result = np.copy(args[0])
for arg in args:
result = np.logical_and(result, arg)
return result
#Eine Methode, um 1 Pixel um ein Binärbild mit False zu füllen.
def padding(binary_image):
row, col = np.shape(binary_image)
result = np.zeros((row+2,col+2))
result[1:-1, 1:-1] = binary_image[:, :]
return result
#Das Gegenteil von Polsterung
def unpadding(image):
return image[1:-1, 1:-1]
#Gibt ein Array zurück, das Informationen zu den Pixeln um dieses Pixel enthält.
def generate_mask(image):
row, col = np.shape(image)
p2 = np.zeros((row, col)).astype(bool)
p3 = np.zeros((row, col)).astype(bool)
p4 = np.zeros((row, col)).astype(bool)
p5 = np.zeros((row, col)).astype(bool)
p6 = np.zeros((row, col)).astype(bool)
p7 = np.zeros((row, col)).astype(bool)
p8 = np.zeros((row, col)).astype(bool)
p9 = np.zeros((row, col)).astype(bool)
#Oben
p2[1:row-1, 1:col-1] = image[0:row-2, 1:col-1]
#Oben rechts
p3[1:row-1, 1:col-1] = image[0:row-2, 2:col]
#richtig
p4[1:row-1, 1:col-1] = image[1:row-1, 2:col]
#Rechts unten
p5[1:row-1, 1:col-1] = image[2:row, 2:col]
#unter
p6[1:row-1, 1:col-1] = image[2:row, 1:col-1]
#Unten links
p7[1:row-1, 1:col-1] = image[2:row, 0:col-2]
#links
p8[1:row-1, 1:col-1] = image[1:row-1, 0:col-2]
#Oben links
p9[1:row-1, 1:col-1] = image[0:row-2, 0:col-2]
return (p2, p3, p4, p5, p6, p7, p8, p9)
#Es ist eine Methode, um zu beurteilen, ob es genau ein Weiß → Schwarz gibt, wenn die umgebenden Pixel in der richtigen Reihenfolge angeordnet sind.
def is_once_change(p_tuple):
number_change = np.zeros_like(p_tuple[0])
# P2~P9,Zählen Sie für P2 die Anzahl der Trues, wenn die exklusive logische Summe benachbarter Elemente verwendet wird.
for i in range(len(p_tuple) - 1):
number_change = np.add(number_change, np.logical_xor(p_tuple[i], p_tuple[i+1]).astype(int))
number_change = np.add(number_change, np.logical_xor(p_tuple[7], p_tuple[0]).astype(int))
array_two = np.ones_like(p_tuple[0]) * 2
return np.equal(number_change, array_two)
#Diese Methode zählt die Anzahl der schwarzen Pixel um sie herum und bestimmt, ob es 2 oder mehr und 6 oder weniger ist.
def is_black_pixels_appropriate(p_tuple):
number_of_black_pxels = np.zeros_like(p_tuple[0])
array_two = np.ones_like(p_tuple[0]) * 2
array_six = np.ones_like(p_tuple[0]) * 6
for p in p_tuple:
number_of_black_pxels = np.add(number_of_black_pxels, p.astype(int))
greater_two = np.greater_equal(number_of_black_pxels, array_two)
less_six = np.less_equal(number_of_black_pxels, array_six)
return np.logical_and(greater_two, less_six)
def step1(image, p_tuple):
#Bedingung 1
condition1 = np.copy(image)
#Bedingung 2
condition2 = is_once_change(p_tuple)
#Bedingung 3
condition3 = is_black_pixels_appropriate(p_tuple)
#Bedingung 4
condition4 = np.logical_not(multi_logical_and(p_tuple[0], p_tuple[2], p_tuple[4]))
#Bedingung 5
condition5 = np.logical_not(multi_logical_and(p_tuple[2], p_tuple[4], p_tuple[6]))
return np.logical_xor(multi_logical_and(condition1, condition2, condition3, condition4, condition5), image)
def step2(image, p_tuple):
#Bedingung 1
condition1 = np.copy(image)
#Bedingung 2
condition2 = is_once_change(p_tuple)
#Bedingung 3
condition3 = is_black_pixels_appropriate(p_tuple)
#Bedingung 4
condition4 = np.logical_not(np.logical_and(p_tuple[0], np.logical_and(p_tuple[2], p_tuple[6])))
#Bedingung 5
condition5 = np.logical_not(np.logical_and(p_tuple[0], np.logical_and(p_tuple[4], p_tuple[6])))
return np.logical_xor(multi_logical_and(condition1, condition2, condition3, condition4, condition5), image)
#Diese Methode gibt ein binärisiertes Bild als dünne Linie zurück.
def ZhangSuen(image):
image = padding(image)
while True:
old_image = np.copy(image)
p_tuple = generate_mask(image)
image = step1(image, p_tuple)
p_tuple = generate_mask(image)
image = step2(image, p_tuple)
if (np.array_equal(old_image, image)):
break
return unpadding(image)
Recommended Posts