3D wie im Magischen Auge


Processing 2.0

Wer kennt sie nicht? Die 3D Bilder der Buchreihe „Das magische Auge“ die Anfang der 90er erschien. Bei den 3D Bildern handelt es sich um sogenannte Stereogramme. Das sind räumlich wirkende Darstellungen zu deren Betrachtung man keine weiteren Hilfsmittel wie etwa eine Rot- Grün 3D Brille benötigt. Hier ein sehr einfaches Beispiel:

Wie funktioniert die Betrachtungstechnik?

Entspanne Deine Augen und blicke geradeaus, als wenn Du durch das 3D Bild hindurchgucken wolltest. Jetzt sollte sich normalerweise langsam ein räumliches Bild entwickeln. Versuche jetzt mit den Augen das 3D Bild scharf zu stellen ohne sich bewußt auf das Stereogramm zu konzentrieren. Diese Methode des Betrachtens erfordert bei einigen eine gewisse Übung. Also nicht verzagen wenn es nicht auf Anhieb klappt.

Hier noch einige Tipps damit sich der Erfolg schneller einstellt:

* Keine Lichtreflexionen auf dem Bildschirm.

* Kopf geradehalten und die Augen parallel zur Bildschirmhorizontale.

* Abstand zum Bildschirm sollte ca. 80 cm betragen.

* Konzentration auf markante Bildpunkte und durch unscharfes Sehen Bildpunkte benachbarter Perioden zur Überlagerung bringen.

Text aus: http://www.wer-kennt-wen.de/gruppen/weltweit/das-magische-auge-uk6hr5qx/

Übe die Technik mit folgenden Beispielbildern:

Über den Erfinder dieser Technik:

Aufbau des Auges:

Urheber: Talos

Das Licht fällt durch die Linse und den durchsichtigen Glaskörper auf die Netzhaut. Dort wird von den Sinneszellen (Zäpfchen und Stäbchen) die Helligkeit und Wellenlänge (Farbe) des Lichts aufgenommen. Über den Sehnerv, in dem schon die ersten signalverarbeitenden Prozesse stattfinden, werden die mittlerweile in Nervensignale umgewandelten Reize zum Gehirn weitergeleitet. Dort findet dann der eigentliche Wahrnehmungsprozess statt.

Wie nimmt das Auge Tiefe wahr?

Lies auf Wikipedia nach wie die Binokulare Raumwahrnehmung (mit 2 Augen) zustande kommt!

3 Tiefenkriterien:

http://de.wikipedia.org/wiki/Raumwahrnehmung

Während die Parallaxe den Winkel zwischen zwei Geraden beschreibt, steht der Begriff Disparation für für den Unterschied zwischen den Bildern, die unsere 2 Augen von einem 3-dimensionalen Objekt liefern.

Wie erzeugen wir ein Bild mit 3-D Effekt – Ein Autostereogramm?

Was ist ein Autosteregramm?

Ein Autostereogramm ist ein 2-D Bild, das unser Gehirn, mit Hilfe seiner Eigenschaft immer nach korrespondierenden Netzhautpunkten zu suchen, dazu bringt ein 3-dimensionales Bild wahrzunehmen.

Dazu muss man allerdings seine Augen trainieren, denn das normale Verhältnis des Winkels der Augen zueinander und dem Fokus muss verändert werden. Dies gelingt nicht allen Menschen gleich gut. Außerdem können etwa 10 % der Menschen überhaupt keine 3-D Bilder sehen.

Die einfachste Form eines Autosterogramms besteht aus horizontal in gleichem Abstand angeordneten gleichen Objekten (Siehe Beispielbild oben).

Wie entsteht der Tiefeneindruck?

Die Tiefe der einzelnen Objektreihen wird durch deren (horizontalen) Abstand zu einander bestimmt („distance„). Dieser Abstand kann nun variieren. Diese Variation bezeichnen wir als „shift„, also die Abweichung vom Standard-Abstand.

In dieser Konstellation erscheinen die größeren Wolken unten(shift 0) als weiter entfernt, als die kleineren Wolken oben (shift 40). Man kann diese Methode auch ganz einfach mit Schrift erzeugen.

Betrachte die Buchstaben mit dem 3D Blick. Was kannst du beobachten?


Aus Wikipedia: http://en.wikipedia.org/wiki/File:Stereogram_Tut_Clean.png by Fred Hsu

Demo: Hier siehst Du wie aus 2 gleichen Objekten im Bild ein virtuelles Objekt, das hinter der Bildebene liegt entsteht.
Bewege den Mauszeiger auf der Grafik auf und ab, um die Tiefe des virtuellen Objekts verändern.

 Aufgabe: Verändere das Programm so, dass die Flugrichtung und Geschwindigkeit der Vögel mit der Maus gesteuert werden können.

Der Processing Sketch als Download: Landschaft

Etwas schwerer: Schreibe selbst ein Programm, das ein Autostereogramm erzeugt.

Programm zur Aufgabe: starte Applet

/** Copyright 2012 Thomas Koberger
*/

// https://lernprocessing.wordpress.com/
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

float picSize=1; //standard Zoom Factor
ArrayList pics; //holds the Pic-Objects

void setup() {
size (1200, 800);
background(9, 139, 232);
smooth();

fill(0, 200, 0);

pics = new ArrayList();

//adds the Pics to the ArrayList (Path,distance,Start-X-Pos,y-Pos, Zoom-Factor
pics.add(new Pic (loadImage("tree1.png"), 210,0, 540,picSize));
pics.add(new Pic (loadImage("cloud3.png"), 210,0, 160,picSize));
pics.add(new Pic (loadImage("tree2.png"), 190,200, 400,3));
pics.add(new Pic (loadImage("birds1.png"), 170,0, 340,picSize));
pics.add(new Pic (loadImage("butterfly.png"), 160,50, 430,picSize));
pics.add(new Pic (loadImage("bird2.png"), 150,0, 590,picSize));
pics.add(new Pic (loadImage("cloud1.png"), 190,0, 100,picSize));
pics.add(new Pic (loadImage("cloud2.png"), 170,0, 80,picSize));
pics.add(new Pic (loadImage("cloud1.png"), 150,0, 10,picSize));
}

void draw() {

//draws the Pics
for (int i=0; i<pics.size(); i++) {
Pic pic = (Pic) pics.get(i);
pic.drawpic();
}
}

void keyReleased() {
if (key == DELETE || key == BACKSPACE) background(360);
if (key == 's' || key == 'S') saveFrame(timestamp()+"_##.png");
}

// timestamp
String timestamp() {
Calendar now = Calendar.getInstance();
return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now);
}

class Pic {

//Variables of Pic-Object
PImage pic;
int distance;
int startX;
int yPos;
float picSize;

//The Constructor
Pic (PImage pic, int distance, int startX, int yPos, float picSize) {
this.pic    = pic;
this.distance   = distance;
this.yPos = yPos;
this.picSize=picSize;
this.startX=startX;
}

//Methods of Pics
void drawpic() {
for (int i=10; i<width; i+=distance) {
image(pic, i-startX, yPos, distance*picSize, distance*7/10*picSize);
}
}
}

Einfache Ebene mit Wallpaper

Ersetzen wir nun die einzelnen Objekte mit einem Flächen füllenden Wallpaper, sehen wir, dass bei entsprechender Betrachtung eine Fläche zu sehen ist, die unter der realen Zeichenebene liegt.

Aus Wikipedia: http://en.wikipedia.org/wiki/File:Stereogram_Tut_Clean.png by Fred Hsu

Wieder gilt: Je weiter die korrespondierenden Pixel auseinander liegen, desto weiter unter der Oberfläche wird der Bildabschnitt wahrgenommen.

3D Bild aus einer Depth Map:
Als Depth Map bezeichnet man ein Graustufen-Bild, welches die Tiefeninformation als Grauwert darstellt (dunkel…hinten, hell…vorne). Damit kann man nun nicht nur ganze Objekte in einer bestimmten Ebene platzieren, sondern jedes Pixel seiner Tiefeninformation entsprechend darstellen (stimmt eigentlich nicht ganz, ist zu diesem Zeitpunkt aber egal).

Aus Wikipedia: http://en.wikipedia.org/wiki/File:Stereogram_Tut_Clean.png by Fred Hsu

Das funktioniert folgendermaßen: Der erste Steifen Wallpaper wird ganz links am Bildschirm gezeichnet. Beim Zeichnen des zweiten Streifens wird dann Zeile für Zeile zu jedem Pixel das entsprechende Pixel aus der Depth Map eingelesen. Ist das Pixel schwarz, wird das Pixel von der gleichen Position im 1.Streifen (rot) in den 2. Streifen (blau) kopiert (siehe Abb. oben!). Ist das Pixel in der Depth Map heller, wird im ersten Streifen (rot) ein Pixel weiter rechts kopiert.


Dadurch wird das Bild Streifen für Streifen immer weiter verzerrt. Schöner wäre es vielleicht, wenn man von der Mitte ausgehend dann links und nach rechts verzerrt.

Wallpapers kann man relativ leicht selber herstellen, oder durch ein zufälliges Pixelmuster ersetzen. Depth Maps können aus 3D Programmen exportiert werden.

Mit einem Gimp Plugin können solche Depth Maps auch selbst hergestellt werden.

Es findet sich aber auch im Internet brauchbares Material. Z.B. hier: Muster, Depth-Maps und einige Stereogramme

  • Oder mit einer veränderten Code-Zeile :

Beispiel: starte Applet

/** Copyright 2012 Thomas Koberger
*/

// https://lernprocessing.wordpress.com/
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

PImage depthMap, wallpaper;//deklariert die Bild Variablen;

int [] [] depth = new int [1260] [600]; //hier wird ein zweidimensionales Array deklariert
color [] [] wall = new color [140] [600];
color [] [] actual = new color [140] [600];
int shift; //horizontale Verschiebung des Pixels
int x=0; // damit sich die
int xToTake; //Bildpunkt im vorigen Wallpaper Streifen, der gezeichnet wird

void setup() {
size(1260, 600,P2D);

//Einlesen der Depth Maps und speichern der Tiefeninfo als Int-Array
depthMap = loadImage("hai_grey.png");//weist der Variablen depthMap die Datei hai_grey.png zu
while(depthMap.width<1){} //pausiert den Sketch, bis das Bild geladen ist.
depthMap.loadPixels(); //sollte man aufrufen, bevor man die einzelen Pixel bearbeitet
for (int gridX = 0; gridX < depthMap.width; gridX++) {
for (int gridY = 0; gridY < depthMap.height; gridY++) {
// überträgt die Farbinfo eines Pixels auf die Variable farbe
color farbe = depthMap.pixels[gridY*depthMap.width+gridX];
// wandelt die Farbinfo in einen Grauwert um
int grauwert =round(red(farbe)*0.222+green(farbe)*0.707+blue(farbe)*0.071);
depth [gridX] [gridY] = grauwert;//speichert den Grauwert in unser Array grau
}
}

//Einlesen des Wallpapers
wallpaper=loadImage("hai_pattern.png");
while(wallpaper.width<1){} //pausiert den Sketch, bis das Bild geladen ist.
wallpaper.loadPixels(); //sollte man aufrufen, bevor man die einzelen Pixel bearbeitet
for (int gridX = 0; gridX < wallpaper.width; gridX++) {
for (int gridY = 0; gridY < wallpaper.height; gridY++) {
// überträgt die Farbinfo eines Pixels auf die Variable farbe
color farbe = wallpaper.pixels[gridY*wallpaper.width+gridX];
// wird die nächste Zeile statt der vorherigen einkommentiert, wird das Wallpaper Bild
// durch ein zufälliges Pixelmuster ersetzt
// color farbe = color ((int) random(0,255),(int) random(0,255),(int) random(0,255));
wall [gridX] [gridY] = farbe;//speichert den Grauwert in unser Array grau
}
}
}

void draw() {
strokeWeight(2);
for (int gridY = 0; gridY < depthMap.height; gridY+=1) {
for (int gridX = 0; gridX < depthMap.width; gridX+=1) {
if (depth[gridX] [gridY]>0) {
shift=floor( depth[gridX] [gridY]/(10));
xToTake= (gridX+shift)%wallpaper.width;
stroke(wall [xToTake] [gridY]);
point(gridX, gridY);
wall [gridX%wallpaper.width] [gridY]=wall  [xToTake] [gridY];
}
else {
stroke(wall [gridX%wallpaper.width] [gridY]);
point(gridX, gridY);
}
}
}
noLoop();
}

void keyReleased() {
if (key == DELETE || key == BACKSPACE) background(360);
if (key == 's' || key == 'S') saveFrame(timestamp()+"_##.png");
}


// timestamp
String timestamp() {
Calendar now = Calendar.getInstance();
return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now);
}

Processing Sketch als Download:  3D Hai

Advertisements

5 Kommentare

  1. Pingback: Processing – Über dieses Weblog « processing – tutorial

  2. Thomas

    Hallo zusammen, kleine Frage:
    Ich möchte in Processing eine Depth Map aus csv-PointCloud-Daten erzeugen um es dann im PS, CS5.5 in ein Mesh zu drücken. Geht dass und wenn ja Wie?

    Vielleicht hilft ja dieser Code (http://code.google.com/p/radiohead/downloads/list) als Grundlage. Da nehmen sie die x ,y und z Werte für Punkte in nem 3D Renderer (P3D, OpenGL) Könnte man zum Beispiel die x und y Werte als Koordinaten auf einer 2-Dimensionalen Fläche und den z-Wert umgerechnet in als (0-255) Grauwert auf nem array? K.A.

    PS. Super Seite! Sehr Lehrreich Danke

  3. lamm

    Ich hab immer noch keine Ahnung wie man diese scheiss bilder erkennt

    • Thomas Koberger

      Üben! Aber ~10% der Bevölkerung kann diese Bilder überhaupt nicht erkennen. Vielleicht gehörst du ja zu den Auserwählten!

  4. Ich bin schon richtig gut da drin. ich kann die 3D Bilder schon auf ein Meter Entfernung entziffern und die 3D Bilder kann ich bis zu sechs Meter Entfernung noch sehen ich kann sogar mittlerweile allein wenn ich ganz normale Bücher lese diesen Blick anwenden, natürlich kommt Da kein 3d Bild raus aber ich sehe wie die Buchstaben sich überschneiden. ich habe nur Angst dass es ganz ungesund für die Augen ist ,denn manchmal sehe ich danach noch verschwommen vor allem nachdem ich das auf dem Tablet oder auf dem Handy gemacht habe. ich hoffe Sie können mir sagen ob es wirklich schädlich für die Augen ist oder nicht.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: