Texturesynthesis: Unterschied zwischen den Versionen
(→MRFsynthesis: Lizenzfrage ist geklärt, siehe Diskussion.) |
K (→Was ist Texturesynthesis?) |
||
(Eine dazwischenliegende Version von einem anderen Benutzer wird nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
== Was ist Texturesynthesis? == | == Was ist Texturesynthesis? == | ||
− | Häufig steht man vor dem Problem, dass man zwar in Textursammlung XY eine vom Prinzip | + | Häufig steht man vor dem Problem, dass man zwar in Textursammlung XY eine vom Prinzip her schöne [[Textur]] gefunden hat, diese jedoch aus diversen Gründen nicht sinnvoll nutzbar ist. Ein paar Beispiele: |
− | * | + | * Die Textur ist zu klein. Würde man die Textur kacheln, sähe man dies sofort. |
− | * | + | * Die Textur ist ein Foto und daher gar nicht kachelbar. |
− | * | + | * Die Textur hat einige kleinere Stellen die "doof" aussehen. Beispielsweise größere Schatten in einer Fototextur können merkwürdig aussehen, wenn das Licht in der Szene nicht aus der entsprechenden Richtung kommt. Gleiches gilt für besonders auffällige Elemente deren Wiederholung man sofort sehen würde. |
− | Sofern es sich um eine Textur mit nur lokaler Struktur handelt und man etwas Rechenleistung investiert kann man diese Mängel ohne Verlust an Qualität beheben! | + | Sofern es sich um eine Textur mit nur lokaler Struktur handelt und man etwas Rechenleistung investiert, kann man diese Mängel ohne Verlust an Qualität beheben! |
− | Texturesynthesis ist die Wissenschaft die sich damit beschäftigt die grundlegende Struktur einer Textur weiterzuführen OHNE Wiederholungen zu erzeugen. Der Standardalgorithmus beginnt mit einer Zufallstextur mit RGB-rauschen. Nun wird die Textur Pixel für Pixel durchlaufen und jeweils der Pixel aus der Inputtextur gewählt, dessen lokale Nachbarschaft best-möglich zum aktuellen Pixel passt. | + | Texturesynthesis ist die Wissenschaft, die sich damit beschäftigt die grundlegende Struktur einer Textur weiterzuführen, OHNE Wiederholungen zu erzeugen. Der Standardalgorithmus beginnt mit einer Zufallstextur mit RGB-rauschen. Nun wird die Textur Pixel für Pixel durchlaufen und jeweils der Pixel aus der Inputtextur gewählt, dessen lokale Nachbarschaft best-möglich zum aktuellen Pixel passt. |
− | Das ganze klappt nicht bei jeder Textur, erfordert etwas Rechenleistung, aber prinzipiell kann man aus einer kleinen Quelltextur beliebig große, kachelbare Texturen | + | Das ganze klappt nicht bei jeder Textur, erfordert etwas Rechenleistung, aber prinzipiell kann man aus einer kleinen Quelltextur beliebig große, kachelbare Texturen erzeugen! Ebenfalls ist es möglich, nur Teilbereiche einer Textur neu zu erzeugen. |
== Beispiele == | == Beispiele == | ||
Zeile 50: | Zeile 50: | ||
nonparaMRF_fast -n 2 -square -cyclic -x 1300 -y 1300 texinput1.png | nonparaMRF_fast -n 2 -square -cyclic -x 1300 -y 1300 texinput1.png | ||
− | Der Parameter '''-n''' ist der wichtigste, er gibt den Radius an in dem die Pixel verglichen werden. Möglich sind 1,2,3 und 4. Ein größerer Wert erfordert mehr Rechenleistung. Es hängt aber von der Struktur der Textur ab, ob man auch ein schöneres Ergebnis erhält. Man sollte mal 2 und 3 probieren. Der Parameter '''-square''' bewirkt das statt der üblichen 2-norm die | + | Der Parameter '''-n''' ist der wichtigste, er gibt den Radius an in dem die Pixel verglichen werden. Möglich sind 1,2,3 und 4. Ein größerer Wert erfordert mehr Rechenleistung. Es hängt aber von der Struktur der Textur ab, ob man auch ein schöneres Ergebnis erhält. Man sollte mal 2 und 3 probieren. Der Parameter '''-square''' bewirkt das statt der üblichen 2-norm die Maximumdistanz verwendet wird. Was das heißt sieht man am besten auf dem folgenden Bild:<br> |
[[Bild:neighbourhood.png]] | [[Bild:neighbourhood.png]] | ||
Aktuelle Version vom 19. März 2014, 16:12 Uhr
Inhaltsverzeichnis
Was ist Texturesynthesis?
Häufig steht man vor dem Problem, dass man zwar in Textursammlung XY eine vom Prinzip her schöne Textur gefunden hat, diese jedoch aus diversen Gründen nicht sinnvoll nutzbar ist. Ein paar Beispiele:
- Die Textur ist zu klein. Würde man die Textur kacheln, sähe man dies sofort.
- Die Textur ist ein Foto und daher gar nicht kachelbar.
- Die Textur hat einige kleinere Stellen die "doof" aussehen. Beispielsweise größere Schatten in einer Fototextur können merkwürdig aussehen, wenn das Licht in der Szene nicht aus der entsprechenden Richtung kommt. Gleiches gilt für besonders auffällige Elemente deren Wiederholung man sofort sehen würde.
Sofern es sich um eine Textur mit nur lokaler Struktur handelt und man etwas Rechenleistung investiert, kann man diese Mängel ohne Verlust an Qualität beheben!
Texturesynthesis ist die Wissenschaft, die sich damit beschäftigt die grundlegende Struktur einer Textur weiterzuführen, OHNE Wiederholungen zu erzeugen. Der Standardalgorithmus beginnt mit einer Zufallstextur mit RGB-rauschen. Nun wird die Textur Pixel für Pixel durchlaufen und jeweils der Pixel aus der Inputtextur gewählt, dessen lokale Nachbarschaft best-möglich zum aktuellen Pixel passt.
Das ganze klappt nicht bei jeder Textur, erfordert etwas Rechenleistung, aber prinzipiell kann man aus einer kleinen Quelltextur beliebig große, kachelbare Texturen erzeugen! Ebenfalls ist es möglich, nur Teilbereiche einer Textur neu zu erzeugen.
Beispiele
Dank freundlicher Genehmigung von cgtextures.com kann ich hier einige Beispiele präsentieren. Die folgenden Beispiel-Texturen unterliegen wie das gesamte Wiki der GNU Free Documentation License 1.2. Dies gilt jedoch ausschließlich für die Texturen in diesem Artikel. Texturen die von cgtextures.com heruntergeladen werden sind urheberrechtlich geschützt und unterliegen nicht dieser Lizenz! |
Das erste Beispiel wurde mit dem Programm MRFsynthesis erstellt. Die Input-Textur ist links zu sehen. In der Masken-Textur rechts sind unerwünschte Bereiche mit schwarz (RGB: 0,0,0) übermalt. Die Textur hatte eine Originalgröße von 1600x1200 und wurde vor Anwendung des Tools auf 683x512 herunter skaliert.
Als Output bekommt man diese kachelbare Textur. Sie hat im Original eine Auflösung von 1300x1300.
Ein weiteres Beispiel mit einer anderen Texturart. Auch dieses Beispiel wurde mit MRFsynthesis erzeugt. Die Schwierigkeit liegt hier darin, dass der Algorithmus nicht weiß was eine Pflanze ist, geschweige denn, wie eine Pflanze auszusehen hat. Die Masken Textur wurde etwas aufgehellt, da die Risse in der Erde sehr dunkel sind und sonst möglicherweise ausgeschlossen würden.
Die Qualität der Erd-Risse in der Outputtextur ist sehr gut. Insbesondere in der Originalauflösung (roter Kasten) sieht man den hohen Detailgrad. Die Pflanzen sehen allerdings leicht abgewetzt aus, da sie zum Teil nur aus einem einzigen Blatt bestehen.
Das folgende Beispiel demostriert die Fähigkeiten des Algorithmus auch "doofe" Stellen aus einem Bild zu entfernen ohne das Bild vollständig neu zu konstruieren. Wen blöde Stromleitungen auf Urlaubsbildern nerven, dem kann geholfen werden. Das Bild wurde mit dem GIMP-Plugin Resynthesizer bearbeitet.
Tools
Es gibt viele verschiedene Tools die diese Technik beherrschen. Im folgenden werden einige davon vorgestellt. Es gibt aber sicher noch mehr, einfach mal googlen.
MRFsynthesis
Das Tool hat den klangvollen Namen "Semi Causal Nonparametric Markov Random Field Texture Synthesis", oder kurz "MRFsynthesis". Es gibt kein Binary, aber der Quellcode ist hier verfügbar. In den einzelnen Quellcodedateien findet sich ein Lizenztext als Kommentar. Die mit MRFsynthesis erzeugten Texturen dürfen für beliebige Zwecke eingesetzt werden, also insbesondere auch kommerziell. Das Tool selbst ist kostenlos verfügbar und darf auch verändert werden. Es darf jedoch nicht kommerziell verbreitet werden.
Vermutlich, da der Code aus dem Jahr 2002 stammt, muss man leider etwas am Quellcode fummeln bis aktuelle Compiler den Code akzeptieren. Sollte aber ziemlich offensichtlich sein, in Option.h musste ich ein using namespace std; hinzufügen und in nr.h zweimal eine ungenutzte Funktion fmin auskommentieren. Ich nutze Fedora 10 Linux mit gcc 4.3.2 und kann daher nichts darüber sagen, ob es möglich ist das ganze unter Windows zum laufen zu bringen.
Das Programm ist leider nicht für Mehrkern-CPUs geschrieben, man kann aber einfach für jeden Kern das Programm einmal starten. Man muss sowieso immer etwas an den Parametern spielen, bis man ein sinnvolles Ergebnis erhält. Je nach verwendetem Algorithmus und Größe der Textur kann das ganze durchaus ein paar Stunden dauern. Die Texturgröße geht stark in die Laufzeit ein, im Vergleich zum Resynthesizer ist das Programm ziemlich langsam.
Als Inputdatei sollte man ein PNG wählen. Zum einen geht so keine Qualität verloren, zum anderen produziert das Programm aus irgendeinem Grund beim speichern von JPG Dateien einen schwarzen Balken am oberen Bildrand. Wenn man Probleme mit Rauschen im Ergebnis hat, kann man die Ausgabeauflösung etwas höher wählen und nachher das Bild herunter skalieren.
Algorithmen
MRFsynthesis implementiert verschiedene Variationen des Algorithmus. Die Unterschiede sind in der beiliegenden Readme beschrieben, verstehen tut man diese vermutlich aber nur nach der Lektüre des Papers, welches ich nicht gelesen habe.
- nonparaMRF : der Standardalgorithmus?
- nonparaMRF_fast : eine schnellere Version die einen QuadTree (?) verwendet
- nonparaMRF_fast_k : eine 2D-Variante von nonparaMRF_fast, was immer das bedeutet...
- nonparaMRF_gaussian_k : verwendet eine "Gaussian pyramid" als Suchalgorithmus
Es hängt wahrscheinlich von der Quelltextur ab welcher Algorithmus sich am besten eignet. Einfach ausprobieren...
Parameter
Ein Beispielaufruf sieht so aus:
nonparaMRF_fast -n 2 -square -cyclic -x 1300 -y 1300 texinput1.png
Der Parameter -n ist der wichtigste, er gibt den Radius an in dem die Pixel verglichen werden. Möglich sind 1,2,3 und 4. Ein größerer Wert erfordert mehr Rechenleistung. Es hängt aber von der Struktur der Textur ab, ob man auch ein schöneres Ergebnis erhält. Man sollte mal 2 und 3 probieren. Der Parameter -square bewirkt das statt der üblichen 2-norm die Maximumdistanz verwendet wird. Was das heißt sieht man am besten auf dem folgenden Bild:
Der Parameter -cyclic bewirkt das die Textur kachelbar wird. Mit -x und -y gibt man die Größe der Outputtextur an.
Praktisch ist ebenfalls der -m Parameter. Damit kann man "doofe" Stellen in der Inputtextur ausblenden. Einfach die Quelltextur nehmen und mit schwarzer Farbe alles ausradieren was nicht gefällt. Alle Pixel die Farbe RGB 0,0,0 haben werden ignoriert. Sollten sich erwünschte Pixel mit dieser Farbe in der Textur befinden, sollte man vorher die Helligkeit der Masken-Textur erhöhen, z.B. indem man einen dunklen Grauwert aufaddiert. Auf das Ergebnis hat dies keinen Einfluss, da die eigentlichen Farbwerte aus der Inputtextur kommen.
Weitere Parameter sind in der beliegenden Readme beschrieben.
Für das erste Beispiel (siehe oben) habe ich die folgenden Parameter benutzt:
nonparaMRF_fast -n 2 -square -cyclic -x 1300 -y 1300 -m rock_mask.png rock_input.png
Das zweite Beispiel wurde mit folgender Befehlszeile berechnet:
nonparaMRF_fast -n 3 -square -cyclic -x 1300 -y 1300 -m earth_mask.png earth_input.png
Die Rechenzeit betrug auf meinem Intel Core 2 Quad Q9300 jeweils etwa 2-3 Stunden. Allerdings wurde natürlich nur ein Core genutzt und die CPU läuft bei mir zudem auf 2.0 GHz statt 2.5 GHz.
Resynthesizer
Der Resynthesizer ist ein Plugin für das beliebte Grafikprogramm GIMP. Sowohl GIMP als auch das Plugin sind freie Software, also insbesondere kostenlos und auch kommerziell nutzbar.
Von der Qualität her ist das Plugin mit MRFsynthesis vergleichbar. Durch die Integration in GIMP ist die Bedienung deutlich einfacher als über die Kommandozeile. Zudem hat Resynthesizer mehr Features und ist darüberhinaus wesentlich schneller. Da die Laufzeit weniger abhängig von der Texturgröße ist kann man mit wesentlich höheren Auflösungen arbeiten.
Auch der Resynthesizer setzt nur einen CPU-core ein und bei entsprechend hohen Auflösungen lohnt es sich mehrere Texturen gleichzeitig zu generieren. Wenn man es geschickt anstellt kann es auch sinnvoll sein mehrere Texturen zu generieren und dann nachträglich zusammenzufügen. Dies dürfte sich aber erst bei richtig hohen Auflösungen jenseits von 4096x4096 lohnen.
Die Bedienung ist recht simpel. Zunächst lädt man die gewünschte Quelltextur in GIMP und markiert dort alle Bereiche die man nicht für die Textur Generierung verwenden möchte. Man sollte daran denken, dass man die Kantenglättung der Markierung ausschaltet. Dann erstellt man ein neues Bild mit der gewünschten Auflösung und wählt im Menü
- Filter -> Abbilden -> Resynthesize...
Daraufhin öffnet sich das folgende Fenster.
Oben kann man die Texturquelle angeben, wir können aus den gerade mit GIMP geöffneten Bilddateien auswählen. Insbesondere kann auch die Quelle mit dem Ziel identisch sein. Die Haken bezüglich horizontalem und vertikalem Tiling sollten klar sein. Ist in der Zieltextur ein Bereich markiert, so bewirkt ein Haken bei "Fit output to bordering pixels", dass die neu erzeugte Textur nahtlos in den bereits bestehenden Bereich übergeht. Auch hier sollte man daran denken, dass man die Kantenglättung der Markierung ausschaltet.
Hier kann man einige Parameter des Algorithmus beeinflussen. Es hängt von der Quelltextur ab welche Einstellung hier gut ist. Die Standardeinstellung erzeugt aber meistens bereits gute Resultate.
Das Plugin fügt auch noch ein paar Skripte zu GIMP hinzu die man mal austesten sollte:
- Script-Fu -> Enhance -> Smart enlarge
- Bild skalieren ohne Schärfe zu verlieren
- Script-Fu -> Enhance -> Smart sharpen
- Bild schärfen unter Einsatz von Textursynthese
- Script-Fu -> Enhance -> Smart remove selection
- ersetzt den markierten Bereich durch eine synthetische Textur
Perspektivenkorrektur
Als Abschluss möchte ich noch erwähnen, dass es mittlerweile auch eine stark verbesserte Implementierung des Lehrstuhls Informatik 8 der RWTH Aachen die unter anderem eine Perspektivenkorrektur einsetzt. Dies ermöglicht es zu einem gewissen Grad auch die globale Struktur zu erhalten bzw. fortzusetzen. Zum Beispiel kann man das Colosseum in Rom virtuell wieder aufbauen. Bilder und ein Video gibts hier. Insbesondere das Bild des Aachener Rathauses ist heftig!