PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bloom mit Mathematica



nudelsalat
28.03.2006, 21:48
Joah, Schul/Grafik oder Programmierforum standen zur Auswahl, ich hab mir mal die Freiheit genommen, es hier zu posten.

Und zwar wollte ich euch kurz vorstellen, wie man mit dem Programm "Mathematica" (http://www.wolfram.com/) einen Bloom Effekt realisieren kann.

----------------------

Sucht euch irgendein Bild und speichert es mithilfe irgendeines Grafikprogramms als unkomprimiertes tif ohne Layer.
Ich habe dieses Bild von Isac Goulart verwendet:
http://img478.imageshack.us/img478/3707/scma66cv.png (als .tif, imageshack hat es leider automatisch umgewandelt)
Für diesen Effekt sollte das Bild einen guten Kontrast haben und evt. auch etwas Farbenfroher sein.

Das erste was ihr mit diesem Bild in Mathematika machen müsst ist, es zu imprtieren und alle wichtigen Bilddaten, in diesem Fall die Bildgroesse und die Farbinformationen, zu extrahieren. Ich werde nicht detailiert auf die Funktionen eingehen, ihr könnt in der Hilfe nachschlagen.

In den ersten 3 Zeilen wird das Bild importiert, alle Farbinformationen in einer Matrix gespeichert und die Bildgröße ebenfalls in einer anderen Matrix.
In den letzten 3 Zeilen wird zu überprüfungszwecken das ganze Bild wieder zusammengesetzt und ausgegeben.
Input


imgdschungel = Import["D:\\schule\\am\\scma29h\\scma6.tif"];
farbmatrix = Part;
bildgroesse = Rest[imgdschungel[[1]]][[1]];

bild = Raster[farbmatrix, bildgroesse, {0, 255}, ColorFunction -> RGBColor];
imgbild2 = Graphics[bild, ImageSize -> bildgroesse[[2]], AspectRatio ->
Automatic];
Show;

[i]Output:
http://img475.imageshack.us/img475/999/bloom11en.jpg

Erstellen des Kerns zum Weichzeichnen. In der Variable sinus wird eine Matrix gespeichert, dessen Werte als Grafik einen weichen Brush in Photoshop darstellen würden, wobei der Wertebereich hier nur von 0-1 und nicht bis 255 geht.
Im Moment hat der Kern am Rand hohe Werte(nahe 1) und in der Mitte niedrige Werte. Zum Weichzeichnen wird das genaue gegenteil benötigt, weshalb er zunächst mit 1-sinus invertiert wird. Anschließend wird jeder Wert durch 20 dividiert. Die Summe aller Werte innerhalb der Matrix darf nämlich nicht zu groß sein, da das Bild sonst zu hell wird.
Input


[img]http://img475.imageshack.us/img475/5651/sinus0pw.gif


Zur weiteren Bearbeitung muss das Bild in seine Rot, grün und blau Anteile zerlegt werden. Hier wird für jede Farbe eine Matrix mit deren Werten erstellt.
Input:


rotmatrix = Table[farbmatrix[[i, j,
1]], {i, bildgroesse[[2, 2]]}, {j, bildgroesse[[2, 1]]}];
gruenmatrix = Table[farbmatrix[[i, j,
2]], {i, bildgroesse[[2, 2]]}, {j, bildgroesse[[2, 1]]}];
blaumatrix = Table[farbmatrix[[i, j,
3]], {i, bildgroesse[[2, 2]]}, {j, bildgroesse[[2, 1]]}];


Durch die Funktion ListConvolve(Faltung der Matrix), wird der Kern zum Weichzeichnen auf jede der Matrizen angewandt. Im Prinzip haben wir jetzt ein weichgezeichnetes rotes, grünes und blaues Bild.
Input:


rotweichgezeichnet = ListConvolve[kernweich, rotmatrix];
gruenweichgezeichnet = ListConvolve[kernweich, gruenmatrix];
blauweichgezeichnet = ListConvolve[kernweich, blaumatrix];


Zusammensetzen der 3 Farbmatrizen zu einem gesamtbild.
Hier hab ich selber etwas Probleme. Die weichgezeichneten Matrizen scheinen allesamt kleiner als die originalmatrizen zu sein, den grund verstehe ich nicht. Die, wenn auch nicht gerade schöne, Lösung ist, einfach die Lauffweite für hoehe und breite um 10 zu verringern. Dadurch wird das Bild zwar kleiner, Aussehen tuts trotzdem nach was.
Input:


farbmatrixweichgezeichnet = Table[Round[
If[pos == 1, rotweichgezeichnet[[hoehe, breite]],
If[pos == 2, gruenweichgezeichnet[[hoehe, breite]],
blauweichgezeichnet[[hoehe, breite]]
]]
], {hoehe,
bildgroesse[[2, 2]] - 10}, {breite, bildgroesse[[2, 1]] - 10},
{pos, 3}];


Kontrollausgabe des weichgezeichneten Bildes:
Input:


bild = Raster[
farbmatrixweichgezeichnet, bildgroesse, {0, 255}, ColorFunction ->
RGBColor];
imgbild2 = Graphics[
bild, ImageSize -> bildgroesse[[2]], AspectRatio -> Automatic];
Show;

[i]Output:
http://img461.imageshack.us/img461/385/bloom26kx.jpg

In diesem Schritt werden das Originalbild und das weichgezeichnete Bild zusammengefügt.
Das ganze läuft so ab, dass jeder Farbwert des Originalbildes mit dem Farbwert des Weichgezeichneten Bildes Mulitpliziert wird. Dannach wird vom Ergebniss die Wurzel gezogen.
Input:


http://img86.imageshack.us/img86/4210/zusammensetzen1uf.gif


Hier werden wieder die drei Matrizen für rot, grün und blau zu einer Matrix für das fertige Bild zusammengefügt.
Input:


farbmatrixbloom = Table[Round[
If[pos == 1, bloomrot[[hoehe, breite]],
If[pos == 2, bloomgruen[[hoehe, breite]],
bloomblau[[hoehe, breite]]
]]
], {hoehe, bildgroesse[[2, 2]] - 10}, {breite, bildgroesse[[2, 1]] -
10}, {pos, 3}];


Ausgabe des Bildes.
Das Bild wirkt verschwommener und heller. Mir persönlich gefällt der Effekt, solange er nicht in Spielen verwendet wird. Von bewegten Bildern mit Bloom Effekt wird mir schlecht. :D
Input:


bild = Raster[
farbmatrixbloom, bildgroesse, {0, 255}, ColorFunction -> RGBColor];
imgbild2 = Graphics[bild,
ImageSize -> bildgroesse[[2]], AspectRatio -> Automatic];
Show;

[i]Output:
http://img137.imageshack.us/img137/1203/bloom37xu.jpg

Randbemerkung:

RGB-Matrizen haben folgenden Aufbau:
{{{R,G,B},{R,G,B}},{{R,G,B},{R,G,B}}}
Matrizen mit einer Farbe haben folgenden Aufbau:
{{F,F},{F,F}}

Der rote Beistrich steht für einen Zeilenwechsel.

Im Prinzip steht ein F in einer einfarbigen Matrix für ein {R,G,B} in einer 3 farbigen.

-------------------
Hf, wenns Probleme mit dem Code gibt, sagt es bitte. Es kann sein, dass beim herauskopieren Mathematica interne Zeichen durch andere Zeichenfolgen ersetzt wurden.

Verbesserungsvorschläge sind auch wilkommen, egal obs um den Code oder um das Verfahren selber geht.

EDIT:
Mir fällt gerade auf, das ich in meiner müdigkeit vergessen habe, den für die Vorschau dahingekrizelten Thementitel in etwas...aussagekräftigeres zu ändern.
Könnte ein Mod den Titel in "Bloom mit Mathematica" oder etwas ähnlichem ändern? ^^

Ineluki
29.03.2006, 16:45
koennte die verkleinerung des Bildes was damit zu tun haben ?


ListConvolve[ker, list] gives a result of length Length[list]-Length[ker]+1.


Ansonsten ganz hybsch ... allerdings waere ich nicht auf die Idee gekommen Bilder mit Mathematica zu bearbeiten ...
Das gibt interessante ansaetze

Jesus_666
31.03.2006, 12:26
Hmm. Könnte mal jemand elaborieren, was Bloom eigentlich ist, also wie man den Effekt auf einer abstrakten Ebene erstellt? Dann könnte man den Kram auch auf PHP/gd, ImageMagick oder anderen programmatischen Grafikbearbeitungsumgebungen umsetzen.

So wie's für mich bisher aussieht wird einfach eine Kopie des Bildes weichgezeichnet und dann halbtransparent über das Ausgangsbild gelegt. Allerdings habe ich von Mathematica keinen blassen Schimmer.

nudelsalat
31.03.2006, 12:43
@Ineluki
danke für den Hinweis, zumindest weiss ich jetzt um wieviel das Bild verkleinert wird.

@Jesus_666
Irgendwo hab ich noch eine erklärung für Bloom in Photoshop gefunden. Dabei wird das Bild zuerst dupliziert, dann wird der Kontrast der Kopie stark erhöht. Je nach Bild wird die Helligkeit noch erhöht oder verringert. Das Kontrastreiche Bild wird dann weichgezeichnet und mithilfe der Layeroption "Screen" mit dem Originalbild verbunden.
Leider habe ich keine Ahnung, auf welche Art und Weise Screen die Bilder miteinander verknüpft.
Wie Bloom eigentlich definiert ist und umgesetzt wird weiss ich leider nicht.

DFYX
31.03.2006, 16:18
OK, mal mein Senf dazu: Bloom ist eine Möglichkeit, einen HDR-ähnlichen Effekt zu erzielen. Das heißt, die Umgebung von hellen Stellen auf dem Bild wird ebenfalls stärker beleuchtet, um sie heller erscheinen zu lassen als der Bildschirm eigentlich kann. Besonders in Half Life 2 - Lost Cost (Technikdemo mit HRD und Bloom) kann man das sehr schön sehen.