Dies ist der Quellcode und das vorab trainierte Modell für die Webcam pix2pix-Demo, die ich kürzlich auf Twitter und Vimeo gepostet habe. Es nutzt Deep Learning, oder um ein paar Schlagworte zu verwenden: Deep Convolutional Conditional Conditional Generative Adversarial Network Autoencoder .
Video 1
Video 2
Der Code in diesem speziellen Repo hat eigentlich nichts mit pix2pix, GANs oder sogar Deep Learning zu tun. Es lädt einfach jedes vorab trainierte Tensorflow-Modell (sofern es einige Einschränkungen erfüllt), füttert es mit einer verarbeiteten Webcam-Eingabe und zeigt die Ausgabe des Modells an. Zufälligerweise ist das Modell, das ich trainiert und verwendet habe, pix2pix (Details unten).
Dh die Schritte können wie folgt zusammengefasst werden:
Ich habe Kunstsammlungen aus der ganzen Welt aus dem Google Art Project auf Wikimedia herausgesucht. Bei vielen Bildern handelt es sich um klassische Porträts reicher weißer Typen, daher habe ich nur etwa 150 Sammlungen verwendet und versucht, die Daten geografisch und kulturell so vielfältig wie möglich zu halten (die vollständige Liste, die ich verwendet habe, finden Sie hier). Aber die Daten sind immer noch sehr eurozentrisch, da es Hunderte oder Tausende von Scans aus einem einzigen europäischen Museum geben kann, aber nur 8 Scans aus einem arabischen Museum.
Ich habe die 300-Pixel-Versionen der Bilder heruntergeladen und einen Batch-Prozess ausgeführt, um Folgendes zu erreichen:
Ich habe auch einen Stapelprozess durchgeführt, um mehrere Ausschnitte aus den Bildern zu erstellen (anstelle einer ungleichmäßigen Größenänderung), aber ich habe das noch nicht trainiert. Anstelle der raffinierten Kantenerkennung habe ich mich auch mit der viel besseren „Holistically-Nested Edge Detection“ (auch bekannt als HED) von Xie und Tu befasst (wie sie im ursprünglichen pix2pix-Artikel verwendet wurde), habe aber auch damit noch nicht trainiert.
Dies erfolgt durch das Skript preprocess.py (leider keine Befehlszeilenargumente, bearbeiten Sie das Skript, um Pfade und Einstellungen zu ändern, sollte ziemlich selbsterklärend sein).
Eine kleine Auswahl der Trainingsdaten – einschließlich Vorhersagen des trainierten Modells – ist hier zu sehen. Die Spalte ganz rechts ist das Originalbild, die Spalte ganz links ist die vorverarbeitete Version. Diese beiden Bilder werden als „Paar“ zum Trainieren in das pix2pix-Netzwerk eingespeist. Die mittlere Spalte ist das, was das Modell erzeugen lernt , wenn nur die Spalte ganz links vorhanden ist . (Die Bilder zeigen jede Trainingsiteration – d. h. die Zahl auf der linken Seite, die von 20.000 auf 58.000 reicht. Sie wird also allmählich besser, je weiter man auf der Seite nach unten geht.)
Ich habe auch ein bedingungsloses GAN (d. h. normales DCGAN) auf denselben Trainingsdaten trainiert. Ein Beispiel für seine Ausgabe ist unten zu sehen. (Dadurch werden „völlig zufällige“ Bilder generiert, die den Trainingsdaten ähneln).
Das Training und die Architektur basieren direkt auf „ Image-to-Image Translation with Conditional Adversarial Nets “ von Isola et al. (auch bekannt als pix2pix). Ich habe mit dem Tensorflow-Port von @affinelayer (Christopher Hesse) trainiert, der auch die „Sketch-to-Cat“-Demo antreibt, die kürzlich viral ging. Er hat auch ein schönes Tutorial darüber geschrieben, wie pix2pix funktioniert. Unendlichen Dank an die Autoren (und alle, auf denen sie aufgebaut haben), dass sie ihren Code als Open-Source-Lösung bereitgestellt haben!
Ich habe nur eine winzig kleine Änderung am Trainingscode tensorflow-pix2pix vorgenommen, und zwar das Hinzufügen von tf.Identity zu den Ein- und Ausgängen des Generators mit einem für Menschen lesbaren Namen, damit ich die Tensoren problemlos füttern und abrufen kann. Wenn Sie also Ihre eigenen Modelle mit dieser Anwendung verwenden möchten, müssen Sie dasselbe tun . (Oder notieren Sie sich die Eingabe-/Ausgabe-Tensornamen und ändern Sie den JSON entsprechend, mehr dazu weiter unten).
Sie können mein vorab trainiertes Modell über die Registerkarte „Releases“ herunterladen.
Diese spezielle Anwendung lädt das vorab trainierte Modell, führt eine Live-Vorverarbeitung einer Webcam-Eingabe durch und speist sie in das Modell ein. Ich mache die Vorverarbeitung mit altmodischer grundlegender Computer Vision und verwende opencv. Es ist wirklich sehr minimalistisch und einfach. Sie können die GUI unten sehen (die GUI verwendet pyqtgraph).
Unterschiedliche Szenen erfordern unterschiedliche Einstellungen.
Für „Live-Action“ habe ich beispielsweise festgestellt, dass die Funktion (meiner Meinung nach) bessere Ergebnisse liefert, und ich habe sie auch im ersten Video oben verwendet. Die Schwellenwerte (canny_t1, canny_t2) hängen von der Szene, der Detailgenauigkeit und dem gewünschten Aussehen ab.
Wenn Ihr Bild viel Rauschen aufweist, können Sie ein wenig pre_blur oder pre_median hinzufügen. Oder spielen Sie mit ihnen, um einen „künstlerischen Effekt“ zu erzielen. Beispielsweise füge ich im ersten Video bei etwa 1:05–1:40 eine Menge Median hinzu (Werte um 30–50).
Beim Zeichnen von Szenen (z. B. zweites Video) habe ich herausgefunden, dass der adaptive Schwellenwert interessantere Ergebnisse liefert als „Canny“ (z. B. „Canny deaktivieren“ und „Adaptiver Schwellenwert“ aktivieren), auch wenn Sie vielleicht anderer Meinung sind.
Bei einer vollständig statischen Eingabe (z. B. wenn Sie die Aufnahme einfrieren oder die Kameraaktualisierung deaktivieren) flackert die Ausgabe wahrscheinlich sehr geringfügig, da das Modell unterschiedliche Vorhersagen für dieselbe Eingabe trifft – obwohl dies normalerweise recht subtil ist. Bei einem Live -Kamera-Feed führt das Rauschen in der Eingabe jedoch wahrscheinlich zu starkem Flackern in der Ausgabe, insbesondere aufgrund der hohen Anfälligkeit von Canny- oder adaptiven Schwellenwerten für Rauschen, sodass eine gewisse zeitliche Unschärfe hilfreich sein kann.
accum_w1 und accum_w2 dienen zur zeitlichen Unschärfe der Eingabe, bevor in das Modell eingestiegen wird: new_image = old_image * w1 + new_image * w2 (im Idealfall sollten sie also eins ergeben – oder nahe daran).
Prediction.pre_time_lerp und post_time_lerp führen auch eine zeitliche Glättung durch: new_image = old_image * xxx_lerp + new_image * (1 - xxx_lerp) pre_time_lerp befindet sich vor dem Eintritt in das Modell und post_time_lerp erfolgt nach dem Verlassen des Modells.
Null für eine der zeitlichen Unschärfen deaktiviert sie. Die Werte hierfür hängen von Ihrem Geschmack ab. Für die beiden oben genannten Videos hatte ich alle pre_model-Unschärfen (also accum_w1, accum_w2 und pre_time_lerp) auf Null gesetzt und mit unterschiedlichen post_time_lerp-Einstellungen abgespielt, die von 0,0 (sehr flimmernd und blinkend) bis 0,9 (sehr langsam und verblasst und „verträumt“) reichten. ). Normalerweise liegt mein Lieblingsbereich zwischen 0,5 und 0,8.
Wenn Sie ein anderes Modell verwenden möchten, müssen Sie eine JSON-Datei ähnlich der folgenden einrichten. Die Motivation hierfür ist, dass ich tatsächlich eine Reihe von JSONs in meinem Ordner „app/models“ habe, die ich dynamisch scannen und neu laden kann, und die Modelldaten an anderer Stelle auf anderen Festplatten gespeichert sind und die App Modelle zur Laufzeit und im Maßstab laden und zwischen ihnen wechseln kann Ein-/Ausgänge usw. automatisch.
{
"name" : "gart_canny_256", # name of the model (for GUI)
"ckpt_path" : "./models/gart_canny_256", # path to saved model (meta + checkpoints). Loads latest if points to a folder, otherwise loads specific checkpoint
"input" : { # info for input tensor
"shape" : [256, 256, 3], # expected shape (height, width, channels) EXCLUDING batch (assumes additional axis==0 will contain batch)
"range" : [-1.0, 1.0], # expected range of values
"opname" : "generator/generator_inputs" # name of tensor (':0' is appended in code)
},
"output" : { # info for output tensor
"shape" : [256, 256, 3], # shape that is output (height, width, channels) EXCLUDING batch (assumes additional axis==0 will contain batch)
"range" : [-1.0, 1.0], # value range that is output
"opname" : "generator/generator_outputs" # name of tensor (':0' is appended in code)
}
}
Nur auf Ubuntu 16.04 getestet, sollte aber auf anderen Plattformen funktionieren.
Ich verwende die Anaconda-Python-Distribution, die fast alles enthält, was Sie brauchen. Dann ist es (hoffentlich) so einfach wie:
Laden Sie Anaconda von https://www.continuum.io/downloads herunter und installieren Sie es
Tensorflow installieren https://www.tensorflow.org/install/ (Was – wenn Sie Anaconda haben – oft recht einfach ist, da die meisten Abhängigkeiten enthalten sind)
Installieren Sie opencv und pyqtgraph
conda install -c menpo opencv3 conda install pyqtgraph
Nochmals vielen Dank an