Reproduzieren von Bildern mit geometrischen Primitiven.
Ein Zielbild wird als Eingabe bereitgestellt. Der Algorithmus versucht, die optimalste Form zu finden, die gezeichnet werden kann, um den Fehler zwischen dem Zielbild und dem gezogenen Bild zu minimieren. Es wiederholt diesen Vorgang und fügt jeweils eine Form hinzu. Es sind rund 50 bis 200 Formen erforderlich, um ein Ergebnis zu erzielen, das erkennbar und dennoch künstlerisch und abstrakt ist.
Jetzt als native Mac -Anwendung erhältlich!
https://primitive.lol/
Folgen Sie @PrimitivePic auf Twitter, um alle 30 Minuten ein neues primitives Bild zu sehen!
Der Twitter -Bot sucht nach interessanten Fotos mit der Flickr -API, führt den Algorithmus mit randomisierten Parametern aus und veröffentlicht das Bild mit der Twitter -API.
Sie können ein Bild dem Bot twittern und es wird es für Sie verarbeiten.
Führen Sie es auf Ihre eigenen Bilder aus! Installieren Sie zuerst Go.
go get -u github.com/fogleman/primitive
primitive -i input.png -o output.png -n 100
Es sollten kleine Eingangsbilder verwendet werden (wie 256x256px). Sie brauchen das Detail sowieso nicht und der Code wird schneller ausgeführt.
Flagge | Standard | Beschreibung |
---|---|---|
i | n / A | Eingabedatei |
o | n / A | Ausgabedatei |
n | n / A | Anzahl der Formen |
m | 1 | Modus: 0 = Kombination, 1 = Dreieck, 2 = Rechte |
rep | 0 | Fügen Sie n zusätzliche Formen jede Iteration mit reduzierter Suche hinzu (meistens gut für Beziers) |
nth | 1 | Speichern Sie jeden N -ten Frame (nur wenn %d im Ausgangspfad ist) |
r | 256 | Größen Sie die Größe der Größe großer Eingangsbilder zu dieser Größe vor der Verarbeitung |
s | 1024 | Ausgabe Bildgröße |
a | 128 | Farbe Alpha (Verwenden Sie 0 , um den Algorithmus für jede Form Alpha zu wählen). |
bg | avg | Hintergrundfarbe beginnen (Hex) |
j | 0 | Anzahl der parallelen Arbeiter (Standard verwendet alle Kerne) |
v | aus | ausführliche Ausgabe |
vv | aus | Sehr ausführliche Ausgabe |
Abhängig von der vorgestellten Ausgabe -Dateiname -Erweiterung können Sie verschiedene Arten von Ausgabe erzeugen.
PNG
: RasterausgangJPG
: RasterausgangSVG
: VektorausgabeGIF
: Animierte Ausgabe, die zu hinzugefügtem Formen hinzugefügt wird - erfordert Imagemagick (insbesondere der Befehl convert
) Für PNG- und SVG -Ausgänge können Sie auch %d
, %03d
usw. in den Dateinamen aufnehmen. In diesem Fall wird jeder Frame separat gespeichert.
Sie können das -o
-Flag mehrmals verwenden. Auf diese Weise können Sie beispielsweise sowohl ein PNG als auch eine SVG speichern.
Dieses GIF demonstriert die iterative Natur des Algorithmus und versucht, den mittleren quadratischen Fehler zu minimieren, indem sie jeweils eine Form hinzufügen. (Verwenden Sie eine ".gif" -Angabedatei, um selbst eine zu generieren!)
Da der Algorithmus eine zufällige Komponente hat, können Sie ihn mehrmals gegen dasselbe Eingabebild ausführen, um ein statisches Bild zu Leben zu führen.
Wenn Sie bereit sind, sich im Code zu beschäftigen, können Sie Einschränkungen der Formen durchsetzen, um noch interessantere Ergebnisse zu erzielen. Hier sind die Rechtecke gezwungen, in diesem Bild eines Pyramidensonnenuntergangs auf die Sonne hinzuweisen.
Die folgende Matrix zeigt Dreiecke, Ellipsen und Rechtecke bei jeweils 50, 100 und 200 Iterationen.
Sagen Sie, wir haben ein Target Image
. Das ist es, was wir auf Nachdenken hinarbeiten. Wir beginnen mit einer leeren Leinwand, aber wir füllen es mit einer einzigen festen Farbe. Derzeit ist dies die durchschnittliche Farbe des Target Image
. Wir nennen diese neue leere Leinwand das Current Image
. Jetzt beginnen wir mit der Bewertung von Formen. Um eine Form zu bewerten, zeichnen wir sie über das Current Image
und erzeugen ein New Image
. Dieses New Image
wird mit dem Target Image
verglichen, um eine Punktzahl zu berechnen. Wir verwenden den Root-Mean-Quadrat-Fehler für die Punktzahl.
Current Image + Shape => New Image
RMSE(New Image, Target Image) => Score
Die Formen werden zufällig erzeugt. Wir können eine zufällige Form erzeugen und sie bewerten. Dann können wir die Form mutieren (indem wir einen Triangle -Scheitelpunkt optimieren, einen Ellipse -Radius oder -Zentrum usw. optimieren und ihn erneut bewerten. Wenn die Mutation die Punktzahl verbesserte, behalten wir sie. Ansonsten rollen wir zum vorherigen Zustand. Das Wiederholen dieses Vorgangs wird als Hügelklettern bezeichnet. Das Klettern des Hügels neigt dazu, in der lokalen Minima festzuhalten, sodass wir so viele Male mit verschiedenen Startformen tun. Wir können auch zufällige Formen generieren und das Beste auswählen, bevor wir mit dem Hügelklettern beginnen. Simuliertes Glühen ist eine weitere gute Option, aber in meinen Tests fand ich die Hügelklettertechnik genauso gut und schneller, zumindest für dieses spezielle Problem.
Sobald wir eine gute Formularform gefunden haben, fügen wir sie dem Current Image
hinzu, wo es unverändert bleibt. Dann beginnen wir den Prozess erneut, um die nächste Form zum Zeichnen zu finden. Dieser Vorgang wird so oft wie gewünscht wiederholt.
Die folgenden Primitiven werden unterstützt:
Weitere Formen können hinzugefügt werden, indem die folgende Schnittstelle implementiert wird:
type Shape interface {
Rasterize () [] Scanline
Copy () Shape
Mutate ()
Draw ( dc * gg. Context )
SVG ( attrs string ) string
}
Dieses Projekt wurde ursprünglich von der beliebten und hervorragenden Arbeit von Roger Johansson - Genetic Programming: Evolution of Mona Lisa - inspiriert. Seitdem ich diesen Artikel gesehen habe, als er ziemlich neu war, habe ich hier und da dieses Problem im Laufe der Jahre bastelt. Aber erst jetzt bin ich mit meinen Ergebnissen zufrieden.
Es ist zu beachten, dass es im Vergleich zu Rogers ursprünglicher Arbeit signifikante Unterschiede in meiner Implementierung gibt. Meins ist kein genetischer Algorithmus. Mine arbeitet jeweils nur in einer Form. Meins ist viel schneller (AFAIK) und unterstützt viele Arten von Formen.
Hier sind weitere Beispiele von interessanten Fotos, die auf Flickr gefunden wurden.