Praktikum Medizinische Bildverarbeitung in C# ... - Bernd Radig
Praktikum Medizinische Bildverarbeitung in C# ... - Bernd Radig
Praktikum Medizinische Bildverarbeitung in C# ... - Bernd Radig
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Praktikum</strong> <strong>Mediz<strong>in</strong>ische</strong> <strong>Bildverarbeitung</strong> <strong>in</strong> <strong>C#</strong>:<br />
„Volume-Render<strong>in</strong>g“<br />
Technische Universität München / Lehrstuhl Informatik IX SS 2005<br />
Dr. Michael Roth Prof. Dr. <strong>Bernd</strong> <strong>Radig</strong><br />
Aufgabe 1<br />
Blatt 1<br />
Erstellen Sie e<strong>in</strong> erstes kle<strong>in</strong>es <strong>C#</strong>-Programm, welches den Text „Hello World!“ auf<br />
e<strong>in</strong>er Konsole ausgibt. Folgen Sie dabei Schritt für Schritt den folgenden<br />
Anweisungen:<br />
1. Erzeugen Sie <strong>in</strong>nerhalb der SharpDevelop-Umgebung e<strong>in</strong>e neues Projekt vom<br />
Typ „Leere <strong>C#</strong> Konsolenanwendung“ mit dem Name VolumeRender<strong>in</strong>g.<br />
2. Fügen Sie dem Projekt e<strong>in</strong>e Datei "VolumeRender<strong>in</strong>g.cs" h<strong>in</strong>zu.<br />
3. Teilen Sie dem Compiler mit, dass Sie den Namensraum (engl. namespace)<br />
"System" verwenden möchten. Die Syntax hierfür ist us<strong>in</strong>g ; 1<br />
4. Def<strong>in</strong>ieren Sie <strong>in</strong>nerhalb der Datei die Klasse VolumeRender<strong>in</strong>g.<br />
5. Def<strong>in</strong>ieren Sie <strong>in</strong>nerhalb dieser Klasse e<strong>in</strong>e Methode mit der folgenden<br />
Signatur:<br />
static public void Ma<strong>in</strong>() { }<br />
6. Die Ausgabe auf der Konsole geschieht durch die Methode<br />
Console.WriteL<strong>in</strong>e( );<br />
7. Kompilieren sie das Programm und führen Sie es aus.<br />
Was s<strong>in</strong>d Namensräume?<br />
<strong>C#</strong> ist e<strong>in</strong> Nachfolger zu Java und C++ und hat deshalb auch weitestgehend ähnliche Konstrukte zu<br />
diesen Programmiersprachen. Das "Hello-World"-Programm dieser Aufgabe sieht se<strong>in</strong>em Java-Pedant<br />
sehr ähnlich. <strong>C#</strong> nennt se<strong>in</strong>e Packages jedoch Namensräume/Namespaces und lässt se<strong>in</strong>e C++-Wurzeln<br />
durchschimmern, <strong>in</strong>dem es das Schlüsselwort us<strong>in</strong>g statt import (wie <strong>in</strong> Java) verwendet.<br />
Namesräume enthalten e<strong>in</strong>e Menge von vordef<strong>in</strong>ierten Klassen oder auch geschachtelt weitere<br />
Namensräume. Der Namensraum System enthält z.B. die Klasse Console. Durch die Angabe von<br />
us<strong>in</strong>g System; können wir bequem Console.WriteL<strong>in</strong>e() statt dem vollqualifizierten Namen<br />
System.Console.WriteL<strong>in</strong>e() schreiben.<br />
Wieviele Klassen können <strong>in</strong> e<strong>in</strong>er Datei stehen?<br />
Anders als Java erlaubt <strong>C#</strong> auch mehrere (nicht geschachtelte) Klassen pro Datei und folglich muss auch<br />
der Klassenname nicht mit dem Date<strong>in</strong>amen übere<strong>in</strong>stimmen. Im Laufe dieses <strong>Praktikum</strong>s wird allerd<strong>in</strong>gs<br />
die Konvention und schöne Sitte "E<strong>in</strong>e Klasse pro Datei" und "Date<strong>in</strong>ame gleich .cs"<br />
e<strong>in</strong>gehalten.<br />
1 Die spitzen Klammern kennzeichnen hier und im weiteren Verlauf des <strong>Praktikum</strong>s e<strong>in</strong>en variablen<br />
Teil <strong>in</strong>nerhalb e<strong>in</strong>es Syntaxbeispiels. Man muss also us<strong>in</strong>g System ; und nicht us<strong>in</strong>g ;<br />
schreiben.<br />
Seite 1 von 6
Aufgabe 2<br />
In dieser Aufgabe soll nun Ihr Programm aus Aufgabe 1 auf folgende Weise erweitert<br />
werden:<br />
• Öffnen Sie e<strong>in</strong> Fenster der Größe 640 x 480 Pixel (Bildpunkte)<br />
• Der Titel des Fensters soll "VolumeRender<strong>in</strong>g <strong>Praktikum</strong>" lauten.<br />
Wie öffnet man e<strong>in</strong> Fenster?<br />
Die e<strong>in</strong>fachste Art e<strong>in</strong> Fenster zu öffnen, ist die Klasse VolumeRender<strong>in</strong>g von der Klasse Form aus<br />
dem Namensraum System.W<strong>in</strong>dows.Forms abzuleiten. E<strong>in</strong> Form-Objekt stellt e<strong>in</strong> vollständiges<br />
Fenster mit Titelleiste auf der Arbeitsfläche dar.<br />
Die <strong>C#</strong>-Syntax für das Ableiten e<strong>in</strong>er Klasse lehnt sich an C++ an und lautet:<br />
class : <br />
{<br />
}<br />
Im Konstruktor von VolumeRender<strong>in</strong>g können Fenstereigenschaften wie die Größe oder die Position<br />
verändert werden. Die Syntax für e<strong>in</strong>en Konstruktor ist analog zu Java/C++. Nach der Abarbeitung des<br />
Konstruktors von VolumeRender<strong>in</strong>g ist der Form für den Benutzer sichtbar und betriebsbereit.<br />
Wie kann man Eigenschaften wie Größe oder Titel e<strong>in</strong>es Fensters ändern?<br />
Klassen können <strong>in</strong> <strong>C#</strong> so genannte Properties (dt. Eigenschaften) enthalten, von denen wir im Laufe<br />
des <strong>Praktikum</strong>s noch sehr viel mehr hören werden. Die wichtigsten Properties der Klasse Form für<br />
diese Aufgabe lauten ClientSize für die Fenstergröße und Text für den Titel des Fensters.<br />
Properties mit Schreibzugriff können verändert werden, <strong>in</strong> dem e<strong>in</strong>fach e<strong>in</strong> neuer Wert zugewiesen<br />
wird, z.B:<br />
ClientSize = new Size( 640 , 480 );<br />
Dabei ist zu beachten, dass sich Size <strong>in</strong> dem Namesraum System.Draw<strong>in</strong>g bef<strong>in</strong>det.<br />
Tipp: Wenn Sie an e<strong>in</strong>em Rechner mit W<strong>in</strong>dows 2000 oder XP als Betriebsystem sitzen, sollten Sie<br />
unbed<strong>in</strong>gt auch die Property Opacity der Klasse Form mal auf 0.5 setzen.<br />
Wie und wann erzeuge ich me<strong>in</strong> Fenster/Form-Objekt?<br />
Um Ihr Fenster zu erzeugen, müssen Sie <strong>in</strong> der Ma<strong>in</strong>-Methode e<strong>in</strong> Objekt der Klasse<br />
VolumeRender<strong>in</strong>g erstellen und den Programmablauf mit dem Fenster verb<strong>in</strong>den. Dies geschieht<br />
durch:<br />
Application.Run( new VolumeRender<strong>in</strong>g() );<br />
Seite 2 von 6
Aufgabe 3<br />
Innerhalb des Fensters soll nun e<strong>in</strong>e e<strong>in</strong>fache L<strong>in</strong>iengrafik dargestellt werden, <strong>in</strong> der<br />
jeder 40. Bildpunkt am oberen Rand des Fensters mit jedem 40. Bildpunkt des unteren<br />
Bildrandes durch e<strong>in</strong>e rote L<strong>in</strong>e verbunden ist.<br />
Was braucht man für das Zeichnen der L<strong>in</strong>ien?<br />
Für das Zeichnen der L<strong>in</strong>iengrafik verwenden wir die Methoden und Klassen aus dem Namensraum<br />
System.Draw<strong>in</strong>g. Genauer gesagt benötigen wir die Klassen Color, Pen und Graphics. Letztere ist e<strong>in</strong>e<br />
Klasse <strong>in</strong> der die Methoden zum Zeichnen von L<strong>in</strong>ien vorhanden s<strong>in</strong>d. Wie das genau geht, können Sie<br />
<strong>in</strong> der .NET-Framework-SDK-Dokumentation nachschlagen, die alle vordef<strong>in</strong>ierten Namensräume und<br />
Klassen beschreibt.<br />
Wann soll man die Grafik zeichnen?<br />
Das Zeichnen sollte genau dann erfolgen, wenn das Betriebsystem mitteilt, dass der Fenster<strong>in</strong>halt auf<br />
dem Bildschirm sichtbar wird (z.B. auch nach Verdeckung durch e<strong>in</strong> anderes Fenster).<br />
In diesem Fall wird die Methode OnPa<strong>in</strong>t( Pa<strong>in</strong>tEventArgs e ) der Klasse Form aufgerufen, die wir<br />
<strong>in</strong> VolumeRender<strong>in</strong>g nur überschreiben müssen, um unseren eigenen Fenster<strong>in</strong>halt zu zeichnen.<br />
Das Überschreiben geschieht e<strong>in</strong>fach durch die Def<strong>in</strong>ition der folgenden Methode <strong>in</strong> der von Form<br />
abgeleiteten Klasse VolumeRender<strong>in</strong>g:<br />
protected override void OnPa<strong>in</strong>t( Pa<strong>in</strong>tEventArgs e )<br />
{ }<br />
Durch die Property e.Graphics kommen Sie übrigens an das Graphics-Objekt ran, das Sie für das<br />
Zeichnen der L<strong>in</strong>ien benötigen.<br />
Für diese Aufgabe braucht man doch zwei geschachtelte for-Schleifen, oder?<br />
Richtig! Und deren Syntax ist wie <strong>in</strong> C++ oder Java:<br />
for( ; ; )<br />
{ }<br />
wobei auch die Deklaration e<strong>in</strong>er Variable be<strong>in</strong>halten kann, z.B:<br />
for( <strong>in</strong>t i = 0 ; i < 100 ; i++ ) { ... }<br />
Aufgabe 4<br />
Das eigenartige Schlüsselwort override <strong>in</strong> der letzten Aufgabe wird <strong>in</strong> <strong>C#</strong> benutzt,<br />
wenn man e<strong>in</strong>e Methode aus der Basisklasse überschreiben möchte. Experimentieren<br />
Sie etwas mit dem Programm, um die Antwort auf die folgenden Fragen<br />
herauszuf<strong>in</strong>den:<br />
• Was passiert, wenn man override weglässt oder vergisst?<br />
• Was passiert, wenn man sich verschreibt und z.B. e<strong>in</strong>e Methode OnPa<strong>in</strong>(...)<br />
statt OnPa<strong>in</strong>t(...) def<strong>in</strong>iert?<br />
• Ist das beobachtete Verhalten s<strong>in</strong>nvoll? Begründen Sie Ihre Antwort!<br />
Br<strong>in</strong>gen Sie das Programm im Anschluss wieder <strong>in</strong> e<strong>in</strong>en lauffähigen Zustand!<br />
Seite 3 von 6
Aufgabe 5<br />
Starten Sie das Programm aus Aufgabe 3 und verändern Sie mit der Maus die Größe<br />
des Fensters. Welche Mängel fallen Ihnen bei der L<strong>in</strong>iengrafik auf?<br />
Achten Sie dabei auf die folgenden Programmeigenschaften:<br />
• Wird die L<strong>in</strong>iengrafik an die Fenstergröße angepasst?<br />
• Wird die L<strong>in</strong>iengrafik immer korrekt dargestellt?<br />
• Wie steht es mit der Geschw<strong>in</strong>digkeit bei größeren Fenstern?<br />
Beheben Sie die gefundenen Mängel.<br />
Wie kriegt man e<strong>in</strong>en Form dazu, dass bei e<strong>in</strong>er Größenänderung der gesamte<br />
Fenster<strong>in</strong>halt neu gezeichnet wird?<br />
Für diese Aufgabe müssen Sie das Form-Objekt geeignet konfigurieren, die Methode SetStyle() der<br />
Klasse Control hilft Ihnen dabei.<br />
Control ist e<strong>in</strong>e Klasse, von der Form abgeleitet ist, so dass Sie diese Methode <strong>in</strong>nerhalb Ihrer<br />
VolumeRender<strong>in</strong>g-Klasse verwenden können.<br />
Das Setzen e<strong>in</strong>es Styles geschieht z.B. durch:<br />
SetStyle( ControlStyles., true );<br />
Suchen Sie <strong>in</strong> der Dokumentation zu ControlStyles nach geeigneten Flags.<br />
Tipp: Die Zeichengeschw<strong>in</strong>digkeit kann neben dem Neukauf e<strong>in</strong>es Rechners auch durch das<br />
E<strong>in</strong>schalten des DoubleBuffer<strong>in</strong>g erheblich gesteigert werden.<br />
Aufgabe 6<br />
Die Methoden der Klasse Graphics eignen sich auch zur Darstellung von Bildern,<br />
z.B. im BMP oder JPEG Format. Erweitern Sie dafür Ihr Programm um e<strong>in</strong> Objekt<br />
vom Typ Bitmap, das Sie im Konstruktor der Klasse VolumeRender<strong>in</strong>g aus e<strong>in</strong>er<br />
Datei erzeugen und <strong>in</strong> OnPa<strong>in</strong>t() mit e<strong>in</strong>er entsprechenden Methode der Klasse<br />
Graphics darstellen.<br />
Auf den WWW-Seiten des <strong>Praktikum</strong>s<br />
http://wwwradig.<strong>in</strong>.tum.de/praktika/praktCSharpMedBV.SS05<br />
f<strong>in</strong>den Sie e<strong>in</strong> Testbild, welches Sie für diese Aufgabe verwenden können.<br />
Seite 4 von 6
Optionale Aufgabe 1<br />
Für die Versionskontrolle steht Ihnen e<strong>in</strong>e Quellcode-Datenbank auf der Basis von<br />
Subversion (http://subversion.tigris.org/) zur Verfügung. E<strong>in</strong>e Versionskontrolle dient<br />
zur Speicherung des momentanen Zustands Ihres Programms und zur Protokollierung<br />
der durchgeführten Veränderungen am Code, <strong>in</strong>sbesondere wenn mehr als e<strong>in</strong><br />
Programmierer daran arbeitet.<br />
Sie können diese Datenbank dazu verwenden um den Quellcode auch zu Hause zu<br />
bearbeiten und den Programmcode konsistent mit der Version am Lehrstuhl und die<br />
Ihres <strong>Praktikum</strong>partners zu halten.<br />
Vielleicht kennen Sie das Konzept der Versionskontrolle bereits von dem recht<br />
bekannten und verbreiteten CVS, zu dem Subversion e<strong>in</strong>en Nachfolger darstellt.<br />
Zum Datenaustausch mit der Datenbank benötigen Sie e<strong>in</strong>en Client. Wir empfehlen<br />
hierfür TortoiseSVN, das auf den <strong>Praktikum</strong>srechnern vor<strong>in</strong>stalliert ist.<br />
Der TortoiseSVN-Client bietet Ihnen folgende Möglichkeiten über das W<strong>in</strong>dows-<br />
Kontextmenü für Dateien und Verzeichnisse an, dass bei Klicken mit der rechten<br />
Maustaste ersche<strong>in</strong>t:<br />
• Import/Importieren...: Initiales Übertragen Ihres Programmcode-Verzeichnis<br />
<strong>in</strong> die Datenbank<br />
• Checkout/Auschecken: Erstellen e<strong>in</strong>er Arbeitsversion des Inhaltes der<br />
Datenbank auf Ihrem Rechner<br />
• Commit/Übertragen: Übertragen von Veränderungen an e<strong>in</strong>er ausgecheckten<br />
Arbeitsversion <strong>in</strong> die Datenbank<br />
• Update/Aktualisieren: Übertragen der aktuellen Version der Datenbank <strong>in</strong> Ihr<br />
ausgechecktes Programmverzeichnis, d.h. Veränderungen anderer<br />
Programmierer werden <strong>in</strong> Ihre Arbeitsversion e<strong>in</strong>gearbeitet<br />
• Add/H<strong>in</strong>zufügen: neue Dateien zu e<strong>in</strong>er ausgecheckten Version h<strong>in</strong>zufügen,<br />
die Veränderungen werden erst nach e<strong>in</strong>em Commit <strong>in</strong> die Datenbank<br />
übertragen<br />
• Delete/Löschen: Dateien von e<strong>in</strong>er ausgecheckten Version entfernen, die<br />
Veränderungen werden erst nach e<strong>in</strong>em Commit <strong>in</strong> die Datenbank übertragen<br />
• Zeige Log: Anzeige der Historie der Datenbank<br />
Nachfolgende Abbildung verdeutlicht den Datenfluss für die e<strong>in</strong>zelnen Aktionen.<br />
Benutzer mit<br />
Arbeitsversion<br />
Auschecken<br />
Übertragen<br />
Subversion-<br />
Datenbank<br />
Aktualisieren<br />
Seite 5 von 6
Für den Zugang zu der Datenbank benötigen Sie die Angaben, die auf dem Passwort-<br />
Handout aufgelistet s<strong>in</strong>d. Sie müssen sich bei e<strong>in</strong>em Zugriff auf die Datenbank bei<br />
dieser anmelden. Dies geschieht mit dem Log<strong>in</strong> und Passwort für Ihre Gruppe.<br />
Zum Importieren Ihres Projekts gehen Sie folgendermaßen vor:<br />
1. Wählen Sie mit der rechten Maustaste im Kontextmenü für Ihr<br />
Projektverzeichnis „TortoiseSVN/Importieren...“<br />
2. Geben Sie im darauf ersche<strong>in</strong>enden Dialog die URL Ihrer Programm-<br />
Datenbank an und klicken Sie „Ok“.<br />
3. Wenn Sie im Internet-Explorer nun die URL Ihrer Programm-Datenbank<br />
e<strong>in</strong>geben, sollten Sie nun e<strong>in</strong>e navigierbare Darstellung Ihres Quellcodes<br />
sehen.<br />
Achtung: bitte beachten Sie, dass Sie nicht auf der importierten Version<br />
weiterarbeiten (benennen Sie am Besten das Verzeichnis Ihres Projekts um!), sondern<br />
stattdessen nur e<strong>in</strong>e dafür vorgesehen Arbeitsversion verwenden. Um diese aus Ihrer<br />
Datenbank zu holen, gehen Sie folgendermaßen vor:<br />
4. Wechseln Sie mit dem W<strong>in</strong>dows-Explorer <strong>in</strong> e<strong>in</strong> Verzeichnis, das für Ihre<br />
Arbeitsversion vorgesehenen ist.<br />
5. Wählen Sie im W<strong>in</strong>dows-Kontextmenü „TortoiseSVN/Auschecken...“<br />
6. Im darauf folgenden Dialog müssen Sie wieder die URL ihrer Datenbank<br />
angeben und auf „Ok“-klicken.<br />
Durch die Schritte 4-6 können Sie auch zuhause beliebig viele Arbeitsversionen<br />
anlegen.<br />
Seite 6 von 6