3D-(Voxel-/)Schnittbilder(MRT) Visualisieren (OpenGL 4.3)
-
Da heutige Grafikkarten recht schnell sind würde ich eventuell etwas sehr einfaches anwenden.
Z.B. sehr viele transparente 2D flächen hintereinander. OpenGL hat 3d Texturen mit denen man das recht einfach machen kann. Eine Art Raytracer durch eine 3d Texture sollte dabei am schnellsten sein.Bei einem Voxelgitter von 1024x1024x1024 mit einem byte pro texel ist man bei 1GiB.
Wenn man also etwas größeres/detailreicheres darstellen möchte hat diese Technik zu großen Speicherhunger.
-
Vielen Dank für die schnellen Antworten,
In der späteren Verarbeitung soll ein Picking auf der 3D-Grafik vorgenommen werden.
Die MRT-Daten sind so vorsegmentiert, dass lediglich die Gefäße übrig bleiben, und diese sollen markiert werden können.
Um dies zu ermöglichen muss die Grafik auch beliebig rotiert/skaliert werden können.
Mir fällt jetzt spontan kein weg ein wie ich das mit Texturen schön ermöglichen kann. Zumindest mit den 2D-Transparent schichten nicht.
Um was genau Handelt es sich denn bei 3D-Texturen?
Hab da schonmal was zu gelesen, aber hab das nicht so ganz verstanden.Klang allerdings so als könnte das passen.
Lieben Gruß
-
Stichworte: Direct Volume Rendering, Volume Raycasting etc.
-
Heyho dot,
Danke für die Antwort
Hilft mir auf jeden Fall schon mal weiter,
allerdings nur für den weitere Tests mit anderen Verfahren.Ich möchte eigentlich erstmal nur einen "naiven"- (und offensichtlich schlechten) Ansatz implementieren um ihn als Vergleichsverfahren in die Arbeit mit ein zu beziehen.
Ich habe meine z-Schichten mit der größe x*y..Ist der Farbwert meiner Schicht größer 0 möchte ich diesen als Voxel der Größe 1*1*Abtastbreite an der stelle (x,y,z) in meine Scene malen.
Die Ursprungs frage ist jetzt eigentlich: Wie male ich den Voxel in OpenGL.
mit Direct-Volume-Rendering verlasse ich schon wieder den "naiven"-Ansatz einfach Voxel zu male und gehe schon wieder einen (durchaus sinnvollen und Intelligenten) Schritt weiter.
Ähnlich wie bei Marching-Cubes.Lieben Gruß
-
Marching Cubes kann lediglich Isoflächen extrahieren, das ist etwas völlig anderes als DVR, aber ok
Ein ganz einfacher Ansatz wäre wohl etwas basierend auf Slicing, so wie z.B. hier beschrieben: http://http.developer.nvidia.com/GPUGems/gpugems_ch39.html
-
JangoK schrieb:
Die Ursprungs frage ist jetzt eigentlich: Wie male ich den Voxel in OpenGL.
..
Ähnlich wie bei Marching-Cubes.wenn dass das ziel ist, generieren ein mesch. lege einfach eine box pro 'vollen' voxel ab, wobei du keine seite der box ablegst wenn sie zu einem anderen vollen voxel gehoert. das duerfte einfach zu implementieren sein und auf heutigen GPUs vermutlich schneller laufen als man denkt
-
Ok,
danke euch beiden.
Damit kann ich arbeiten
Lieben Gruß
Jango
-
Sry für Doppelposting ^^
Also nochmal für mich zum Verständnis und für alle anderen die es Interessiert und über Google hier drauf Stoßen.
Ausgangspunkt sind 3D-Schicht-Daten wie sie z.B. ein MRT liefert.
Sprich 2D-Schichten und davon "z-viele".Um diese zu Visualisieren gibt es 2 Wege.
Der eine ist das Indirect Volume Rendering.
Worunter der von mir angedachte "Naive"-Ansatz fällt.
Dieser heißt dann meinen Recherchen zur Folge. "Cuberille-Approach"
Unter diesen Punkt würde auch das Marching-Cube Fallen.Dieser Ansatz beschäftigt sich damit, aus den 2D-Schicht Daten wieder ein 3D-Gittermodell zu erstellen welches dann einfach Visualisiert werden kann.
Vorteil - Kann schneller mit Gerechnet werden und leichter manipuliert werden.
Der zweite ist der von dot angesprochene... das Direct Volume Rendering
Dieser beschäftigt sich damit, wie man die 2D-Schichten Visualisieren kann ohne sie vorher in ein 3D-Modell zurück zu rechnen.
Das wird z.B. gemacht indem man die 2D-Schichten als Textur Implementiert unter Hintereinander ablegt und dann per Verfahren wie Ray-Casting auf eine 2D-Schicht abbildet. (Wie Osbios es ansprach)
Problem, dass ich hierbei sehe ist die Rotation um genau 90°, da kommt es bei der Visualisierung zu einer Lücke, weil die 2D-Schichten keine Tiefe haben.
In der Literatur, die ich Online gefunden und einsehen konnte habe ich dafür die Lösung noch nicht gefunden, oder einfach nicht wirklich verstanden
Hab mir jetzt allerdings ein Buch bestellt, was hoffentlich nochmal ein bisschen Klarheit in die ganze Sache bringt.
Falls ich hier irgendwas falsches Schreibe, bitte korregiert mich
Lieben Gruß
Jango
-
eigentlich renderst du nicht die schichten der textur, sondern schichten in die tiefe vom view-cone. du passt dabei die indizierung der textur so an, dass die UVs inverse rotiert sind zur camera rotation. natuerlich benutzt du dafuer dann eine 3d textur, keine z * 2d texturen.
-
JangoK schrieb:
Der zweite ist der von dot angesprochene... das Direct Volume Rendering
Dieser beschäftigt sich damit, wie man die 2D-Schichten Visualisieren kann ohne sie vorher in ein 3D-Modell zurück zu rechnen.
Das wird z.B. gemacht indem man die 2D-Schichten als Textur Implementiert unter Hintereinander ablegt und dann per Verfahren wie Ray-Casting auf eine 2D-Schicht abbildet. (Wie Osbios es ansprach)
Problem, dass ich hierbei sehe ist die Rotation um genau 90°, da kommt es bei der Visualisierung zu einer Lücke, weil die 2D-Schichten keine Tiefe haben.
3d Texturen sampelt man mit 3d-coordinaten.
Man kann dabei einen normalen linear filter anwenden.
Anstelle von 4 Texeln wie bei einer 2d Textur werden bei 3d Texturen 8 Texel gelesen.
-
JangoK schrieb:
Das wird z.B. gemacht indem man die 2D-Schichten als Textur Implementiert unter Hintereinander ablegt und dann per Verfahren wie Ray-Casting auf eine 2D-Schicht abbildet. (Wie Osbios es ansprach)
Problem, dass ich hierbei sehe ist die Rotation um genau 90°, da kommt es bei der Visualisierung zu einer Lücke, weil die 2D-Schichten keine Tiefe haben.
In der Literatur, die ich Online gefunden und einsehen konnte habe ich dafür die Lösung noch nicht gefunden, oder einfach nicht wirklich verstanden
Was haelt Dich davon ab, entsprechende Texturen in x, y und z Richtung zu erzeugen? Du koenntest die dann gleichzeitig darstellen oder einfach immer die nehmen, die fuer den Blickwinkel am Besten passen. Zumindest wuerdest Du so diese "Luecke" ganz einfach umgehen.
-
Gregor schrieb:
Was haelt Dich davon ab, entsprechende Texturen in x, y und z Richtung zu erzeugen? Du koenntest die dann gleichzeitig darstellen oder einfach immer die nehmen, die fuer den Blickwinkel am Besten passen. Zumindest wuerdest Du so diese "Luecke" ganz einfach umgehen.
Nunja, einerseits ist es unnötig weil es 3D Texturen gibt.
Andererseits ist die Schwachstelle dieser Methode der benötigte Speicher und man würde so die dreifache menge Speicher benötigen.
-
Heyho Osbios, heyho Gregor, heyho Community,
ich hab jetzt ein wenig weiter Recherchiert und gelesen und habe mich dazu entschieden beide Vorschläge von Euch zu Implementieren und in meiner Arbeit auf zu nehmen.
Das generelle Vorgehen bei den beiden Verfahren habe ich auch soweit verstanden.
Lediglich zu Implementierung hätte ich noch eine Frage.Als Daten habe ich einen Stapel von 2D-Bildern vorliegen.
Dieser würde beim 2D-Texture-Based-Volume-Rendering ja exakt den Textur-Daten einer Achse entsprechen.Wie Berechne ich mir aus diesem Datensatz sinnvolle Datensätze für die anderen beiden Achsen?
Da steh ich grad noch was auf dem Schlauch
Wäre gut, wenn mir da jemand weiterhelfen könnte ^^
Lieben Gruß
-
JangoK schrieb:
Wie Berechne ich mir aus diesem Datensatz sinnvolle Datensätze für die anderen beiden Achsen?
auch fuer den fall dass ich mich wiederhole:
raps schrieb:
eigentlich renderst du nicht die schichten der textur, sondern schichten in die tiefe vom view-cone. du passt dabei die indizierung der textur so an, dass die UVWs inverse rotiert sind zur camera rotation. natuerlich benutzt du dafuer dann eine 3d textur, keine z * 2d texturen.
-
Hallo rapso,
meine Frage setzt allerdings etwas früher an (wenn ich mich nicht Irre).
Meinen Recherchen zufolge ist es notwendig die durch die Aufnahme vom MRT diskretisierten Daten des Objektes wieder zurück zu Rechnen, da gegebenenfalls auch Daten zwischen den Abtast-Schichten des MRT benötigt werden.
Unabhängig von 2D oder 3D Textur.Methoden zur Rekonstruktion der Daten habe ich mittlerweile allerdings auch gefunden. Beschrieben und verglichen werden einige im Paper von Marschner et. al. "An Evaluation of Reconstruction Filters for Volume Rendering".
Tut mir leid, falls die Frage unklar formuliert war.
Lieben Gruß
-
ich dachte dir ging es darum den existierenden scan zu visualisieren. daten zwischen den pixeln zu interpolieren klingt nach einem ganz anderem topic.
wie waere es wenn du erst die visualisierung loest? wenn das geht, kannst du die daten immer noch erweitern. zuviel auf einmal kann am ende dazu fuehren dass nichts da ist
-
Heyho rapso,
du hast schon recht, mir geht es darum verschiedene Visualisierungs-Verfahren für MRT-Schichtdaten zu implementieren und zu vergleichen.
In der Literatur steht allerdings beschrieben, dass zur Visualisierung mittels Direct-Volume-Rendering vorher eine Rekonstruktion und Klassifikation der Schichtdaten vorgenommen werden muss. Ansonsten kann Beispielsweise das 2D und/oder 3D-Texture-Based-Rendering garnicht vorgenommen werden, da Werte fehlen um die notwendigen Render-Schichten zu erzeugen.
Daher muss ich scheinbar um das Problem der Visualisierung zu lösen, erst einmal das Problem der Rekonstruktion und Klassifizierung lösen. ^^
-
Du musst nicht unbedingt interpolieren.
Wenn Du Direct Volume Rendering betreibst und dafür einen Raycasting-Algorithmus verwendest, dann ist letztendlich die Frage, wie Du den "Strahl" diskretisierst. Du kannst natürlich sagen, dass Du einen Strahl hast, der die Voxel nicht genau trifft und deshalb muss immer zwischen verschiedenen Voxeln interpoliert werden. Du könntest aber auch einen Bresenham Linienalgorithmus zur Erzeugung des Strahls verwenden. Der liefert Dir einen Strahl in Form von einer Menge diskreter Koordinaten, an denen sich jeweils ein Voxel befindet. Das Resultat davon ist möglicherweise um Nuancen schlechter als ein Algorithmus, der mit Interpolation arbeitet, dafür ist er aber auch wesentlich schneller. Du brauchst dort eben keine Interpolation und zudem läuft das Erzeugen der Linie mit Ganzzahlarithmetik.
Ich habe vor langer Zeit auch mal etwas mit Direct Volume Rendering rumgespielt und dafür so einen Bresenham Algorithmus verwendet. Herausgekommen sind Darstellungen wie die da:
https://i.imgur.com/i7oXNBq.png
Ist vielleicht etwas grobpixelig. Andererseits wird das pixelige nicht direkt etwas mit dem Bresenham-Algorithmus zu tun haben.
-
mir ist nicht ganz klar was du rekonstruieren bzw klassifizieren willst. fuer die visualisierung sind eigentlich nur die schnittbilder noetig und die hast du, wie du sagtest.
dann muss man das nur auf die GPU laden und raycastern wie z.B. bei http://demos.vicomtech.org/volren/ zu sehen (ein browser mit WebGL ist noetig).
-
Generell hast du recht.
Angenommen ich möchte Raycasten kann ich das wie Gregor auch schon beschrieben hat vollkommen ohne Interpolation/Rekonstruktion machen.Allerdings geht es mir weniger darum irgend einen Algorithmus zu implementieren.
Sondern mehr darum mehrere mögliche Verfahren zu beschreiben, zu testen und dann Anhand der Ergebnisse zu Vergleichen um begründen zu können warum ich mich für Verfahren XY entschieden habe.Zu den Verfahren gehört unter anderem auch das Raycasting, welches als Bildbasiertes Verfahren gilt.
Allerdings gibt es im Bezug auf Direct-Volume-Rendering noch verfahren wie Splatting, welches Objektbasiert ist, oder Shear-Warp und Texture-Mapping, welche Mischformen sind.
Bei diesen Verfahren ist dann eine Interpolation/Rekonstruktion der Daten notwendig.
Und bei allen Verfahren ist eine Klassifikation notwendig, auch beim Raycasting.
Denn die Definition der Objekteigenschaft (Grauwert XY ist transparent etc) ist ein Teil der Klassifikation.Des Weiteren gibt es auch noch das Indirect-Volume-Rendering. Wo dann Verfahren wie Marching-Cubes eine Rolle spielen um Oberflächen Approximationen zu erzeugen.
Gruß
Jango