[PYTHON] Eine Geschichte über die Verbesserung des Programms zum teilweisen Füllen von binärisierten 3D-Bilddaten

Das Füllprogramm, das ich das letzte Mal erstellt habe, hatte einen Stapelüberlauf

Das in Vorheriger Artikel erstellte Programm hatte einen Stapelüberlauf. Die Ursache ist ziemlich klar, und da es zurückgerufen wird, wird es das Gedächtnis überwältigen, wenn es mehr als eine bestimmte Menge wiederholt. Ich dachte, dass es kein Problem geben würde, wenn die Daten für Forschungszwecke verwendet würden, aber die Daten, die ich tatsächlich verwendete, liefen über, also entschied ich mich, den Algorithmus zu ändern.

Umgebung

python 3.7.4

Ich habe die Bibliothek nicht besonders benutzt.

Lösungsmethode

Die Ursache war, dass es den Speicher drückte, also entschied ich mich, es zu lösen, indem ich es mit for anstelle eines Rückrufs wiederholte. Es dauert jedoch zu lange, alle Zellen jedes Mal zu betrachten und zu verarbeiten. Erstellen Sie daher eine Funktion, die die 6 Richtungen (oben / unten / links / rechts + Z-Achse oben / unten) Ihrer eigenen Zelle ausfüllt und die Koordinaten der zu durchsuchenden Zelle speichert. Und nur diese Zelle verarbeiten. Ich weiß nicht einmal, ob ich es in Sätzen schreibe, also schreibe ich die Reihenfolge der Verarbeitung.

Status

Zunächst zeigt eine Tabelle, in welchen Zellen sich die Zellen befinden.

Statussymbol Inhalt des Staates
0 Eine der Binarisierung
1 Eine der Binarisierung
2 Gefüllte Zelle

wird bearbeitet

Dann ist es der Inhalt der eigentlichen Verarbeitung. Ich werde den ersten nicht wiederholen (natürlich)

  1. Bestimmen Sie den ersten Punkt
  2. Fügen Sie die Koordinaten der angegebenen Punkte in die Liste ein (z, y, x).
  3. Daten aus der Liste extrahieren. (Löschen Sie die abgerufenen Daten aus der Liste)
  4. Füllen Sie die entsprechende Zelle (auf 2 gesetzt)
  5. Fügen Sie die Koordinaten der entsprechenden Zelle in 6 Richtungen in die Liste ein (setzen Sie sie nicht ein, wenn sie bereits durchsucht wurde oder nicht das Ziel des Füllens ist).
  6. Wiederholen Sie die Schritte 3 bis 5, bis die Liste leer ist

Es ist so. Beim letzten Mal habe ich jeweils eine Zelle durchsucht, aber diesmal ist es so, als würde ich mich daran erinnern, welche Zellen im Voraus durchsucht werden sollen, und sie alle gleichzeitig verarbeiten.

fill.gif

Implementierung

Werfen wir einen Blick auf den Code. Die erste ist die iterative Hauptfunktion.

new_fill.py


def fill(data, plot):
    stack=[]
    end_stack=[]
    data, defaultvalue= plot_point(data, plot, stack) #Geben Sie den ersten Punkt an

    while stack: #Wiederholen, sofern nicht leer
        for pop_data in stack: #Daten aus dem Stapel extrahieren
            stack.remove(pop_data) #
            data = step_fill(data, pop_data["x"], pop_data["y"], pop_data["z"], defaultvalue, stack) #
            end_stack.append(pop_data) #
    return data

Das Programm, das den ersten Punkt angibt, ist fast das gleiche wie das vorherige. Der Unterschied besteht darin, dass die Koordinatendaten in den Stapel eingefügt werden, sodass sich der Rückgabewert ändert und intern in den Stapel eingefügt wird.

new_fill.py


def plot_point(data, plot, stack):
    defaultvalue = data[plot["z"]][plot["y"]][plot["x"]]
    data[plot["z"]][plot["y"]][plot["x"]]=2
    stack.append(plot)
    return data, defaultvalue

Sie haben gerade "stack.append (plot)" hinzugefügt.

Und obwohl es sich um eine Funktion handelt, die die Umgebung ausfüllt, ist dies die Funktion, die ursprünglich den Neustartaufruf ausgeführt hat. Dieses Mal fülle ich mich einfach selbst und lege die umgebenden nicht gesuchten Koordinaten in den Stapel Es ist eine Funktion wie.

new_fill.py


def step_fill(data, x, y, z, defaultvalue, stack):
    data[z][y][x]=2
        
    if (data[z][y][x-1]==defaultvalue) and (not {"x":x-1, "y":y, "z":z} in stack):
        stack.append({"x":x-1, "y":y, "z":z})

    if (data[z][y][x+1]==defaultvalue) and (not {"x":x+1, "y":y, "z":z} in stack):
        stack.append({"x":x+1, "y":y, "z":z})
        
    if (data[z][y-1][x]==defaultvalue) and (not {"x":x, "y":y-1, "z":z} in stack):
        stack.append({"x":x, "y":y-1, "z":z})

    if (data[z][y+1][x]==defaultvalue) and (not {"x":x, "y":y+1, "z":z} in stack):
        stack.append({"x":x, "y":y+1, "z":z})

    if (data[z-1][y][x]==defaultvalue) and (not {"x":x, "y":y, "z":z-1} in stack):
        stack.append({"x":x, "y":y, "z":z-1})

    if (data[z+1][y][x]==defaultvalue) and (not {"x":x, "y":y, "z":z+1} in stack):
        stack.append({"x":x, "y":y, "z":z+1})
    return data

Es ist einfach. Ich habe das Gefühl, dass ich etwas Schöneres schreiben kann, also werde ich darüber nachdenken.

Mit den oben genannten drei können Sie 3D-Füllung implementieren.

Übrigens habe ich die Zeit des vorherigen ursprünglichen Experiments verglichen.

Vorherige Füllung Diese Füllung
1 0.004987001419067383 0.12566423416137695
2 0.003987789154052734 0.10970711708068848
3 0.003989219665527344 0.11269998550415039
4 0.004986763000488281 0.11568784713745117
5 0.00598454475402832 0.11369585990905762
6 0.015959978103637695 0.11469197273254395
7 0.004986763000488281 0.11768507957458496
8 0.003989934921264648 0.11369562149047852
9 0.003988981246948242 0.1136932373046875
10 0.005983829498291016 0.11469554901123047
durchschnittlich 0.00588448047637 0.115191650390625

Die Bearbeitungszeit hat sich um das 200-fache erhöht. Vielleicht gibt es eine Mischung aus nutzloser Verarbeitung, also werde ich noch einmal darüber nachdenken.

Recommended Posts

Eine Geschichte über die Verbesserung des Programms zum teilweisen Füllen von binärisierten 3D-Bilddaten
Die Geschichte des Exportierens eines Programms
Programm zur Suche nach demselben Bild
Bildverarbeitung? Die Geschichte, Python für zu starten
Eine Geschichte über die Änderung des Master-Namens von BlueZ
Die Geschichte der Einrichtung eines VIP-Kanals im internen Chatwork
Eine Geschichte über das Clustering von Zeitreihendaten des Austauschs
Die Geschichte, einen Standardtreiber für db mit Python zu erstellen.
[AtCoder für Anfänger] Sprechen Sie über den Rechenaufwand, den Sie grob wissen möchten
Eine Geschichte über den Versuch, den Testprozess eines 20 Jahre alten Systems in C zu verbessern
Eine Geschichte über das Erstellen eines Programms, mit dem die Anzahl der Instagram-Follower in einer Woche von 0 auf 700 erhöht wird
Latein lernen zum Schreiben eines lateinischen Satzanalyseprogramms (Teil 1)
Eine Geschichte von einer Person, die von Anfang an auf Datenwissenschaftler abzielte
Die Geschichte der Verarbeitung A von Blackjack (Python)
[Einführung in Python] So erhalten Sie den Datenindex mit der for-Anweisung
Die Geschichte, dass die Lernkosten von Python niedrig sind
Schreiben Sie eine Notiz über die Python-Version von Python Virtualenv
Die Geschichte des Lesens von HSPICE-Daten in Python
Die Geschichte eines Mel-Icon-Generators
[Kleine Geschichte] Laden Sie das Bild von Ghibli sofort herunter
Geschichte rund um die Datenanalyse durch maschinelles Lernen
Die Geschichte des Wechsels von WoSign zu Let's Encrypt für ein kostenloses SSL-Zertifikat
Programm, das die CSV-Daten der Transaktionshistorie der SBI Securities-Aktie zusammenfasst [Python3]
Eine Geschichte über den Versuch, Linter mitten in einem Python (Flask) -Projekt vorzustellen
Erstellt ein Narrbild für das Modell der Untertitelgenerierung
Die Geschichte des Starts eines Minecraft-Servers von Discord
[Python] Ein Programm, das die Anzahl der Täler zählt
Ein Memorandum über Warnungen in Pylint-Ausgabeergebnissen
Generieren Sie aus Textdaten ein vertikales Bild eines Romans
Die Geschichte eines neuronalen Netzwerks der Musikgeneration
Über die Ineffizienz der Datenübertragung im luigi on-memory
Geschichte der Bildanalyse von PDF-Dateien und Datenextraktion
Eine Geschichte über das Problem, 3 Millionen ID-Daten in einer Schleife zu verarbeiten
Zip 4 Gbyte Problem ist eine Geschichte der Vergangenheit
Eine Geschichte, die die Lieferung von Nico Nama analysierte.
Ein Memorandum über die Umsetzung von Empfehlungen in Python
[Python] Ein Programm, das die Positionen von Kängurus vergleicht.
Die Geschichte der Schaffung eines "Geist- und Zeit-Chatrooms" exklusiv für Ingenieure im Unternehmen
Eine Geschichte über das Finden des längsten Drucks einer bestimmten Wortgruppe durch Ignorieren der Pistole für den Berechnungsbetrag
Über den Inhalt von wscript beim Erstellen einer solchen D-Sprachumgebung mit Waf
Eine Geschichte über die Portierung des Codes "Versuchen Sie zu verstehen, wie Linux funktioniert" nach Rust