Fully automatic detection of the vertebrae in 2D CT images

FINALLY submitted the paper which we sent to the SPIE Medical Imaging Conference  (and got accepted!)

Abstract:

Knowledge about the vertebrae is a valuable source of information for several annotation tasks. In recent years, the research community spent a considerable effort for detecting, segmenting and analyzing the vertebrae and the spine in various image modalities like CT or MR. Most of these methods rely on prior knowledge like the location of the vertebrae or other initial information like the manual detection of the spine. Furthermore, the majority of these methods require a complete volume scan. With the existence of use cases where only a single slice is available, there arises a demand for methods allowing the detection of the vertebrae in 2D images. In this paper, we propose a fully automatic and parameterless algorithm for detecting the vertebrae in 2D CT images. Our algorithm starts with detecting candidate locations by taking the density of bone-like structures into account. Afterwards, the candidate locations are extended into candidate regions for which certain image features are extracted. The resulting feature vectors are compared to a sample set of previously annotated and processed images in order to determine the best candidate region. In a final step, the result region is readjusted until convergence to a locally optimal position. Our new method is validated on a real world data set of more than 9 329 images of 34 patients being annotated by a clinician in order to provide a realistic ground truth.

More Information and the paper as PDF can be found at my publication site.

Excel 2007: Diagrammflächen schraffieren

Schraffuren für Diagramme gibt es in Excel 2007 offenbar leider nicht mehr. Abhilfe schafft jedoch ein Add-In.

Am besten, das Add-In nach C:Dokumente und Einstellungen[Benutzername]AnwendungsdatenMicrosoftAddIns kopieren und dann der Installationsanleitung folgen:

  • Excel-Button drücken (der große runde button oben links)
  • letzte Zeile: Excel-Optionen
  • Add-Ins
  • fast ganz unten: “Gehe zu”
  • Durchsuchen
  • PatternFills.xlam anklicken und fertig

Anwendung

  • Diagramm anklicken
  • Diagrammtools > Format > ganz rechts gibt es jetzt eine “Patterns” Schaltfläche
blank

GoogleMail: Dateianhänge aus E-Mails löschen

Google ist der Meinung, dass es unnötig sei Anhänge/Attachments aus eMails zu löschen. Dummerweise bin ich anderer Meinung. Trotz mittlerweile mehr als 7.5 GB potentiellem Speicherplatz bei Google Mail, will ich nicht jeden Mist an den Mails kleben lassen.

Da ich per IMAP und Thunderbird auf meine Mails zugreife, kann ich die Anhänge wenigstens im Thunderbird löschen. Gesagt getan – nur wird der belegte Speicher dadurch nicht weniger sondern mehr. Das Problem ist, dass bei jedem Löschen eines Anhangs, eine Kopie der Nachricht (inklusive dem Anhang!) im Ordner “Alle Nachrichten” verbleibt und zusätzlich eine Mail ohne Anhang erstellt wird.

Die Lösung ist folgendermaßen:

  • Thunderbird per IMAP mit Google verbinden (Anleitung von Google)
  • Die unerwünschten Anhänge löschen – dabei werden unerwünschte Mailduplikate erstellt.
  • Das Thunderbird Addon Remove Duplicate Messages installieren und so konfigurieren:
  • Extras > Add-ons > “Remove Duplicate Messages” Einstellungen > Lösche bevorzugt “größere” E-Mail
  • Anhänge löschen nicht vergessen (z.B. den Ordner “Alle Nachrichten” nach Größe sortieren und dann die Mails durchsehen)
  • Rechts Klick auf den Ordner “Alle Nachrichten” > “Doppelte Nachrichten entfernen”
  • Dort noch schnell die Ausgabe kontrollieren, bestätigen und fertig.

Die gelöschten Duplikate sollten jetzt im Papierkorb sein, den man bei Bedarf noch löschen kann. Kurz darauf sollte man die Änderung auch in der GoogleMail Oberfläche sehen.

Epson Perfection 1240U mit Windows7 64bit und Windows 10

Epson stellt für den relativ alten Scanner “Epson Perfection 1240U” (aus dem Jahr 2001) keine 64bit Treiber für Windows 7 oder Windows 10 bereit.

Anstatt einen neuen Scanner zu kaufen scheint es mindestens 3 Lösungen zu geben:

Kauf zusätzlicher Software (bei Win 7)

  1. Die Empfehlung von Epson ist, die Software VueScan von Hamrick zuinstallieren. Vorteil: es geht! Nachteil: Die Software kostet ca. 30€
  2. In einem Windows 7-Forum wird ein modifizierter Treiber zum Download angeboten. Aber ehrlich gesagt habe ich Skrupel irgendwelche modifizierten Treiber aus nicht absolut vertrauenswürdigen Quellen zu installieren.
  3. Einen original Epson-Treiber eines anderen Scanners verwenden. Der Tip kommt übrigens aus dem selben Forum – da ich den Beitrag in einigen Monaten / Jahren nicht mehr wiederfinden werde, wenn ich es brauche: hier nochmal eine Beschreibung:

Epson Perfection 1240U mit Windows7 64bit:

  1. Scanner abstecken
  2. Epson Perfection 2400 Treiber für Windows 7 von Epson runterladen (EPSON Scan 3.0.4 vom 17. Juli 2009 / 20,68 MB)  Download
  3. Treiber installieren
  4. Scanner anstecken (findet keine Treiber)
  5. Start > Systemsteuerung > Gerätemanager: dort sollte jetzt ein neues Gerät mit gelbem Icon sein (der Scanner)
  6. Rechtsklick > Eigenschaften > Treiber > Treiber aktualisieren
  7. “Auf dem Computer nach Treibersoftware suchen”
  8. “Aus einer Liste von Gerätetreibern auf dem Computer Auswählen” > “Bildverarbeitungsgeräte”
  9. Hersteller: Epson, Modell: Epson Perfection 2400 auswählen und bestätigen

Mit IrvanView kann man nun scannen!

Zeitaufwand: minimal

Epson Perfection 1240U mit Windows10

Ich habe den Scanner mittlerweile entsorgt, aber er scheint auch unter Windows 10 noch seinen Dienst zu tun. Wie mir in einem Kommentar mitgeteilt wurde könnte es ungefähr wie folgt gehen:

  1. Start
  2. Einstellungen
  3. Geräte unter „Verwandte Einstellungen“ (rechts unten) „Geräte und Drucker“ auswählen.
  4. Den Scanner auswählen (Windows 10 schlägt erst mal nur vor das Gerät zu entfernen, da kein passender Treiber verfügbar ist.)
  5. Rechtsklick > Eigenschaften
  6. Hardware > Eigenschaften
  7. Einstellungen ändern > Treiber > Treiber aktualisieren.

TeXnicCenter: PDF vor Compilierung schließen

Sollte TeXnicCenter einen Fehler melden wie “Beim Öffnen dieses Dokuments ist ein Fehler aufgetreten”, liegt es evtl. daran, dass das PDF noch offen ist.

TeXnicCenter-Ausgabeprofile
TeXnicCenter-Ausgabeprofile

Zum automatischen Schließen des PDFs definiert man das “LaTeX => PDF”-Profil derart (siehe Screenshot rechts):

  1. Ausgabe > Ausgabeprofile definieren > Profil links wählen, rechts den Reiter  “Viewer”
  2. Projektausgabe betrachten: [x] DDE Komando, Kommando: [DocOpen(“%bm.pdf”)], Server: acroview, Thema: control
  3. Suche in Ausgabe: [x] DDE Komando, Kommando: [DocOpen(“%bm.pdf”)], Server: acroview, Thema: control
  4. Vor Compilierung Ausgabe schließen: [x] DDE Komando, Kommando: [DocClose(“%bm.pdf”)], Server: acroview, Thema: control

Alternativ kann man sich eine der folgenden Profile runterladen und importieren. Einmal mit und einmal ohne die Pfade zu Acrobat.

“Latex => PDF”-Profil ohne Pfad (sollte bei den meisten funktionieren)
“Latex => PDF”-Profil mit Pfad (wird nicht funktionieren, falls Acrobat nicht im exakt selben Verzeichnis wie bei mir installiert ist)

Links zum Thema:

PAROS download!

Das Ziel war nobel: Code aufräumen, schöner machen, refactoren und dokumentieren und dann online stellen.

Die Realität war derart, dass es leider wichtigeres zu tun gibt. Daher stelle ich das PAROS-Projekt, das dieses Jahr auf der SIGMOD war so online wie es ist: lauffähig, und vom Softwareengineeringaspekt ziemlich hässlich. Aber vielleicht kann ja jemand etwas damit anfangen – zumindest die kleinen hacks um größere Graphen auch annehmbar schnell zeichnen zu können.

Ausserdem ist es ein schönes Beispiel, wie man JXMapKit und OpenStreetMap (OSM) zu Forschungszwecken im Bereich Datamining, GIS (GeoInformationssysteme) und auch SpatialIndexing  verwenden kann. Auf der Konferenz kannten viele OSM nämlich erstaunlicherweise gar nicht, obwohl sie auf dem Bereich tätig waren.

Und zur nächsten Version muss ich nochmal nachsehen, ob es nach den Google Maps Terms of Services  immernoch verboten ist, Maps in Nicht-Browser-Anwendungen zu integrieren. Wäre natürlich auch sehr nett, oder weiß jemand Bescheid? (Update Jan. 2011: das ist nicht mehr verboten!)

Relevante Links:

JavaBeans via GUI konfigurieren

Was genau Java Beans isnd und wozu sie konzipiert sind, möchte ich an dieser Stelle nicht komplett und genau ausführen, dazu gibt es schon genügend Literatur (siehe Linkliste unten). Stattdessen möchte ich nur ganz grob das Konzept umreißen, darstellen wozu man Beans (unter anderem) benutzen kann und dann eine kleine Bean-Konfig-GUI zeigen, die mich mehr Zeit gekostet hat, als ich erst dachte …

Was sind Java Beans?

Eine Java Bean ist eine Klasse, die mindestens die folgenden Eigenschaften erfüllt:

  • öffentlicher Standardkonstruktor
  • öffentliche Zugriffsmethoden (also getter/setter für die relevanten Attribute)
  • Serialisierbarkeit (für das folgende Beispiel nicht wichtig)

Nicht viel also. Beispiele sind übrigens alle UI-Klassen von Swing, also zB JButton, JLabel, etc. Tonnenweise zugehörige Literatur kann man sich an einem ruhigen Winterabend gerne zu Gemüte führen

Wozu sind JavaBeans?

Beans kommen in vielen Java-Bereichen vor: GUIs, Servlets, Persitenz, etc. Java Beans bieten die Möglichkeit von außen per Introspection ausgelesen und bearbeitet zu werden, sie enthalten Attribute (Properties), die den Zustand beschreiben, sie können Events auslösen, sie bieten die Möglichkeit der Persistenz und sie können per Customization angepasst werden. Der letzte Punkt ist zugegebenermaßen sehr schwammig. Also kurz dazu zwei Beispiele:

Beispiel 1: GUI-Komponenten als Beans

Wer schon einmal mit einem Gui Editor gearbeitet hat, wie zum Bsp dem NetBeans Gui Builder, gearbeitet hat, hat schon Beans verwendet ohne es vielleicht zu merken. Klickt man zum Beispiel im GUI Builder auf einen JLabel  kann man sich die Eigenschaften des Labels ansehen und diese dort auch gleich konfigurieren. SO kann man bequem und einfach die Hintergrundfarbe, Schriftart, den Text und diverse andere Eigenschaften sofort und bequem ändern, ohne dafür programmieren zu müssen oder erst extra die API zu bemühen um nachzusehen, mit welcher Methode man die vertikale Ausrichtung ändern kann.

Da es natürlich etwas ineffizient wäre, für jede erdenkliche Komponente eine starre Konfig-Oberfläche zu bauen, ist es viel bequemer, per Introspection, die Komponente nach ihren Attributen zu fragen und die entsprechenden Elemente dynamisch erstellen zu lassen. Auf diese Art und weise kann man dann auch jede erdenkliche Bean konfigurieren – egal ob GUI Komponente von Sun oder selbst erstellt.

Beispiel 2: Konfigurierbare Algorithmen als Beans

ImageJ ist ein Java-Programm das einem per API sehr umfangreiche und vor allem schnelle Bildbearbeitung ermöglicht. Des weiteren lassen sich sehr leicht eigene PlugIns schreiben. Will man nun einen beliebigen Algorithmus schreiben, kann man diesen entweder parameterlos starten (z.B: “Bild horizontal spiegeln”) oder man benötigt noch eine Benutzereingabe (“Bild um X-Grad im Uhrzeigersinn drehen”). In ImageJ wurde dabei die Möglichkeit gewählt, einen generischen Dialog erzeugen und auslesen zu können. Alternativ hätte man auch hier JavaBeans einsetzen können um die Gui vollautomatisch erzeugen zu können, ohne dass sich der Programmierer darum kümmern muss.

Eine einfache Beans GUI

Ziel:

  • Eine einfache JavaBean mit einem Double und einem boolean-Wert und
  • ein einfacher Frame mit einem JTable, der aussieht wie die Komponente im NetBeans Gui Builder.

Problem:

  • Wie verknüpft man die ganzen Klassen aus dem java.beans-Package?
  • Wie bringe ich der GUI bei, die Änderungen an die Bean zu propagieren?

Lösung:

Noch nicht ideal aber ausbaufähig, besteht mein Beispiel aus 5 Dateien:

  1. eine BeanModel Klasse die ein DefaultTableModel erweitert
  2. eine BeanTable klasse die einen JTable erweitert
  3. MyTestBean – die eigentliche JavaBean
  4. MyTestBeanBeanInfo – Beanbeschreibungsklasse
  5. TestFrame, der kleine Frame der das ganze visualisiert

Das ganze gibt’s natürlich auch als ZIP zum Download / und als NetBeansProjekt.

Unschön finde ich derzeit, dass ich sowohl das Modell ALS AUCH den JTable erweitern musste. Aber – ehrlich gesagt hatte ich gestern Nacht um halb 12 auch keinen Nerv mehr, das noch schöner zu machen.

relevante Links:

System.gc() – gut gemeint, aber meist unnötig

Vor ein paar Tagen durfte ich mal wieder einen Blick in Fremdcode werfen, um zu sehen, wie die entsprechende Implementierung realisiert wurde. Eine an sich recht übersichtliche Methode, endete dann mit einem System.gc();. Die Intention ist schon klar: “Gib bitte all den Speicher frei, der jetzt noch durch herrenlose Objekte belegt wird.” Das ist zwar gut gemeint, aber im Regelfall erstens unnötig und zweitens oft sogar kontraproduktiv.

Zu den Fakten. Als erstes sollte an der Stelle ein Blick in die API von System.gc() folgen:

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

Das heißt die API impliziert hier schon, dass man sich nicht darauf verlassen kann und soll, dass nach dem Aufruf überhaupt irgendetwas passiert ist. (Die nächst schlimmere Lösung, die ich auch ab und zu gesehen habe, ist dann eine Schleife, in der der GC X-mal aufgerufen wird.)

Auf Stackoverflow findet sich eine interessante Diskussion, ob und warum der GC-Aufruf keine gute Idee ist – bzw WANN es eine gute Idee ist, den Aufruf wirklich zu machen. Ein kleines Fazit der ganzen Diskussion:

  • Es wird oft gesagt, dass es Bad-Practice ist, also lass es (naja okay, kein gutes Argument)
  • Die JVM kennt viele GCs, man weiß zur Ausführungszeit gar nicht, welcher GC aktiviert ist und wie er konfiguriert ist. Einfach mal auf der Java HotSpot VM Options nach “garbage collection” suchen.
  • Die sinnvollere Art den GC zu konfigurieren ist nicht ihn einfach aufzurufen sondern ihn zu konfigurieren.
  • Je nach Implementierung, kann ein Stop-The-World passieren. Also dass das gesamte Programm zur Garbage Collection steht.
  • Eventuell geschieht auch gar nichts: http://bugs.sun.com/view_bug.do?bug_id=6668279
  • Die Speicherverwaltung in der JVM ist nicht nur in Stack und Heap unterteilt. Der Heap ist unterteilt in Heap,Young,Tenured und Perm generation. Sun hat viel Zeit in die intelligente Garbage Collection gesteckt. Wenn man sich nicht mit Speicher Verwaltung und Garbage Collection beschäftigt, macht man es wahrscheinlich weniger intelligent als die Automatik.
  • Oracle/Sun schlägt im Tuning Guide “Tuning the Java Runtime System” explizit vor, den Aufruf auszuschalten.
  • .. und vermutlich noch einige weitere Argumente.

Wann es dann wirkliche eine gute Idee ist, den garbage collect selbst aufzurufen, ist dort auch zu lesen. Unter anderem, ist ein manueller GC sinnvoll wenn:

  • Wenn man ein Speicherleck finden will, kann es sinnvoll sein, zu bestimmten Checkpunkten die Garbage Collection zu forcieren (oder es zu versuchen)
  • Wenn man den Speicherverbrauch von Klassen bestimmen will (siehe Posting).
  • Nach einer umfangreichen und langen Initialisierungsphase ist die Tenured-Generation vermutlich voll mit Objekten, die man nicht mehr brauchen wird und die man gleich aufzuräumen will/muss, um zu verhindern, dass der erste spätere GCs lange braucht, da dort enorm viele Objekte herumlungern die schon lange nicht mehr gebraucht werden.
  • Nach einer kurzen Initialisierungsphase sind eventuell viele – später nicht mehr benötigte – Objekte im Speicher, die gar nicht erst in die Tenured Generation wandern sollen.

Interessante Links zum Thema:

Tuning the Java Runtime System