Das Erzeugen der Punktwolke soll einfach und schnell sein und mit einer Kinect erfolgen.
Damit ein Experte assistierend zugeschaltet werden kann benötigt dieser Informationen zu dem problematischen Objekt.
Aus einem Frame der Kinect, bestehend aus Farbbild und Tiefenbild, lässt sich einfach eine Punktwolke relativ zum Tiefensensor der Kinect errechnen.
Diese Daten sollen anschließend in einer VR Umgebung dem Experten präsentiert werden, deshalb sollte die Aufnahme ein 3D Scan sein.
Eine Aufnahme beinhaltet aber nur alle Informationen, die aus den 2D Bildern errechnet werden können.
Ziel der Arbeit war es eine Lösung für das Aufnehmen der benötigten 3D Daten zu finden die einfach Bedienbar ist und ohne Aufwendige Nachbearbeitung oder Berechnungen auskommt.
Das heißt, man erhält eine Seite des Objektes gut aufgelöst und Artefakte, die sich aus dieser Berechnung ergeben.
Deshalb wurde sich für die Aufnahme und Visualisierung von 3D Punktwolken entschieden.
Für die Darstellung in einer VR Umgebung ist dieses nicht ausreichend.
Der Betrachter kann sich frei in der virtuellen Welt bewegen und erkennt schnell die nicht vorhanden Informationen und Fehler.
Als Sensor wurde die Kinect ausgewählt. Diese ist günstig, portabel und wird in der Forschung häufig als 3D Sensor eingesetzt.
Die Kinect als Sensor bietet die Möglichkeit aus einzelnen Aufnahmen bestehend aus einem Farbbild und einem Tiefeinbild eine Punktwolke aus der Perspektive der Kinect zu errechnen.
Eine Aufnahme (ein Frame) beinhaltet aber nur alle Informationen die aus der Perspektive der Kamera sichtbar sind.
Das beinhaltet zum einen die Flächen der nächsten Oberfläche.
Dahinterliegende Geometrie wird verdeckt und ist aus einer Perspektive nicht sichtbar(siehe \ref{img:KinectSides} (a)).
Außerdem sind an Kanten meist nicht genügend Informationen in der Aufnahme enthalten sodass seitliche Flächen richtig in Punkte konvertiert werden können.
In vielen Fällen führt das zu falschen und nicht existierenden Flächen der errechneten Punktwolke(siehe \ref{img:KinectSides} (b)).
Diese Informationen aus einer Aufnahme reichen für eine die Visualisierung in VR für den Experten nicht aus.
Das Objekt sollte von allen Seiten gescannt werden damit der Experte frei entscheiden kann von welcher Seite er das Objekt bzw. die Punktwolke betrachtet.
Um eine Punktwolke zu erhalten die das gesamte Objekt abdeckt, werden mehrere Aufnahmen aus unterschiedlichen Perspektiven gemacht.
Diese Aufnahmen müssen aber anschließend richtig zu einer großen Punktwolke zusammengefügt werden.
Eine Möglichkeit 2 Aufnahmen zusammenzufügen ist über die Transformation zwischen den Kamerapositionen.
Mit dieser Transformation lässt sich eine Punktwolke aus einem Frame in das Koordinatensystem einer andern Aufnahme transformieren.
Um diese Transformation zu errechne gibt es einige Ansätze die aber meist rechenaufwändig und fehleranfällig sind.\todo{ref realted work}
In dieser Abriet wurde die Kinect mit dem Lighthouse Tracking der HTC Vive verbunden.
Das Trackingsystem liefert eine globale Position des Kinect Sensor und ermöglicht damit eine einfache Berechnung der relativen Transformation zwischen 2 Kameraperspektiven.
Durch ein globales Tracking zur Aufnahmezeit entfallen nachträgliche Berechnungen um aus den einzelnen Aufnahmen die Kamerapositionen zu errechnen.
Das spart zeit und Rechenleistung und bietet somit eine einfache und schnelle Möglichkeit eine 3D Aufnahme von einem Objekt zu erstellen.
Eine Fehlerquelle sind die Kanten von Objekten zu Flächen, die von der Kinect nicht gesehen werden.
Das Bild der Kinect ist perspektivisch und wird beim Errechnen der Punktwolke dort ein Punkt approximiert, dann entstehen Flächen die nicht der Realität entsprechen. (siehe \ref{img:KinectSides} ).
\begin{figure}
\begin{figure}
\label{img:KinectSides}
\subfigure[Aufnahme aus Sicht der Kinect ]{\includegraphics[width=0.49\textwidth]{Bilder/1FrameKamera.png}}
\subfigure[Aufnahme aus Sicht der Kinect ]{\includegraphics[width=0.49\textwidth]{Bilder/1FrameKamera.png}}
\subfigure[Aufnahme von der Seite]{\includegraphics[width=0.49\textwidth]{Bilder/1FrameSeite.png}}
\subfigure[Aufnahme von der Seite]{\includegraphics[width=0.49\textwidth]{Bilder/1FrameSeite.png}}
\caption{Aufnahme der Kinect aus verschiedenen Perspektiven. In Bild (b) sind falsche Punkte zu sehen, die durch die Rekonstruktion aus einem 2D Bild entstehen. }
\caption{Aufnahme der Kinect aus verschiedenen Perspektiven. In Bild (a) ist zu erkennen wie die Türme den Hintergrund verdecken. In Bild (b) sind falsche Punkte zu sehen, die durch die Rekonstruktion aus einem 2D Bild entstehen. }
\label{img:KinectSides}
\end{figure}
\end{figure}
Das zweite Problem, das es zu lösen galt, war das Zusammenfügen von mehreren Aufnahmen aus unterschiedlichen Perspektiven zu einer großen zusammenhängenden Punktwolke.
Um 2 Frames miteinander zu verbinden, braucht man die relative Transformation zwischen den beiden Aufnahmen.
Bei bestehenden Algorithmen wird dieses zum Beispiel durch Zurückrechnen der Kamerabewegung erreicht \todo{quellen}.
Solche Verfahren sind meist rechenaufwändig und zeitintensiv.
Für diese Arbeit war es das Ziel, die Kinect mit dem Lighthouse Tracking System zu verbinden.
Die Trackingdaten aus SteamVR, bzw OpenVR geben uns eine globale Position aller Aufnahmen und vereinfachen das Erzeugen einer großen Punktwolke.
\section{Frames aufnehmen und bereinigen}
\section{Frames aufnehmen und bereinigen}
Im ersten Schritt wird ein Frame mit der Kinect aufgenommen und das Tiefenbild geglättet.
Im ersten Schritt wird ein Frame mit der Kinect aufgenommen.
Die Rohdaten der Kinect sind verrauscht und deshalb wird das Tiefenbild geglättet.
Anschließend wird das Tiefen- und Farbbild in 3D Punkte umgewandelt und unerwünschte Punkte verworfen.
Anschließend wird das Tiefen- und Farbbild in 3D Punkte umgewandelt und unerwünschte Punkte verworfen.
\subsection{Aufnahme und Glättung}
\subsection{Aufnahme und Glättung}
Zum Aufnehmen einer kleinen Punktwolke wird das Kinect SDK verwendet.
Zum Aufnehmen einer Punktwolke aus einem Frame wird das Kinect SDK verwendet.
Sowohl das Tiefeinbild auch als auch das Farbbild kann man aus der API erhalten.
Sowohl das Tiefeinbild auch als auch das Farbbild kann man aus der API erhalten.
Anschließend wird das Tiefenbild geglättet.
Anschließend wird das Tiefenbild geglättet um glattere Oberflächen in der Punktwolke zu erhalten.
Die Rohdaten sind teilweise sehr verrauscht und so erhält man eine Punktwolke mit glatteren Flächen.
Hierfür braucht man einen Filter, der zwar die Flächen glättet, aber gleichzeitig die Objektkanten erhält.
Hierfür braucht man einen Filter, der zwar die Flächen glättet, aber gleichzeitig die Objektkanten erhält.
Ein Bilateral Filter erzielt den gewünschten Effekt ist aber relativ rechenaufwändig.
Ein Bilateral Filter erzielt den gewünschten Effekt ist aber relativ rechenaufwändig.
Verwendet wurde der Filter, der in dem Paper \cite{Martin:2014:RTH} vorgestellt wird.
Im Paper \cite{Martin:2014:RTH} wird hierfür ein Filter vorgestellt den auch in dieser Ausarbeitung verwendet wurde.
Hierbei wird zunächst das Bild mit einem Gauß-Filter geglättet.
Hierbei wird zunächst das Bild mit einem Gauß-Filter geglättet.
Dieser ist nicht kantenerhaltend. Deshalb wird das geglättet Bild anschließend mit dem Original verglichen.
Dieser ist nicht kantenerhaltend. Deshalb wird das geglättet Bild anschließend mit dem Original verglichen.
Bei zu starker Abweichung vom Original wird der Wert des Pixels auf das Original zurückgesetzt.
Bei zu starker Abweichung vom Original wird der Wert des Pixels auf das Original zurückgesetzt.
...
@@ -45,13 +53,15 @@ Bei zu starker Abweichung vom Original wird der Wert des Pixels auf das Original
...
@@ -45,13 +53,15 @@ Bei zu starker Abweichung vom Original wird der Wert des Pixels auf das Original
Nach der Glättung des Tiefenbildes wird dieses in eine Punktwolke umgewandelt.
Nach der Glättung des Tiefenbildes wird dieses in eine Punktwolke umgewandelt.
Hierfür wurde ebenfalls das Microsoft Kinect SDK verwendet, das alle benötigten Methoden bereitstellt.
Hierfür wurde ebenfalls das Microsoft Kinect SDK verwendet, das alle benötigten Methoden bereitstellt.
Nach der Umwandlung werden noch weitere Punkte verworfen.
Nach der Umwandlung werden noch weitere Punkte verworfen:
Zunächst werden alle Punkte ohne zuordnungsfähige Farbe verworfen.
Zunächst werden alle Punkte ohne zuordnungsfähige Farbe verworfen um ein schönere Aufnahme zu erhalten.
Der Farbsensor ist nicht an der gleichen Stelle der Kinect und deshalb kann es vorkommen, dass die Tiefeinkamera Geometrie aufnimmt, die aus Sicht der Farbkamera verdenkt ist.
Außerdem hat der Tiefeinsensor eine andere Auflösung und ein anderes Seitenverhältnis als die Farbkamera, sodass es am oberen und unteren Rand zu nicht farbigen punkten kommt.
Auch alle Punkte, die zu nah oder zu weit vom Sensor entfernt sind, werden nicht weiter betrachtet.
Auch alle Punkte, die zu nah oder zu weit vom Sensor entfernt sind, werden nicht weiter betrachtet.
Je weiter das Objekt entfernt ist, desto ungenauer werden die Aufnahmen.
Je weiter das Objekt entfernt ist, desto ungenauer werden die Aufnahmen.
Im folgenden wurde ein Mindestabstand von 30cm und ein Maximalabstand von 90cm verwendet.
Im folgenden wurde ein Mindestabstand von 30cm und ein Maximalabstand von 90cm verwendet.
Als letztes filtern wir alle Flächen deren Oberflächennormale zu weit von dem Kameravektor abweicht (siehe Abb \ref{img:KinectSides} b)
Als letztes werden alle Flächen deren Oberflächennormale zu weit von dem Kameravektor abweicht (siehe Abb \ref{img:KinectSides} b)
Diese Flächen entstehen durch die Umwandlung des 2D Tiefenbildes in eine 3D Punktwolke.
Diese Flächen entstehen durch die Umwandlung des 2D Tiefenbildes in eine 3D Punktwolke.
Die benötigten Informationen fehlen an dieser Stelle und Punkte werden auf die Fläche zwischen Oberflächenobjekt und Hintergrund gesetzt.
Die benötigten Informationen fehlen an dieser Stelle und Punkte werden auf die Fläche zwischen Oberflächenobjekt und Hintergrund gesetzt.
Diese Ebene stimmt nicht mit der wirklichen Oberfläche überein und diese falschen Punkte müssen entfernt werden.
Diese Ebene stimmt nicht mit der wirklichen Oberfläche überein und diese falschen Punkte müssen entfernt werden.
Eine wichtige Transformation ist die zwischen dem Koordinatensystem der Kinect und dem des Vive Controllers.
Eine Transformation ist die zwischen dem Koordinatensystem der Kinect und dem des Vive Controllers.
Ist zum Beispiel die Transformation entlang der X Achse der Kinect verschoben, so verstärkt sich der Fehler, wenn man das Objekt von der anderen Seite, also um 180\degree gedreht aufnimmt (siehe Abb, \ref{img:KinecOffset}).
Ist zum Beispiel die Transformation entlang der X Achse der Kinect verschoben, so verstärkt sich der Fehler, wenn man das Objekt von der anderen Seite, also um 180\degree gedreht aufnimmt (siehe Abb, \ref{img:KinecOffset}).
Der Fehler im lokalen Koordinatensystem wird in das globale transformiert und ist in dem Fall dann in genau entgegengesetzter Richtung.
Der Fehler im lokalen Koordinatensystem wird in das globale transformiert und ist in dem Fall dann in genau entgegengesetzter Richtung.
\caption{Effekt einer falschen Kalibrierung dx auf die endgültige Punktwolke. Aufnahme 1 und 2 sind von lokalen Koordinaten in Welt Koordinaten transformiert}
\caption{Effekt einer falschen Kalibrierung dx auf die endgültige Punktwolke. Aufnahme 1 und 2 sind von lokalen Koordinaten in Welt Koordinaten transformiert}
\label{img:KinecOffset}
\end{center}
\end{center}
\end{figure}
\end{figure}
In der offiziellen Dokumentation der Kinect ist beschrieben, dass der Ursprung von Punktwolken in dem Tiefensensor liegt (siehe \cite{KinectDoku}).
In der offiziellen Dokumentation der Kinect ist beschrieben, dass der Ursprung von Punktwolken in dem Tiefensensor liegt (siehe \cite{KinectDoku}).
Leider fehlt die exakte Positionsangabe in dem Gehäuse.
Leider fehlt die exakte Positionsangabe im Gehäuse.
Im Bild \ref{img:KinectOrigin} aus dem chinesischen Microsoft Forum ist eine von Benutzern vermessene schematische Darstellung der Kinect abgebildet.
Im Bild \ref{img:KinectOrigin} aus dem chinesischen Microsoft Forum ist eine von Benutzern vermessene schematische Darstellung der Kinect abgebildet.
Der Tiefensensor liegt hinter der kleineren runden Öffnung, aber Fertigungsungenauigkeiten lassen keine exakten Daten finden.
Der Tiefensensor liegt hinter der kleineren runden Öffnung.
Die exakte Position ließ sich ohne die Kienct zu zerlegen nicht ermitteln, da auch Fertigungsungenauigkeiten die genaue Position beeinflussen können.
Für die Implementation wurde angenommen, dass er sich mittig hinter der Öffnung befindet.
Für die Implementation wurde angenommen, dass er sich mittig hinter der Öffnung befindet.
Eine digitale Kalibrierung gestaltet sich schwierig, da das Lighhouse Tracking für den Controller zusätzlich einige Ungenauigkeiten mit sich bringt.
Eine digitale Kalibrierung gestaltet sich schwierig, da das Lighhouse Tracking des Controllers zusätzlich einige Ungenauigkeiten mit sich bringt.
Der Ursprung des Controllers lässt sich aus den Modellen von SteamVR auslesen.
Der Ursprung des Controllers lässt sich aus den Modellen von Steam VR auslesen (siehe Abb.\ref{img:KinecttoVive} (c))
Dieser liegt geschickt für VR Anwendungen, ist aber für das Tracking von Objekten ungeschickt.
Dieser liegt geschickt für VR Anwendungen da die Z-Achse in der Hand liegt.
Aber das für das Tracking von Objekten liegt der Ursprung ungeschickt, da er im inneren des Controllers liegt und es keine ebene Auflagefläche parallel zu den Achsen gibt.
Bei der Implementation stand noch kein Vive Tracker zur Verfügung.
Bei der Implementation stand noch kein Vive Tracker zur Verfügung.
Für die Arbeit wurde der Controller so nah wie möglich an dem Teifensensor, also direkt darüber angebracht (siehe Abb.\ref{img:KinecttoVive}).
Die Tracker sind extra Sensoren die für das Tracken von Objekten mit dem Lighthouse System entwickelt wurden.
Bei diesen ist der Ursprung in der Schraube und parallel zur Auflagefläche (siehe Abb. \ref{img:Tracker}).
Für die Arbeit wurde der Controller so nah wie möglich an dem Tiefensensor, also direkt darüber angebracht (siehe Abb. \ref{img:KinecttoVive}).
Als Hilfe wurde ein 3D gedruckter Zylinder verwendet der in den Ring des Controllers passt.
\caption{Abmessungen der Kinect. Der Tiefensensor liegt in der kleinen runden Öffnung. Quelle:\cite{KinectChina}}
\caption{Abmessungen der Kinect. Der Tiefensensor liegt in der kleinen runden Öffnung. Quelle:\cite{KinectChina}}
\label{img:KinectOrigin}
\end{center}
\end{center}
\end{figure}
\end{figure}
\begin{figure}
\begin{figure}
\label{img:KinecttoVive}
\subfigure[Befestigung der Kienct]{\includegraphics[width=0.32\textwidth]{Bilder/KincetHalterung.JPG}}
\subfigure[Befestigung der Kienct]{\includegraphics[width=0.32\textwidth]{Bilder/KincetHalterung.JPG}}
\subfigure[Kinect mit Controler]{\includegraphics[width=0.32\textwidth]{Bilder/KinecController1.JPG}}
\subfigure[Kinect mit Controler]{\includegraphics[width=0.32\textwidth]{Bilder/KinecController1.JPG}}
\subfigure[Relative Position in 3D]{\includegraphics[width=0.32\textwidth]{Bilder/KinectToVive.png}}
\subfigure[Relative Position in 3D]{\includegraphics[width=0.32\textwidth]{Bilder/KinectToVive.png}}
\caption{Befestigung des Controllers an der Kinect. Die Mitte des Controllers ist direkt über dem Tiefensensor.
\caption{Befestigung des Controllers an der Kinect. Die Mitte des Controllers ist direkt über dem Tiefensensor.
In Bild a) ist die 3D gedruckte Halterung zusehen. Der Controller wird auf den Zylinder gesteckt. In c) ist die Virtuelle Repräsentation. Koordinatenkreuze zeigen den jeweiligen Ursprung des Geräts ([x,y,z] Achse=[rot,grün,blau]}
In Bild a) ist die 3D gedruckte Halterung zusehen. Der Controller wird auf den Zylinder gesteckt. In c) ist die Virtuelle Repräsentation. Koordinatenkreuze zeigen den jeweiligen Ursprung des Geräts ([x,y,z] Achse=[rot,grün,blau]}
\caption{Ursprung des Vive Trackers aus der offiziellen Dokumentation. Er ist in der Befestigung schraube und parallel zu der Auflagefläche.}
\label{img:Tracker}
\end{center}
\end{figure}
\end{figure}
\section{Ergebnisse}
\section{Ergebnisse}
Mit dem vorgestellten Verfahren lässt sich einfach und schnell eine Punktwolke erstellen.
Mit dem vorgestellten Verfahren lässt sich einfach und schnell eine Punktwolke erstellen.
Jedoch gibt es Ungenauigkeiten in dem Vive Tracking und der Kalibrierung, die die Punktwolke unbrauchbar aussehen lassen.\todo{Bild}
Die Ungenauigkeiten des Trackings und Fehler in der Kalibrierung führen aber zu sichtbaren Fehlern in der endgültigen Punktwolke. \todo{Bild}
Zwischen 2 Aufnahmen und den daraus resultierenden Punktwolken ist ein Versatz bis zu 2-3 cm sichtbar.
Zwischen 2 Aufnahmen und den daraus resultierenden Punktwolken ist ein Versatz bis zu 2-3 cm sichtbar.
In einer 3D Umgebung insbesondere in VR ist das eine zu große Ungenauigkeit.
In einer 3D Umgebung insbesondere in VR ist das eine zu große Ungenauigkeit.
Der Versatz zwischen den Punktwolken ist leider nicht konstant und ändert sich teilweise zwischen Durchläufen.
Durch die Ungenauigkeiten des Trackings verändert sich die Genauigkeit und damit der Versatz der Punktwolken ständig.
Das Vive Tracking ist hierfür ein Grund.
Vergleicht man mit einem 2m Zollstock die reale Distanz mit der realtiven Distanz in VR, so erhält man in VR eine Länge von 1,98 bis 2 m
Vergleicht man mit einem 2m Zollstock die reale Distanz zu der in VR gemessenen dann wird daraus 1,98-2m virtuelle Distanz.
Die Distanz ist hierbei abhängig von der Orientierung zu den Basisstationen und der aktuellen Kalibrierung des Lighthous Tracking Systems.
Die Distanz ist hierbei abhängig von der Orientierung zu den Basisstationen und der aktuellen Kalibrierung des Lighthous Tracking Systems.
Dieses Problem erschwert es, die Kalibrierung zwischen Vive und Kinect zu überprüfen.
Dieses Problem erschwert es, die Kalibrierung zwischen Controller und Kinect zu überprüfen.
Die Rotation der einzelnen Aufnahmen war kein Problem und hat keine sichtbaren Probleme produziert.
Im Gegensatz zur Translation war die Messung der Rotation sehr genau und erzeugte keine Sichtbaren Fehler beim Zusammenfügen der unterschiedlichen Punktwolken.
In diesem Kapitel wird ein grober Überblick über die Struktur und die Komponenten des GL Transmission Formats und der 3D Tiles gegeben. Diese wurden verwendet, um um die Punktwolken zu speichern.
In diesem Kapitel wird ein grober Überblick über die Struktur und die Komponenten des GL Transmission Formats und der 3D Tiles gegeben. Diese wurden verwendet, um die Punktwolken zu speichern.
3D Tiles und gltf
3D Tiles are an open specification for streaming massive heterogeneous 3D geospatial datasets
Tile Struktur (Tielset)
differentTiles (batched, instanced, points ...)
Bounding Volumes und LOD
Dynamic loading
GLTF Struktur
Optimized for OpenGl and streaming
scenes, nodes, meshes
materials
animations ignored
\section{3D Tiles}
\section{3D Tiles}
3D Tiles \cite{3DTiles} ist eine neue offene Spezifikation für das Streamen von massiven, heterogenen, geospatialen 3D Datensätzen.
3D Tiles \cite{3DTiles} ist eine neue offene Spezifikation für das Streamen von massiven, heterogenen, geospatialen 3D Datensätzen.
Die 3D Tiles können genutzt werden, um Gelände, Gebäude, Bäume und Punktwolken zu streamen und bieten Features wie Level of Detail (LOD).
Die 3D Tiles können genutzt werden, um Gelände, Gebäude, Bäume und Punktwolken zu streamen und bieten Features wie Level of Detail (LOD).
Für die Arbeit wurde erwartet, das insbesondere LOD notwendig werden könnte, es wurde aber nicht verwendet.
LOD war bei der Asuwahl des Datenfomrats ein wichtiger Faktor, da dies bei großen Punktwolken ein signifikanten Perfomancevorteil bringen könnte.
Bei der Implementierung wurden LOD verfahren nicht verwendet, da die Darstellung der gesammten Punktwolke möglich ist.
\subsection{glTF}
\label{gltf}
Das GL Transmission Format (glTF \cite{GLTF}) ist ein Format zum effizienten Übertragen von 3D Szenen für Gl Api's wie WebGL. OpenGl ES und OpenGL.
glTF dient als effizientes, einheitliches und erweiterbares Format zur Übertragung und Laden von komplexen 3D Daten.
Dieses wird in den 3D Tiels verwendet um komplexe Geometrie wie Gebäude zu übertragen.
In dieser Arbeit kamen aber nur Punktwolken zum Einsatz.
Im Vergleich zu aktuellen Standards wie COLADA ist glTF optimiert, schnell übertragen und kann schnell in eine Applikation geladen werden.
In einer JSON formatierten Datei (.gltf) wird eine komplette Szene samt Szenengraf, Materialien und deren zugehörigen Shadern, Kamerapositionen, Animationen und Skinning Informationen übertragen.
Dabei kann auf externe Dateien verwiesen werden. Diese sind zum Beispiel Binärdaten oder Bilder, die für das einfache und effiziente Übertragen von Geometrie, Texturen oder den nötigen GLSL Shadern genutzt werden.
Die .gltf Datei ist JSON formatiert und bildet den Kern jedes glTF Modells.
In ihr werden alle grundlegenden Informationen wie zum Beispiel die Baumstruktur des Szenengrafen und die Materialien gespeichert (siehe Abb. \ref{img:glTFOverview}).
Eine Szene bildet hierbei den Startpunkt für die zu rendernde Geometrie.
Szenen bestehen aus Knoten (Nodes), die beliebig viele Knoten als Kinder haben können.
Jeder Knoten kann eine Transformation im lokalen Raum definieren, bestehend aus einer Translation, einer Rotation und einer Skalierung.
Jeder Knoten kann eine Mesh und damit die eigentliche Geometrie referenzieren.
Diese Geometrie wird in Buffern als Binärdaten gespeichert. Diese sind entweder als Base64 String direkt im JSON oder als zusätzliche Binärdatei gespeichert.
Auf einen Buffer wird mit einem Accessor und einer Bufferview zugegriffen. In diesen ist spezifiziert, in welchem Format die Daten vorliegen (z.B. ein Array aus 2D Vektoren (VEC2) aus UNSIGNED SHORT).
Alle Datenformate entsprechen Formaten, die in OpenGL vorliegen, sodass die Daten ohne Konvertierung in OpenGL Vertex Array Objetkts (VAO), bzw. Vertex Buffer Objekts (VBO) umgewandelt werden können.
Jedes Mesh kann auf ein Material referenzieren. Materialien bestehen aus Materialparametern, Texturen und Techniken.
Techniken bestehen hauptsächlich aus einem GLSL Shader Programm, das ebenfalls im glTF mitgeliefert wird.
Außerdem wird spezifiziert, wie die VAO und VBO aus dem Mesh bei dem Rendervorgang an den Shader gebunden werden müssen.
Ein weiteres Feature von glTF Datein ist die Möglichkeit, Animationen und Skinning Informationen zu übertragen.
Buffer sind die eigentlichen Daten in einem Binären Block.
Diese können entweder als externe Datei (.bin) oder als BASE64 encodierter String in der JSON Datei angefügt werden.
Die Hauptaufgabe der Buffer ist es, große Mengen an Daten wie die Geometrie effizient zu übertragen.
\subsection{Tileset und Tiles}
\subsection{Tileset und Tiles}
Als Basis der 3D Tiles wird JSON formatiertes Tileset verwendet, das auf die eigentlichen Daten in Tiles verweist.
Als Basis der 3D Tiles wird JSON formatiertes Tileset verwendet, das auf die eigentlichen Daten in Tiles verweist.
...
@@ -41,7 +68,7 @@ Die eigentlichen Daten der Tiles sind durch eine URL verlinkt und können dynami
...
@@ -41,7 +68,7 @@ Die eigentlichen Daten der Tiles sind durch eine URL verlinkt und können dynami
Tiles können in unterschiedlichen Formaten sein, zum Beispiel:
Tiles können in unterschiedlichen Formaten sein, zum Beispiel:
\begin{description}
\begin{description}
\item[ Batched3D Model]
\item[ Batched3D Model]
3D Daten, die als glTF übertragen werden. Zusätzlich können pro Modell Metadaten zum Visualisieren enthalten sein.
3D Daten, die im GL Transmission Format (glTF \ref{gltf}) übertragen werden. Zusätzlich können pro Modell Metadaten zum Visualisieren enthalten sein.
\item[ Instanced3D Model]
\item[ Instanced3D Model]
Tileformat für Instancing. Die Geometrie wird als glTF übertragen und zusätzlich eine Liste aus Positionen an denen die Objekte instanziiert werden sollen.
Tileformat für Instancing. Die Geometrie wird als glTF übertragen und zusätzlich eine Liste aus Positionen an denen die Objekte instanziiert werden sollen.
Das kann zum Beispiel für Bäume genutzt werden.
Das kann zum Beispiel für Bäume genutzt werden.
...
@@ -55,47 +82,7 @@ Tileformat zum gleichzeitigen Übertragen mehrerer einzelner Tileformate in eine
...
@@ -55,47 +82,7 @@ Tileformat zum gleichzeitigen Übertragen mehrerer einzelner Tileformate in eine
\end{description}
\end{description}
\section{Implementierung der 3D Tiles}
\subsection{glTF}
Das GL Transmission Format (glTF \cite{GLTF}) ist ein Format zum effizienten Übertragen von 3D Szenen für Gl Api's wie WebGL. OpenGl ES und OpenGL wird hier nur kurz erwähnt, da es für die Implementierung nicht verwendet wurde.
glTF dient als effizientes, einheitliches und erweiterbares Format zur Übertragung und Laden von 3D Daten.
Im Vergleich zu aktuellen Standards wie COLADA ist glTF optimiert, schnell übertragen und kann schnell in eine Applikation geladen werden.
In einer JSON formatierten Datei (.gltf) wird eine komplette Szene samt Szenengraf, Materialien und deren zugehörigen Shadern, Kamerapositionen, Animationen und Skinning Informationen übertragen.
Dabei kann auf externe Dateien verwiesen werden. Diese sind zum Beispiel Binärdaten oder Bilder, die für das einfache und effiziente Übertragen von Geometrie, Texturen oder den nötigen GLSL Shadern genutzt werden.
\subsection{Struktur}
Die .gltf Datei ist JSON formatiert und bildet den Kern jedes Modells.
In ihr werden alle grundlegenden Informationen wie zum Beispiel die Baumstruktur des Szenengrafen und die Materialien gespeichert (siehe Abb. \ref{img:glTFOverview}).
Eine Szene bildet hierbei den Startpunkt für die zu rendernde Geometrie.
Szenen bestehen aus Knoten (Nodes), die beliebig viele Knoten als Kinder haben können.
Jeder Knoten kann eine Transformation im lokalen Raum definieren, bestehend aus einer Translation, einer Rotation und einer Skalierung.
Jeder Knoten kann eine Mesh und damit die eigentliche Geometrie referenzieren.
Diese Geometrie wird in Buffern als Binärdaten gespeichert. Diese sind entweder als Base64 String direkt im JSON oder als zusätzliche Binärdatei gespeichert.
Auf einen Buffer wird mit einem Accessor und einer Bufferview zugegriffen. In diesen ist spezifiziert, in welchem Format die Daten vorliegen (z.B. ein Array aus 2D Vektoren (VEC2) aus UNSIGNED SHORT).
Alle Datenformate entsprechen Formaten, die in OpenGL vorliegen, sodass die Daten ohne Konvertierung in OpenGL Vertex Array Objetkts (VAO), bzw. Vertex Buffer Objekts (VBO) umgewandelt werden können.
Jedes Mesh kann auf ein Material referenzieren. Materialien bestehen aus Materialparametern, Texturen und Techniken.
Techniken bestehen hauptsächlich aus einem GLSL Shader Programm, das ebenfalls im glTF mitgeliefert wird.
Außerdem wird spezifiziert, wie die VAO und VBO aus dem Mesh bei dem Rendervorgang an den Shader gebunden werden müssen.
Ein weiteres Feature von glTF Datein ist die Möglichkeit, Animationen und Skinning Informationen zu übertragen.
Buffer sind die eigentlichen Daten in einem Binären Block.
Diese können entweder als externe Datei (.bin) oder als BASE64 encodierter String in der JSON Datei angefügt werden.
Die Hauptaufgabe der Buffer ist es, große Mengen an Daten wie die Geometrie effizient zu übertragen.
%glf right Handed y Axis up in Meters and radians
\section{Umsetzung}
Für das Speichern der Punktwolke wurden keine LOD Verfahren angewendet.
Für das Speichern der Punktwolke wurden keine LOD Verfahren angewendet.
In der Praxis hat sich gezeigt, dass die Wolken klein genug sind, sodass sie als ganzes effizient gerendert werden konnten.
In der Praxis hat sich gezeigt, dass die Wolken klein genug sind, sodass sie als ganzes effizient gerendert werden konnten.
Sollte man größere Punktwolken, z.B. von einem ganzen Raum erstellen, könnte das Performancevorteile beim Visualisieren bringen.
Sollte man größere Punktwolken, z.B. von einem ganzen Raum erstellen, könnte das Performancevorteile beim Visualisieren bringen.
...
@@ -105,10 +92,10 @@ Es beinhaltet ein Tile, das auf die Punktwolke referenziert. Es ist nicht transf
...
@@ -105,10 +92,10 @@ Es beinhaltet ein Tile, das auf die Punktwolke referenziert. Es ist nicht transf
Die eigentlichen Daten werden in einem Point Cloud Tile abgespeichert.
Die eigentlichen Daten werden in einem Point Cloud Tile abgespeichert.
Die Positionsdaten der einzelnen Punkte werden als Array aus float abgespeichert.
Die Positionsdaten der einzelnen Punkte werden als Array aus float abgespeichert.
Dabei bilden 3 floats immer die x,y,und z Koordinaten eines Punktes.
Dabei bilden 3 floats immer die x,y,und z Koordinaten eines Punktes.
Zusätzlich speichern wir einen Array an Farbdaten.
Zusätzlich wird einen Array an Farbdaten gespeichert.
Pro Punkt wird jeweils ein Byte pro RGB gespeichert.
Pro Punkt wird jeweils ein Byte pro RGB gespeichert.
Um das Kalibriern zwischen der Echtwelt zu vereinfachen, wurde beim Aufnehmen ein Vive Tracker in der Welt platziert und als Ursprung verwendet.
Um das Kalibriern zwischen der Echtwelt zu vereinfachen, wurde beim Aufnehmen ein Vive Tracker in der Welt platziert und als Ursprung verwendet (siehe Abbildung \ref{img:trackerAufnahme}).
Alle Punkte wurden vor dem Schreiben der Datei in das lokale Koordinatensystem des Trackers transformiert und können beim Visualisieren erneut an dem Tracker orientiert werden.
Alle Punkte wurden vor dem Schreiben der Datei in das lokale Koordinatensystem des Trackers transformiert und können beim Visualisieren erneut an dem Tracker orientiert werden.