[PYTHON] Beschleunigen Sie den Zhang-Suen-Algorithmus in Numpy

Einführung

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.

Universelle Funktion

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.

wird bearbeitet

Vorverarbeitung

#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)

Bedingung 1

** schwarz ** Das ursprüngliche Array ist so wie es ist.

condition1 = np.copy(image)

Bedingung 2

** 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)

Bedingung 3

** 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)

Bedingung 4, Bedingung 5

** 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]))

Quellcode

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

Beschleunigen Sie den Zhang-Suen-Algorithmus in Numpy
wo von numpy
Implementieren Sie den PRML-Algorithmus in Python (fast nur Numpy)
Achsenspezifikation mit NumPy
Genetischer Algorithmus in Python
Algorithmus in Python (Bellman-Ford-Methode, Bellman-Ford)
Algorithmus in Python (Dijkstra)
Installieren Sie numpy in Visual Studio 2019
Algorithmus in Python (Haupturteil)
Nachahmung von Pythons Numpy in C #
Matrixprodukt in Python numpy
Reproduzieren Sie die euklidische Methode der gegenseitigen Teilung in Python
Algorithmus in Python (Dichotomie)
Implementieren Sie den Dijkstra-Algorithmus in Python
Algorithmus in Python (Breitenprioritätssuche, bfs)
Sortieralgorithmus und Implementierung in Python
Setzen Sie Python, Numpy, OpenCV3 in Ubuntu14
Schreiben Sie A * (A-Stern) -Algorithmen in Python
Selbstorganisierende Karte in der Python NumPy-Version
Lassen Sie uns mit Python 2 einen Investitionsalgorithmus entwickeln
[Numpy] Rufen Sie savetxt () im Append-Modus auf
Algorithmus in Python (Tiefenprioritätssuche, dfs)
Implementierung eines einfachen Algorithmus in Python 2
Algorithmus (Segmentbaum) in Python (Übung)
Führen Sie einen einfachen Algorithmus in Python aus
Invertiere numpy Boolean Array in Tilda