Discussion:
Winkel aus Drehmatrix zurückrechnen
(zu alt für eine Antwort)
Alex Schuster
2011-07-07 14:48:31 UTC
Permalink
Hallo!

Ich komme bei einem Problem nicht so recht weiter. Es geht um tomografische
Aufnahmen, beispielsweise die Kernspinaufnahme eines Kopfes, die gedreht
sind, und die ich wieder zurückdrehen möchte. Die X-Achse zeigt hierbei aus
Sicht des Patienten nach links, die Y-Achse nach hinten, die Z-Achse in
Kopfrichtung. Eine Aufnahme setzt sich aus einem Stapel von Schichten
zusammen, und die Orientierung einer Schicht kann recht beliebig sein
(untereinander sind sie natürlich gleich orientiert). Ohne Rotation würden
X- und Y-Achse der Schicht dem Patientenkoordinatensystem entsprechen, und
der Normalenvektor ginge in Richtung Fuß->Kopf.

Die Lage der Schichten ist oft aber anders gewählt, um eine höhere
Bildqualität zu erreichen - idR ist die Auflösung innerhalb einer Schicht
höher als der Abstand der Schichten voneinander.

Die Software, mit der ich die Bilder anzeige, kann sie beliebig drehen und
verschieben. Die Drehungen werden dabei durch Winkel rx, ry und rz um die
X-, Y- und Z-Achse bestimmt, in dieser Reihenfolge. Die Achsen sind dabei
nicht ortsfest, sondern drehen sich dabei mit.

Die Datensätze liegen im DICOM-Format vor. Die Rotation wird dabei nicht in
Winkeln oder als Drehmatrix angegeben, sondern in Form von zwei mal drei
Werten, die den Kosinus des Winkels zwischen der X-/Y-Achse des Bildes und
den X-, Y- und Z-Achsen des Koordinatensystems angeben.

Beispiel: bei einer Orientierung von (1,0,0) / (0,1,0) wäre nichts zu tun.
Die X-Achse des Bildes liegt entlang der X-Achse des Patienten, der Kosinus
ist 1, und die beiden anderen Achsen sind zu ihr orthogonal, der Kosinus ist
0. Entsprechend bei der Y-Achse des Bildes.

Anderes Beispiel: (0,1,0) / (0,0,-1) ist sagittale Orientierung, eine
Schicht zeigt einen Schnitt bei dem die X-Richtung von vorne nach hinten
geht und die Y-Richtung von oben nach unten. Die X-Achse des Bildes liegt
auf der Y-Achse im Patientenkoordinatensystem, d.h. Richtung Hinterkopf. Die
Y-Achse des Bildes liegt auf der Z-Achse im Patientenkoordinatensystem, aber
entgegengesetzt. In meiner Applikation entspricht das einer Drehung von
jeweils -90 Grad um die X- und die Y-Achse.

Aber an einer allgemeinen Lösung bin ich bislang gescheitert. Ich habe es so
versucht:

/ oxX oyX oxY*oyZ-oxZ*oyY \
R = | oxY oyY oxZ*oyX-oxX*oyZ |
\ oxZ oyZ oxX*oyY-oxY*oyX /

oij ist dabei der Richtungskosinus der i-Achse des Bildes und der
Patientenachse j. Die ersten beiden Spalten sind einfach meine beiden
Vektoren der Richtungskosinusse. Die dritte Spalte ist ihr Vektorprodukt.

Das sollte also die Drehung des Bildes beschreiben. Die invertierte (bzw.
transponierte) Drehmatrix beschreibt dann die Drehung, die ich letztlich
ausführen möchte.

Nun will ich die Winkel aus der Drehmatrix zurückrechnen. Auf [*] habe ich
dazu folgende Formeln gefunden:

ry = atan2( -R31, sqrt( R11^2+R21^2 ) )
rx = atan2( R21/cos(ry), R11/cos(ry) )
rz = atan2( R32/cos(ry), R33/cos(ry) )

So klappt's aber nicht. Ich glaube, der Fehler liegt einfach nur darin,
dass hier von einer raumfesten Orthogonalbasis ausgegangen wird, d.h. die
Achsen drehen sich nicht mit. Ich finde aber keine Formel für den Fall,
dass sie sich mitdrehen. Hat die vielleicht hier jemand parat? Oder denke
ich eh zu kompliziert? Über Hinweise würde ich mich sehr freuen.

Wonko

[*] http://de.wikipedia.org/wiki/Roll-Nick-Gier-Winkel#Berechnung_aus_Rotationsmatrix
Ernst Sauer
2011-07-07 15:35:28 UTC
Permalink
Am 07.07.2011 16:48, schrieb Alex Schuster:
...
...
Post by Alex Schuster
Beispiel: bei einer Orientierung von (1,0,0) / (0,1,0) wäre nichts zu tun.
Die X-Achse des Bildes liegt entlang der X-Achse des Patienten, der Kosinus
ist 1, und die beiden anderen Achsen sind zu ihr orthogonal, der Kosinus ist
0. Entsprechend bei der Y-Achse des Bildes.
Anderes Beispiel: (0,1,0) / (0,0,-1) ist sagittale Orientierung,
Ich sehe es so:
Durch die beiden Vektoren werden die Koordinatenachsen x' und y'
beschrieben, z' ergibt sich aus dem Kreuzprodukt.
Für die Transformation {x'] = [T]*{x} ergeben sich die Elemente von T zu
T_ij = cos(x_i', x_j) mit (x_1, x_2, x_3)=(x,y,z)
Den cos() erhält man aus dem Skalarprodukt der Einheitsvektoren
der Achsen.

Gruß
E.S.
Alex Schuster
2011-07-07 17:14:24 UTC
Permalink
Post by Ernst Sauer
Post by Alex Schuster
Beispiel: bei einer Orientierung von (1,0,0) / (0,1,0) wäre nichts zu
tun. Die X-Achse des Bildes liegt entlang der X-Achse des Patienten, der
Kosinus ist 1, und die beiden anderen Achsen sind zu ihr orthogonal, der
Kosinus ist 0. Entsprechend bei der Y-Achse des Bildes.
Anderes Beispiel: (0,1,0) / (0,0,-1) ist sagittale Orientierung,
Durch die beiden Vektoren werden die Koordinatenachsen x' und y'
beschrieben, z' ergibt sich aus dem Kreuzprodukt.
Für die Transformation {x'] = [T]*{x} ergeben sich die Elemente von T zu
T_ij = cos(x_i', x_j) mit (x_1, x_2, x_3)=(x,y,z)
Das ist in der Tat eine bessere und weniger umständliche Formulierung als
meine :)
Post by Ernst Sauer
Den cos() erhält man aus dem Skalarprodukt der Einheitsvektoren
der Achsen.
Tja, aber wie erhalte ich nun die benötigten Drehwinkel?

Wonko
Ernst Sauer
2011-07-07 18:28:30 UTC
Permalink
Am 07.07.2011 19:14, schrieb Alex Schuster:
...
Post by Alex Schuster
Tja, aber wie erhalte ich nun die benötigten Drehwinkel?
Wonko
Brauchst Du denn unbedingt Winkel, wenn die Transformationsmatrix
bekannt ist?

Andererseits:
wenn man sich die Matrix [Mfg] auf der Seite
http://de.wikipedia.org/wiki/Eulersche_Winkel anschaut,
dann erhält man

sin(t) = (-T_13)
tan(psi) = (T_21/T_11)
tan(phi) = (T_23/T_33)

Die Umkehrfunktionen liefern die Winkel bis auf
Anteile +- pi/2.
Durch die noch nicht genutzten Bedingungen sollte man
die Winkel bestimmen können. Notfalls muss man mit
+/- pi/2 spielen und probieren, was in einem Programm
ja kein Problem ist.

Gruß
E.S.
Ernst Sauer
2011-07-07 19:34:13 UTC
Permalink
Post by Alex Schuster
Tja, aber wie erhalte ich nun die benötigten Drehwinkel?
Brauchst Du denn die Winkel noch, wenn die Transformationsmatrix gegeben
ist?

Andererseits kann man mit der Matrix [Mfg]
http://de.wikipedia.org/wiki/Eulersche_Winkel folgendes
anschreiben:

sin(t) = (-T_13)
tan(psi) = (T_21/T_11)
tan(phi) = (T_23/T_33)

Die Umkehrfunktionen liefern noch keine eindeutigen Winkel.
Kannst Du vielleicht aus Deiner Anwendung heraus die
Winkel so eingrenzen (z.B. -pi/2 <= t <= pi/2), dass die
Umkehrfunktionen schon eindeutige Winkel liefern?

Sonst muss man sich die anderen Bedingungen noch anschauen.

Gruß
E.S.
Ernst Sauer
2011-07-08 08:25:24 UTC
Permalink
Post by Alex Schuster
Tja, aber wie erhalte ich nun die benötigten Drehwinkel?
Hallo,
ich nehme noch einmal die Gleichungen
sin(t) = (-T_13)
tan(psi) = (T_21/T_11)
tan(phi) = (T_23/T_33)
sowie tan = sin/cos.

Da für psi und phi die Vorzeichen von sin und cos bekannt sind,
kann man mit dem atan2 die Winkel eindeutig berechnen:

psi = atan2(T_21,T_11)
phi = atan2(T_23,T_33)

Mit cos(t)*sin(psi) = T_11
ergibt sich das Vorzeichen von cos(t), damit
ist dann auch der Winkel t klar.

Müsste passen.

Gruß
E.S.
Oliver Jennrich
2011-07-07 18:56:04 UTC
Permalink
Post by Alex Schuster
Die Datensätze liegen im DICOM-Format vor. Die Rotation wird dabei nicht in
Winkeln oder als Drehmatrix angegeben, sondern in Form von zwei mal drei
Werten, die den Kosinus des Winkels zwischen der X-/Y-Achse des Bildes und
den X-, Y- und Z-Achsen des Koordinatensystems angeben.
Beispiel: bei einer Orientierung von (1,0,0) / (0,1,0) wäre nichts zu tun.
Die X-Achse des Bildes liegt entlang der X-Achse des Patienten, der Kosinus
ist 1, und die beiden anderen Achsen sind zu ihr orthogonal, der Kosinus ist
0. Entsprechend bei der Y-Achse des Bildes.
Anderes Beispiel: (0,1,0) / (0,0,-1) ist sagittale Orientierung, eine
Schicht zeigt einen Schnitt bei dem die X-Richtung von vorne nach hinten
geht und die Y-Richtung von oben nach unten. Die X-Achse des Bildes liegt
auf der Y-Achse im Patientenkoordinatensystem, d.h. Richtung Hinterkopf. Die
Y-Achse des Bildes liegt auf der Z-Achse im Patientenkoordinatensystem, aber
entgegengesetzt. In meiner Applikation entspricht das einer Drehung von
jeweils -90 Grad um die X- und die Y-Achse.
Aber an einer allgemeinen Lösung bin ich bislang gescheitert.
Es gibt viele Möglichkeiten, die Lage eines gedrehten Koordinatensystems
zu charakterisieren, z.B. die Eulerschen Winkel
(http://de.wikipedia.org/wiki/Eulersche_Winkel). In jedem Fall kann man
die Drehung aus dem ursprünglichen KS in das neue KS durch eine
Drehmatrix M beschreiben, in deren Spalten die Koordinaten der *neuen*
Basiseinheitsvektoren im *alten* KS stehen, bzw. in deren Reihen die *alten*
Basiseinheitsvektoren im *neuen* KS.

Da der Kosinus des Winkels alpha zwischen zwei Einheitsvektoren u und v
schlicht durch das Skalarprodukt gegeben ist, liest man die beiden
DICOM-Zahentripel einfach aus der Matrix ab: Sie entsprechen den ersten
beiden Spalten.

Umgekehrt bekommt man aus den DICOM-Tripeln natürlich auch die dritte
Spalte der Rotationsmatrix (die ersten beiden Spalten kennt man ja
schon). Dazu macht man sich zunutze, dass es sich um eine Drehmatrix
handelt, also die Spalten (und Reihen) paarweise aufeinander senkrecht
stehen. Wenn also M=(a,b,c) ist, dann ist c=axb oder c=bxa. Welche
Version man nimmt entscheidet man anhand der Determinante, die positiv
sein muß.
--
Space - The final frontier
Norbert Dragon
2011-07-08 14:50:52 UTC
Permalink
Post by Oliver Jennrich
Umgekehrt bekommt man aus den DICOM-Tripeln natürlich auch die dritte
Spalte der Rotationsmatrix (die ersten beiden Spalten kennt man ja
schon). Dazu macht man sich zunutze, dass es sich um eine Drehmatrix
handelt, also die Spalten (und Reihen) paarweise aufeinander senkrecht
stehen. Wenn also M=(a,b,c) ist, dann ist c=axb oder c=bxa. Welche
Version man nimmt entscheidet man anhand der Determinante, die positiv
sein muß.
Bei einer Drehung ist c = a x b, nur dann bilden die Bilder
der Basisvektoren genauso ein Rechtshandsystem wie die Urbilder.
--
Aberglaube bringt Unglück

www.itp.uni-hannover.de/~dragon
Detlef Bosau
2011-07-07 23:22:37 UTC
Permalink
Ist die Abbildung, die Du durchführst, eine reine Drehung? Oder kommt da
möglicherweise noch eine Verschiebung rein?

Mir ist noch nicht ganz klar, was bei Dir die Daten sind, die Dir
bekannt sind und welche Du suchst. Kannst Du da evtl. eine Skizze zu
bringen?
Alex Schuster
2011-07-08 00:05:16 UTC
Permalink
Post by Detlef Bosau
Ist die Abbildung, die Du durchführst, eine reine Drehung? Oder kommt da
möglicherweise noch eine Verschiebung rein?
Ja, die gibt's auch noch. Die habe ich aber korrigiert bekommen, das war
vergleichsweise einfach.
Post by Detlef Bosau
Mir ist noch nicht ganz klar, was bei Dir die Daten sind, die Dir
bekannt sind und welche Du suchst. Kannst Du da evtl. eine Skizze zu
bringen?
Hmm, das ließe sich schon machen. Aber heute nicht mehr, langsam wird's
spät. Und ich alt, vor einigen Jahren bin ich selten vor 4 Uhr ins Bett
gegangen...

Inzwischen habe ich auch eine Routine gefunden, die machen sollte was ich
benötige, sogar im Source-Code der Applikation, die die Daten schließlich
auch anzeigt. Ich hänge das mal mit rein, falls es wen interessiert. Die
Routine addiert zwei Rotationen, indem sie die in Drehmatrizen wandelt,
diese multipliziert, und dann die Winkel zurückrechnet.

Es kommt aber immer noch nicht das richtige heraus. Irgendwas stimmt wohl
mit meiner Drehmatrix noch nicht. Ich habe das s im Code unten gleich dem
Inversen der aus den DICOM-Richtungskosinussen erstellten Drehmatrix
gewählt, aber das haut so gar nicht hin. Ist vielleicht nur ein dummer
kleiner Fehler, morgen schaue ich mal weiter. Aber schönen Dank für's
Interesse :) Ich bin heutzutage leider kaum noch im Usenet unterwegs, aber
hier könnte ich mich mal wieder festlesen.


void setup_invrotmatrix_xyz( m, ax, ay, az )
double (*m)[3][3], ax, ay, az;
{
(*m)[0][0] = cos(ay) * cos(az);
(*m)[0][1] = cos(ay) * sin(az);
(*m)[0][2] = sin(ay);
(*m)[1][0] = -sin(ax) * sin(ay) * cos(az) - cos(ax) * sin(az);
(*m)[1][1] = -sin(ax) * sin(ay) * sin(az) + cos(ax) * cos(az);
(*m)[1][2] = sin(ax) * cos(ay);
(*m)[2][0] = -cos(ax) * sin(ay) * cos(az) + sin(ax) * sin(az);
(*m)[2][1] = -cos(ax) * sin(ay) * sin(az) - sin(ax) * cos(az);
(*m)[2][2] = cos(ax) * cos(ay);
}

static double defc( d )
double d;
{
if( d < -1.0 ) return( -1.0 );
if( d > 1.0 ) return( 1.0 );
return( d );
}

void add_rot_mat( ax, ay, az, bx, by, bz )
double *ax, *ay, *az, bx, by, bz;
{
double rx, ry, rz, tmp;
double s[3][3], r[3][3], m[3][3];

setup_invrotmatrix_xyz( r, *ax, *ay, *az );
setup_invrotmatrix_xyz( m, bx, by, bz );
mat_mult( s, m, r );

ry = asin(defc(s[0][2]));
if( ABS(cos(ry)) < 1e-6 ) {
rz = 0.0;
if( ry < 0.0 ) {
rx = acos(defc(s[2][0]))
* ((tmp=SGN(asin(defc(s[1][0]))))?tmp:1.0);
} else {
rx = acos(defc(-s[2][0]))
* ((tmp=SGN(asin(defc(-s[1][0]))))?tmp:1.0);
}
} else {
rx = acos(defc(s[2][2]/cos(ry)))
* ((tmp=SGN(asin(defc(s[1][2]/cos(ry)))))?tmp:1.0);
rz = acos(defc(s[0][0]/cos(ry)))
* ((tmp=SGN(asin(defc(s[0][1]/cos(ry)))))?tmp:1.0);
}

*ax = rx;
*ay = ry;
*az = rz;
}

Wonko
Christian Gollwitzer
2011-07-08 05:53:22 UTC
Permalink
Hallo Axel,
Post by Alex Schuster
Inzwischen habe ich auch eine Routine gefunden, die machen sollte was ich
benötige, sogar im Source-Code der Applikation, die die Daten schließlich
auch anzeigt. Ich hänge das mal mit rein, falls es wen interessiert. Die
Routine addiert zwei Rotationen, indem sie die in Drehmatrizen wandelt,
diese multipliziert, und dann die Winkel zurückrechnet.
Es kommt aber immer noch nicht das richtige heraus.
das ist der Grund warum ich Euler-Winkel auch hasse. Man muss nämlich
dazu sagen, in welcher Reihenfolge - und von welcher Seite - die
Drehmatrizen aufmultipliziert werden. Da gibt es mehrere Konventionen.
Eine ist Drehung um Z, dann Y, dann X, wobei die Matrizen immer rechts
dranmultipliziert werden. Dann gibt es Z-Y-Z, Matrizen werden von links
hinmultipliziert. Sehe gerade, dass auf Wikipedia unter Euler-Winkel
steht, dass sich 3 Konventionen etabliert haben. Ich hab mich jetzt
nicht durch Dein Posting gewühlt, würde aber einfach erst mal versuchen,
durch Testen von charakteristischen Kombinationen (also rx=20°, ry=30°,
rz=0 durchpermutieren) rauszukriegen, wie genau Deine Software die
Drehungen in die Matrix konvertertiert.

Eine andere Möglichkeit zur eindeutigen Zerlegung ist die
Quaternionen-Rotation, also die Drehung um eine schiefe Achse. Das ist
dann deutlich weniger mehrdeutig (Achse kann flippen, Winkel modulo
2pi), hilft Dir aber vermutlich nicht weiter.

Christian
Christian Gollwitzer
2011-07-08 06:22:15 UTC
Permalink
PS:
Eine große Sammlung mit Formeln gibts hier:
http://en.wikipedia.org/wiki/Rotation_representation_%28mathematics%29
Wenn Du Glück hast, spuckt die Formel für Matrix->Euler die Winkel aus,
möglicherweise in der falschen Reihenfolge. Sie sieht zumindest anders
aus als Deine;) Ansonsten musst Du alle 12 Möglichkeiten durchprobieren
http://en.wikipedia.org/wiki/Euler_angles#Conventions

Viel Spaß!

Christian
Detlef Bosau
2011-07-08 15:23:15 UTC
Permalink
Post by Christian Gollwitzer
Hallo Axel,
Post by Alex Schuster
Inzwischen habe ich auch eine Routine gefunden, die machen sollte was ich
benötige, sogar im Source-Code der Applikation, die die Daten schließlich
auch anzeigt. Ich hänge das mal mit rein, falls es wen interessiert. Die
Routine addiert zwei Rotationen, indem sie die in Drehmatrizen wandelt,
diese multipliziert, und dann die Winkel zurückrechnet.
Es kommt aber immer noch nicht das richtige heraus.
das ist der Grund warum ich Euler-Winkel auch hasse. Man muss nämlich
Und warum nehmt Ihr sie dann?

Wenn ich die Drehungsmatrix habe, kann ich mit der Matrix arbeiten. Für
was genau brauche ich dann die Winkel?
Christian Gollwitzer
2011-07-08 15:33:40 UTC
Permalink
Post by Detlef Bosau
Post by Christian Gollwitzer
Hallo Axel,
Post by Alex Schuster
Inzwischen habe ich auch eine Routine gefunden, die machen sollte was ich
benötige, sogar im Source-Code der Applikation, die die Daten schließlich
auch anzeigt. Ich hänge das mal mit rein, falls es wen interessiert. Die
Routine addiert zwei Rotationen, indem sie die in Drehmatrizen wandelt,
diese multipliziert, und dann die Winkel zurückrechnet.
Es kommt aber immer noch nicht das richtige heraus.
das ist der Grund warum ich Euler-Winkel auch hasse. Man muss nämlich
Und warum nehmt Ihr sie dann?
Wenn ich die Drehungsmatrix habe, kann ich mit der Matrix arbeiten. Für
was genau brauche ich dann die Winkel?
Die braucht man nur dann, wenn man eine Software hat, die die
Eingabe/Ausgabe der Euler-Winkel verlangt. Wenn ich mir das aussuchen
kann, rotiere ich mit Quaternionen. Wenn man z.B. die Drehung sucht, die
Vektor a auf Vektor b rotiert, dann ist a x b die Drehachse und a*b der
Kosinus des Winkels. Daraus ergibt sich sofort das Quaternion für die
Drehung.

Christian
Alex Schuster
2011-07-08 16:26:03 UTC
Permalink
Post by Christian Gollwitzer
Hallo Axel,
Post by Alex Schuster
Es kommt aber immer noch nicht das richtige heraus.
Allerdings die exakt gleichen Winkel, die auch meine Methode liefert. Wobei
meine Methode mit drei Zeilen Code auskommt :)
Post by Christian Gollwitzer
das ist der Grund warum ich Euler-Winkel auch hasse. Man muss nämlich
dazu sagen, in welcher Reihenfolge - und von welcher Seite - die
Drehmatrizen aufmultipliziert werden. Da gibt es mehrere Konventionen.
Eine ist Drehung um Z, dann Y, dann X, wobei die Matrizen immer rechts
dranmultipliziert werden. Dann gibt es Z-Y-Z, Matrizen werden von links
hinmultipliziert. Sehe gerade, dass auf Wikipedia unter Euler-Winkel
steht, dass sich 3 Konventionen etabliert haben. Ich hab mich jetzt
nicht durch Dein Posting gewühlt, würde aber einfach erst mal versuchen,
durch Testen von charakteristischen Kombinationen (also rx=20°, ry=30°,
rz=0 durchpermutieren) rauszukriegen, wie genau Deine Software die
Drehungen in die Matrix konvertertiert.
Das weiß ich schon, sie dreht nach dem Schema X-Y-Z.
Post by Christian Gollwitzer
Eine andere Möglichkeit zur eindeutigen Zerlegung ist die
Quaternionen-Rotation, also die Drehung um eine schiefe Achse. Das ist
dann deutlich weniger mehrdeutig (Achse kann flippen, Winkel modulo
2pi), hilft Dir aber vermutlich nicht weiter.
Ja, ich hatte auch überlegt, es mit Quaternionen zu versuchen. Die kenne ich
nicht wirklich gut, aber ich hatte sie vor einer Weile mal verwendet, und
dann auch die Drehwinkel aus ihnen zurückgerechnet. Was prima funktioniert
hatte.

Aber inzwischen habe ich die Lösung gefunden. Seit Tagen suche ich danach,
und dann waren nur zwei Vorzeichen falsch, der X- und Z-Winkel. Ich verstehe
zwar noch nicht warum, aber es scheint zu funktionieren.
Ich hatte ein paar Testdaten eingeladen, die um 90 Grad gedreht waren, und
mir fiel auf dass ich bis auf die Vorzeichen die gleichen Werte hatte. Also
habe ich die Vorzeichen geändert, und schon stimmte es.

Das ist echt frustrierend. Ich freue mich zwar, dass ich es letztlich
hinbekommen habe, aber es wäre schön, wenn meine Formeln auch mal auf Anhieb
richtig wären.

Wonko
Hero
2011-07-08 14:35:39 UTC
Permalink
Post by Alex Schuster
Hallo!
Ich komme bei einem Problem nicht so recht weiter. Es geht um tomografische
Aufnahmen, beispielsweise die Kernspinaufnahme eines Kopfes, die gedreht
sind, und die ich wieder zurückdrehen möchte.
Vielleicht hilft dies:
http://1iz.heimat.eu/theart-Dateien/rot-deutsch.pdf

Mit freundlichen Grüßen
Hero
Robert Rohling
2011-07-08 16:00:47 UTC
Permalink
Post by Alex Schuster
Hallo!
Ich komme bei einem Problem nicht so recht weiter. Es geht um
tomografische Aufnahmen, beispielsweise die Kernspinaufnahme eines
Kopfes, die gedreht sind, und die ich wieder zurückdrehen möchte. Die
X-Achse zeigt hierbei aus Sicht des Patienten nach links, die Y-Achse
nach hinten, die Z-Achse in Kopfrichtung. Eine Aufnahme setzt sich aus
einem Stapel von Schichten zusammen, und die Orientierung einer
Schicht kann recht beliebig sein (untereinander sind sie natürlich
gleich orientiert). Ohne Rotation würden X- und Y-Achse der Schicht
dem Patientenkoordinatensystem entsprechen, und der Normalenvektor
ginge in Richtung Fuß->Kopf.
Die Lage der Schichten ist oft aber anders gewählt, um eine höhere
Bildqualität zu erreichen - idR ist die Auflösung innerhalb einer
Schicht höher als der Abstand der Schichten voneinander.
Die Software, mit der ich die Bilder anzeige, kann sie beliebig drehen
und verschieben. Die Drehungen werden dabei durch Winkel rx, ry und rz
um die X-, Y- und Z-Achse bestimmt, in dieser Reihenfolge. Die Achsen
sind dabei nicht ortsfest, sondern drehen sich dabei mit.
Die Datensätze liegen im DICOM-Format vor.
Laut c.p.d. hast du es jetzt ja.
Nur mal so interessehalber. Hast du das Proggi zur Umwandlung und
Anzeige der dcm-Dateien auch selber geschrieben und soll das dann gedreht
wieder als dcm zurückgeschrieben werden?


Gruß R.R.
--
Ich bin unschuldig, ich hab sie nicht gewählt!
Alex Schuster
2011-07-08 16:56:53 UTC
Permalink
[...]
Post by Robert Rohling
Post by Alex Schuster
Die Datensätze liegen im DICOM-Format vor.
Laut c.p.d. hast du es jetzt ja.
Ja, in der DICOM-Newsgroup hatte ich auch mal gefragt. Das schien mir dann
aber nicht so passend, das Problem ist mehr Mathe als das DICOM-Protokoll an
sich.
Post by Robert Rohling
Nur mal so interessehalber. Hast du das Proggi zur Umwandlung und
Anzeige der dcm-Dateien auch selber geschrieben und soll das dann gedreht
wieder als dcm zurückgeschrieben werden?
Ich hab's nicht geschrieben, aber einige kleinere Teile beigesteuert, z.B.
den DICOM-Import.

Ziel ist, dass mehrere Messungen des gleichen Patienten (der die gleiche
räumliche Position einnimmt, aber mit unterschiedlichen Winkeln gemessen
wurde) exakt aufeinander abgeglichen dargestellt werden.

DICOM-Export haben wir leider noch nicht drin. Ich hatte das mal angefangen,
aber konformes DICOM zu schreiben ist dann doch ganz schön aufwändiger als
es nur zu lesen. Wir setzen für solche Zwecke das DICOM-Toolkit (DCMTK) von
Offis ein, aber das ist in dieser Software noch nicht implementiert. Für's
Lesen bleiben wir bei meinen eigenen Routinen, die sind nicht so mächtig,
aber dafür viel schneller.

Ich werde nun aber wohl auch einen Konverter auf Kommandozeilenbasis
schreiben, der die Daten dann auch exportiert. Dazu werde ich dann komplett
das DCMTK nehmen, das ich übrigens sehr empfehlen kann, wenn man mal DICOM-
Software schreiben will.

Wonko
Robert Rohling
2011-07-08 17:21:14 UTC
Permalink
Post by Alex Schuster
[...]
Post by Robert Rohling
Post by Alex Schuster
Die Datensätze liegen im DICOM-Format vor.
Laut c.p.d. hast du es jetzt ja.
Ja, in der DICOM-Newsgroup hatte ich auch mal gefragt. Das schien mir
dann aber nicht so passend, das Problem ist mehr Mathe als das
DICOM-Protokoll an sich.
Post by Robert Rohling
Nur mal so interessehalber. Hast du das Proggi zur Umwandlung und
Anzeige der dcm-Dateien auch selber geschrieben und soll das dann
gedreht wieder als dcm zurückgeschrieben werden?
Ich hab's nicht geschrieben, aber einige kleinere Teile beigesteuert,
z.B. den DICOM-Import.
Ziel ist, dass mehrere Messungen des gleichen Patienten (der die
gleiche räumliche Position einnimmt, aber mit unterschiedlichen
Winkeln gemessen wurde) exakt aufeinander abgeglichen dargestellt
werden.
DICOM-Export haben wir leider noch nicht drin. Ich hatte das mal
angefangen, aber konformes DICOM zu schreiben ist dann doch ganz schön
aufwändiger als es nur zu lesen.
Naja, dann hätt ich dir viel Spaß beim Lesen der Dicom-Bibel gewünscht.
(ftp://medical.nema.org/medical/dicom/2009/)
SCNR...
Post by Alex Schuster
Wir setzen für solche Zwecke das
DICOM-Toolkit (DCMTK) von Offis ein, aber das ist in dieser Software
noch nicht implementiert. Für's Lesen bleiben wir bei meinen eigenen
Routinen, die sind nicht so mächtig, aber dafür viel schneller.
Ich werde nun aber wohl auch einen Konverter auf Kommandozeilenbasis
schreiben, der die Daten dann auch exportiert. Dazu werde ich dann
komplett das DCMTK nehmen, das ich übrigens sehr empfehlen kann, wenn
man mal DICOM- Software schreiben will.
Ähmmm, naja, geschenkter Gaul und so. Aber ich hab da schon einige
Abwärtskompatibilitätsprobleme bei denen entdeckt.


Gruß R.R.
--
Ich bin unschuldig, ich hab sie nicht gewählt!
Alex Schuster
2011-07-08 17:51:35 UTC
Permalink
Post by Robert Rohling
Post by Alex Schuster
DICOM-Export haben wir leider noch nicht drin. Ich hatte das mal
angefangen, aber konformes DICOM zu schreiben ist dann doch ganz schön
aufwändiger als es nur zu lesen.
Naja, dann hätt ich dir viel Spaß beim Lesen der Dicom-Bibel gewünscht.
(ftp://medical.nema.org/medical/dicom/2009/)
SCNR...
Och, die kenne ich gut, auch wenn ich nicht jede Seite gelesen habe... von
Teil 5 mal abgesehen. War schon ein heftiges Erlebnis, am Anfang.
Post by Robert Rohling
Post by Alex Schuster
Wir setzen für solche Zwecke das
DICOM-Toolkit (DCMTK) von Offis ein, aber das ist in dieser Software
noch nicht implementiert. Für's Lesen bleiben wir bei meinen eigenen
Routinen, die sind nicht so mächtig, aber dafür viel schneller.
Ich werde nun aber wohl auch einen Konverter auf Kommandozeilenbasis
schreiben, der die Daten dann auch exportiert. Dazu werde ich dann
komplett das DCMTK nehmen, das ich übrigens sehr empfehlen kann, wenn
man mal DICOM- Software schreiben will.
Ähmmm, naja, geschenkter Gaul und so. Aber ich hab da schon einige
Abwärtskompatibilitätsprobleme bei denen entdeckt.
Tja, und das ist dann wieder so eine Sache, wo es schön ist, wenn man es
selbst macht. Ich hatte früher auch oft mit kaputten DICOM-Daten zu tun, die
das DCMTK dann auch nicht parsen kann. Aber die Situation hat sich
gebessert.

Wonko
Robert Rohling
2011-07-08 18:36:43 UTC
Permalink
Post by Alex Schuster
Post by Robert Rohling
Naja, dann hätt ich dir viel Spaß beim Lesen der Dicom-Bibel
gewünscht. (ftp://medical.nema.org/medical/dicom/2009/) SCNR...
Och, die kenne ich gut, auch wenn ich nicht jede Seite gelesen habe...
von Teil 5 mal abgesehen. War schon ein heftiges Erlebnis, am Anfang.
Ja gell, da kommt Freude auf...
Post by Alex Schuster
Post by Robert Rohling
Wir setzen für solche Zwecke das DICOM-Toolkit (DCMTK) von Offis
ein, aber das ist in dieser Software noch nicht implementiert. Für's
Lesen bleiben wir bei meinen eigenen Routinen, die sind nicht so
mächtig, aber dafür viel schneller.
Ich werde nun aber wohl auch einen Konverter auf Kommandozeilenbasis
schreiben, der die Daten dann auch exportiert. Dazu werde ich dann
komplett das DCMTK nehmen, das ich übrigens sehr empfehlen kann,
wenn man mal DICOM- Software schreiben will.
Ähmmm, naja, geschenkter Gaul und so. Aber ich hab da schon einige
Abwärtskompatibilitätsprobleme bei denen entdeckt.
Tja, und das ist dann wieder so eine Sache, wo es schön ist, wenn man
es selbst macht. Ich hatte früher auch oft mit kaputten DICOM-Daten zu
tun, die das DCMTK dann auch nicht parsen kann. Aber die Situation hat
sich gebessert.
Ich glaub das eine war die Group Length (gggg,0000) wo das von Offis
schlappgemacht hat. Vielleicht haben sie´s aber mittlerweile behoben.
Das ezDICOM (http://www.cabiatl.com/mricro/ezdicom/activex/index.html)
ist mir da eigentlich am sympathischsten.


Gruß R.R.
--
Ich bin unschuldig, ich hab sie nicht gewählt!
Loading...