technik

realisierung in puredata

Ich hatte nur eine vage Vorstellung, wie nach obigem Modell bearbeites Quellmaterial aussehen könnte. Deswegen wollte ich eine möglichst einfache Methode finden, um dieses Modell umzusetzen. Da ich schon bisschen Erfahrung in pd/Gem sammeln konnte, bot es sich an, diese Tools zu verwenden. In Gem gibt es ein Objekt, das Textur-Daten (Bilder oder Frames eines Filmes) in Audiodaten umwandelt. Somit können die Daten mit normalen pd-Objekten bearbeitet und gespeichert werden. Dies erlaubte mir, auf Pixelebene in den Quellfilm einzugreifen. Grundsätzlich soll die Applikation nichts anderes machen, als den Film Pixel für Pixel neu zusammensetzen. Als Regelvorgabe, wie der Film neu zusammengesetzt werden soll, dient eine Maske. Die Maske ist eine Bilddatei in Graustufen, welche dieselbe Auflösung wie das einzelne Frame besitz. Der Grauwert an einer bestimmten Position in der Maske definiert die Verzögerung des entsprechenden Pixels im Filmframe. Es kann so eine beliebige Maske verwendet werden, sofern deren Auflösung mit der des Filmes übereinstimmt und sie im Grau-Modus gespeichert wurde. Die Wahl der Maske ist somit ein Gestaltungsmittel und kann für einen bestimmten Film extra hergestellt werden.

Beispiel:
Beispiel: Frame 7 des Zielfilms wird berechnet. Der Wert des Pixels 1,1 in der Maske ist 5. Es wird nun also der Wert von Pixel 1,1 im Frame 2 (7-5=2) des Quellfilms zum Pixel 1,1 in Frame 7 des Zielfilms übertragen.

Für jedes Pixel des Films wird auf diese Weise verfahren. Im pd-Patch werden die einzelnen Frames als Audiodaten in einem Array gepuffert und mit einem Lesezeiger, der ständig von Frame zu Frame springt, wieder ausgelesen. Da PD entwickelt wurde, um auf der Audioebene zu arbeiten, können Bilddateien nicht gelesen werden. Diese Tatsache machte es erforderlich, dass bei der Datei der Maske die Headerinformation durch einen Header des Wave-Formats ersetzt werden muss (Die Information bleibt dieselbe, nur die Repräsentationsform ist eine andere). Nachdem nun die Daten wieder ausgelesen und neu zusammengesetzt werden, müssen sie wieder in eine Texturdaten umgewandelt werden, sodass sie im Gem-Fenster dargestellt werden können.

nachteile dieses verfahrens

Da mir keine Möglichkeit bekannt ist, den Output des Gem-Fensters als Videodatei zu speichern, muss die Berechnung in Echtzeit erfolgen. Die Applikation ist jedoch sehr rechenaufwendig, daher ist man auf eine relativ kleine Auflösung beschränkt (auf meinem Rechner maximal 176x144 Pixel).

realisierung in python

Die maximale Auflösung, die man mit der PD-Applikation erreichen konnte, schien mir unbefriedigend. Durch die grobe Rasterung ging jegliche Subtilität, die ich unter anderem suchte, verloren. Zudem konnte ich die Ergebnisse nicht speichern. Aus diesen Gründen suchte ich nach Wegen, die gesamte Berechnung 'offline' erfolgen zu lassen. Um auf Pixeleben arbeiten zu können, musste zuerst ein Video-Format gefunden werden. Als geeignet erwies sich 'AVI uncompressed'. In diesem 'raw'-Format wird jedes Pixel durch 3 Bytes (RGB) repräsentiert. Mit Hilfe von Google und der Arbeit mit einem Hex-Editor gelang es schliesslich, den Header einer solchen Datei zumindest teilweise zu entschlüsseln. Am wichtigsten war es herauszufinden, welche Bytes Pixel repräsentieren und welche 'nur' Header- oder andere Informationen darstellen. Es konnten zudem die Bytes für verschiedene Angaben (x-Aufösung, y-Auflösung, Framerate, Frameperiode und anderes) identifiziert werden.
Da die eigentliche Aufgabe, nämlich ein binäres File Byte für Byte nach einem bestimmten Algorithmus neu zusammenzusetzen, auf Grundfunktionen einer jeden Programmiersprache beruht, konnte das Tool nach anderen Kriterien gewählt werden. Python bot sich an, da es die einzige mir halbwegs geläufige Programmiersprache ist. Die in Python realisierte Applikation macht eigentlich nichts anderes als die PD-Version, ausser dass die Ausgabe in ein File geschrieben und nicht sofort angezeig t wird. Beim Auslesen des Quellfilms springt der Zeiger nach Vorgabe der Maske von Frame zu Frame, liest 3 Bytes aus und und fügt diese dem Zielfilm an. Das Python-Skript beinhaltet drei Bereiche: Zuerst werden die Header-Information des Quelfilms und der Maske asugelesen (es wird geprüft, ob die Auflösungen übereinstimmen). Es werden alle Frames des Filmes in einer Schlaufe abgearbeitet. In dieser Schlaufe verschachtelt wird in einer weiteren Schlaufe Pixel für Pixel bearbeitet. Für einen 30-sekündigen Film im PAL-Format wird die innere Schlaufe 311 Millionen Mal ausgeführt (720*576*25*30). Durch diese riesige Menge von Operationen und weil Python eine interpretierte Skript-Sprache ist, geht das Rendern relativ lange (auf meinem Rechner für die 30s Film ungeähr eine halbe Stunde). Es spielt jedoch keine Rolle mehr, welche Auflösung verwendet wird, diese wird höchsten durch die Geduld limitiert.