Dual-Fischauge zu 360 Grad mit POV-Ray

Ich hat­te vor kur­zem mal mit den Roh­da­ten einer Insta-360-Kamera zu tun. Das fand ich sehr inter­es­sant. Da gibt es das .insp-Dateiformat für 360-Grad-Bilder und das .insv-Dateiformat für 360-Grad-Videos. Man kann den Bild-Dateityp ein­fach von .insp in .jpg bezie­hungs­wei­se bei Vide­os von .insv in .mp4 ändern und so mit Stan­dard­soft­ware betrachten.

Dann sieht man zwei neben­ein­an­der lie­gen­de Fischaugen-Aufnahmen, wel­che jeweils 180 Grad und zusam­men eine voll­stän­di­ge Kugel abde­cken. Ähn­li­che Auf­nah­men hat­te ich 2021 auf dem Weih­nachts­markt Erfurt gemacht. Da ver­wen­de­te ich aller­dings ein Sta­tiv, Belich­tungs­zei­ten bis 30 Sekun­den und deck­te mit mei­nem Objek­tiv nur ca. 170 Grad ab.

Ein künst­li­ches 360-Grad-Panorama aus zwei die­ser Fischaugenlinsen-Aufnahmen wür­de ver­schie­de­ne Orte Erfurts wie ein Por­tal mit­ein­an­der ver­bin­den. Wie das wohl aus­se­hen würde?

Als ers­tes setz­te ich zwei qua­dra­tisch zurecht geschnit­te­ne Auf­nah­men mit Pho­to­shop neben­ein­an­der. Das neue Bild hat­te so das Sei­ten­ver­hält­nis 2 zu 1:

fisheye-360-test.jpg

Die­ses .jpg öff­ne­te ich in Ins­ta 360 Stu­dio. Natür­lich fehl­ten die Meta­da­ten einer rich­ti­gen Insta-360-Kamera und so konn­te das Pro­gramm nichts sinn­vol­les damit tun (auch nicht, wenn man die Datei­endung zu .insp ändert). 

Dann ging ich raus und genoss erst­mal den Sonn­tag­nach­mit­tag im Park und über­leg­te, wie ich die­se Umwand­lung in ein recht­ecki­ges Pan­ora­ma zumin­dest für ein Stand­bild selbst machen kann.

Da erin­ner­te ich mich an mei­ne »alten« Zei­ten mit dem script­ba­sier­ten und kos­ten­lo­sen Ray­tra­cer POV-Ray und des­sen Mög­lich­kei­ten, per Code Kame­ra, Licht und Objek­te anhand eini­ger Para­me­ter zu defi­nie­ren und dabei mit belie­bi­gen Auf­lö­sun­gen zu han­tie­ren. Perfekt! 

Die Sze­ne besteht am Ende aus einer Hohl­ku­gel mit Radi­us 1 und dem Mit­tel­punkt im Koor­di­na­ten­ur­sprung <0,0,0>, die senk­recht in zwei Hälf­ten geteilt wird so dass eine lin­ke und eine rech­te Kugel­scha­le ent­steht. Das Input-Bild wird von links und von rechts auf die jewei­li­ge Kugel­scha­le pla­nar gemappt und selbst leuch­tend ein­ge­stellt, damit die Pixel­far­ben vom Input-Bild über­nom­men wer­den. In die Mit­te die­ser geteil­ten Kugel kommt eine Pan­ora­ma­ka­me­ra, die dann alles um sich her­um als equi­recht­ecki­ges Bild auf­nimmt. Der Ray­tra­cer erzeugt damit das Ergebnis-Bild.

Der POV-Ray-Code sieht so aus:

				
					

#version 3.7;

global_settings {
  assumed_gamma 1.0               
  max_trace_level 12 
  
}                  
                                                                                          
/* PARAMETER */
                                                                                          
#declare src_img = "fisheye-360-test.jpg";   // Das Bild mit den zwei Fischaugenbildern nebeneinander


#declare input_img = pigment { 
                         image_map {         // Bitmap-Textur laden
                             jpeg src_img    // das Inputbild ist in XY-Ebene von &lt;0,0&gt; bis &lt;1,1&gt; gekachelt
                             scale &lt;4,2,2&gt;   // 4x so breit und 2x so hoch zoomen
                         } 
                     }

#declare factor = 1.02;                      // Anpassung wenn Fischauge &lt; 180 Grad umfasst
                      
/* OBJEKTE */                      
                      
union {                                      // Gruppe von Objekten
    sphere { &lt;0,0,0&gt;, 1                      // Kugelmitte im Koordinatenursprung &lt;0,0,0&gt;, Radius 1
        inverse                              // Flächen umkehren
        clipped_by {                         // abschneiden  mit senkrechter Ebene
            plane { x,0 }                    // und dabei LINKE Hälfte stehen lassen
        }              
        texture {                            // Textur definieren
            pigment {                        // Farbeigenschaften                    
                input_img                    // das Inputbild ist in XY-Ebene von 0,0 bis 1,1 gekachelt
                translate &lt;-1,-1,0&gt;          // verschieben: Mitte LINKES Fischauge auf Kugelmitte
                rotate -y*90                 // um die Senkrechte 90 Grad GEGEN die Uhr drehen
                scale factor                 // ggf. geringe Größenanpassungen
            }
            finish {                         // Oberflächeneigenschaften
                ambient 1.0                  // Umgebungslicht auf 100%, Farben sind wie Inputbild
            }
        }
    }
    sphere { &lt;0,0,0&gt;, 1                      // Kugelmitte im Koordinatenursprung &lt;0,0,0&gt;, Radius 1
        inverse                              // Flächen umkehren
        clipped_by {                         // abschneiden mit senkrechter Ebene
            plane { -x,0 }                   // und dabei RECHTE Hälfte stehen lassen
        }              
        texture {                            // Textur definieren
            pigment {                        // Farbeigenschaften
                input_img                    // das Inputbild ist in XY-Ebene von 0,0 bis 1,1 gekachelt
                translate &lt;-3,-1,0&gt;          // verschieben: Mitte RECHTES Fischauge auf Kugelmitte
                rotate y*90                  // um die Senkrechte 90 Grad IM die Uhr drehen
                scale factor                 // ggf. geringe Größenanpassungen 
            }
            finish { 
                ambient 1.0                  // Umgebungslicht auf 100%, Farben sind wie Inputbild
            }
        }
    }      
    // rotate y*90
}

/* KAMERADEFINITION */

camera {
  spherical                                  // Kugelkamera, die equirechteckige Bilder erzeugt
  location 0                                 // Position ist genau Kugelmitte
  look_at z                                  // schaut in die Tiefe
  angle 360                                  // Horizontal 360 Grad
        180                                  // Vertikal 180 Grad
}
           

				
			
Die Aus­ga­be des POV-Ray-Scripts ist das Bild, das die Sphä­ri­sche Kame­ra aufnimmt.
Damit ich bei­de Über­gän­ge auf dem Ergebnis-Bild habe, kom­men­tie­re ich Zei­le 60 aus. Der Befehl dreht die Kugel mit den gemapp­ten Bil­dern um 90 Grad um die Senkrechte
In Pho­to­shop gestal­te­te ich die bei­den  senk­rech­ten Über­gän­ge weicher

Das Ergeb­nis kön­nen Sie rechts im 360-Grad-Widget von Essen­ti­al Addons für Ele­men­tor betrach­ten und sehen wie es sich aus­sieht, wenn man sich an zwei Orten gleich­zei­tig befindet.

 

Fazit:

Mit über 30 Sekun­den Belich­tungs­zeit mit Fischaugen-Objektiv und Sta­tiv und Bear­bei­tung des Bild­ma­te­ri­als mit einem gescrip­te­ten Ray­tra­cer ist es eher die Slow-360-Variante und eher wenig für das Bild­ma­te­ri­al aus einer nati­ven 360-Grad-Panoramakamera geeig­net. Aller­dings bie­tet das Ver­fah­ren über POV-Ray eine gewis­se krea­ti­ve Freiheit. 

Wenn es passt zie­he ich noch­mal mit Fisch­au­gen­ob­jek­tiv und Sta­tiv los und berück­sich­ti­ge dann bei den Auf­nah­men jeweils eine Dre­hung um 180 Grad, um einen vol­len Kreis anzu­de­cken. Mal sehen, wie gut sich das dann zusam­men­set­zen lässt.