kostenloser Webspace werbefrei: lima-city


DICOM-Tag mittels Matlab auslesen

lima-cityForumHeim-PCSoftware

  1. Autor dieses Themas

    chst

    chst hat kostenlosen Webspace.

    Hallo liebe Leute,

    wir haben zuletzt mit einem Prof. in einer Vorlesung DICOMs (16-bit-Bildtag/format">format für zB Röntgenbilder) mit Hilfe von Matlab geöffnet und weiterverarbeitet. Dabei haben wir auf das image-Package verzichtet, weil das nicht zur Standard-Ausstattung von Matlab gehört.

    Der Vollständigkeit halber hätte ich nun gerne versucht die Tags im Header ausgelesen. Um beispielsweise das Erstellungsdatum einer Aufnahme herauszufinden, müsste ich nach dem Dicom-Tag "0008,0020" suchen und die nachfolgende Zeichenkette auslesen.

    Mein Ansatz wäre gewesen die Datei wie eine Textdatei zu öffnen und dann nach der entsprechenden Zeichenkette zu suchen:
    s=textread('abc.dcm','%c');
    fundstelle=strfind(s,'0008,0020');


    Leider wird diese Zeichenkette nicht in der Datei gefunden - laut einem "richtigen" Dicom-Reader und nach dem Öffnen mit Hilfe des Image-Package ist sie aber vorhanden.

    Zusätzlich würde ich eigentlich gerne darauf verzichten die gesamte Datei einzulesen, da diese mit teils mehreren 100MB viel zu viele uninteressante Daten enthalten.

    Habt ihr vielleicht einen guten Tipp für mich?

    Beste Grüße,
    Christoph
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Hallo Christoph,

    ich bin zwar kein DICOM-Experte, aber bevor Deine Frage hier unbeantwortet bleibt, ...

    1. Weil in DICOM-Dateien die Dicom-Tag-Kennungen nicht als String, sondern als Zahl gespeichert werden, konntest Du sie nicht mit der Stringsuche finden.

    Hier ein Hex-Dump-Ausschnitt einer DICOM-Datei, der offensichtlich Datum-Tags enthält.

    --> ~/Roentgenaufnahmen/DICOM/ST000001/SE000000$ xxd CT000000 | more
    ...
    0000200: 3300 0800 2000 4441 0800 3230 3136 3132  3... .DA..201612
    0000210: 3037 0800 2100 4441 0800 3230 3136 3132  07..!.DA..201612
    0000220: 3037 0800 2200 4441 0800 3230 3136 3132  07..".DA..201612
    ...


    2. Selbst wenn die Tag-Kennungen als Strings gespeichert würden, wäre es sehr unsicher, einfach nur nach dem String "0008,0020" zu suchen, und das was danach in der Datei steht, als Erstellungsdatum anzusehen.
    Weil, es könnte jemand als Kommentar (in einem entsprechenden Tag) zufällig "... 0008,0020 ..." geschrieben haben, und das Programm würde so nicht das gewünschte, sondern irgendetwas anderes aus der Datei lesen.

    Um ein Tag mit seinem Wert sicher aus der Datei zu lesen, muss man deren Datenformat kennen, und die Datei von Anfang an, verarbeiten.

    3. Die DICOM-Tags stehen (in meinen DICOM-Dateien) ziemlich am Anfang der Datei, so dass Du zum Auslesen der Tags NICHT die ganze Datei vollständig einzulesen bräuchtest.

    Ich kenne das DICOM-Datenformat übrigens nicht genauer, und habe meine Informationen nur durch einen Blick in mehrere DICOM-Dateien erhalten.

    Gruß Flmap
  4. Autor dieses Themas

    chst

    chst hat kostenlosen Webspace.

    Servus,

    zunächst vielen Dank für deine Rückmeldung und deine Unterstützung! Ich habe nun versucht die Daten herauszufiltern und festgestellt, dass jede Datei einmal mit 128 Byte Leerzeichen beginnt. Diese Bytes kann ich wie folgt überspringen:
    fp=fopen('abc.dcm');
    fseek(fp,128,'bof')


    Nun wäre mein Gedanke gewesen die nachfolgenden Daten zeilenweise auszulesen:
    A=fgetl(fp)


    Nun erhalte ich leider nicht wie erwartet Hexadezimale Zahlen, die ich umwandeln könnte, sondern einen String mit den Startbuchstaben "DICM....", also zum Beispiel DICM☻ UL♦ ã ☻ ☺ OB ☻ ☺☻ ☻ UI→ .2.840.10008.5.1.4.1.1.1 ☻ ♥ UI8 1.2.392.200036.9125.9.0.253116364.3389063205.1687023245 ☻ ► UI¶ 1.2.840.10008.1.2.1 ☻ ↕ UI" 1.2.826.0.1.3680043.2.360.0.3.5.4 ☻ ‼ S IIS_354 UL♦ ¬☺ ♣ CS8

    Vielleicht sehe ich ja den Wald vor lauter Bäumen nicht mehr, aber was mache ich falsch? Auch im Internet habe ich leider keine hilfreichen Anregungen gefunden :/

    Beste Grüße,
    Christoph
  5. burgi

    Co-Admin Kostenloser Webspace von burgi

    burgi hat kostenlosen Webspace.

    Es verwundert mich nicht wirklich. In der Doku steht ja auch, dass fgetl für das zeilenweise Lesen von ASCII-Dateien verwendet wird.
    Byteweise liest man aus einer Datei mittels fread
    Ich kenne Matlab nicht, aber ich kenne andere Programmiersprachen, und bin es gewohnt, Handbücher zu durchsuchen und zu lesen :thumb:
  6. Hallo Christoph,

    die DICOM-Dateien die ich habe, fangen nicht mit 128 Leerzeichen, sondern mit 128 Bytes mit dem Wert 0x00 (Hex) an.

    Auch wenn die ersten 128 Byte (scheinbar) immer 0x00 enthalten, würde ich diese nicht so einfach überspringen. Was ist, wenn dort doch mal etwas drin steht, was evl. sogar interessant sein könnte ?

    Ich würde diese ersten 128 Byte (z.B. mit fread, für binäre Daten) einlesen, prüfen ob diese Bytes alle den Wert 0x00 haben, und wenn nicht, dann das Programm mit einer Fehlermeldung abbrechen. Dann kann man die Daten von Hand analysiert und das Programm verbessern.

    Binäre Dateien zu lesen und zu dekodieren ist nicht einfach.

    Nur mal ein kleiner Blick in meine obrigen Beispiel-Daten (meine Dekodierung ist nur eine Vermutung, ich kenne das Datenformat nicht wirklich):

    0800 2000          : Tag 0x0800 und Subtag 0x2000
    4441               : Datentyp 'Datum im YYYYMMDD-Format'
    0800               : Länge in Bytes (im Little Endian-Format gespeichert) was für 8 Byte stehen sollte
    3230 3136 3132 3037: Das sind die 8 Byte, die das Datum enthalten

    ... danach kommt sofort der nächste Tag, SubTag, Datentyp, Länge, Inhalt.

    Ohne die Dokumentation des Dateiformates, ist man beim Dekodieren von binären Daten auf viel Raten angewiesen, was entsprechend zu Fehlinterpretationen führen kann.

    Gruß Flmap
  7. burgi

    Co-Admin Kostenloser Webspace von burgi

    burgi hat kostenlosen Webspace.

    flmap schrieb:
    Ohne die Dokumentation des Dateiformates, ist man beim Dekodieren von binären Daten auf viel Raten angewiesen, was entsprechend zu Fehlinterpretationen führen kann.

    Das Schöne ist ja, es gibt eine ausführliche Dokumentation. DICOM ist ein standardisiertes Dateiformat:
    http://dicom.nema.org/standard.html
    Im Speziellen ist hier der Header genauer erklärt:
    http://www.cabiatl.com/mricro/dicom/index.html
    Dort steht beispielsweise nachzulesen:

    first 128 bytes: unused by DICOM format, followed by the characters 'D', 'I', 'C', 'M'

    Danach kommen weitere Daten, die auf der im Link geposteten Seite erklärt sind.
    Die UID 1.2.840.10008.1.2.1 würde demnach bedeuten, dass die Daten im Little Endian-Modus gespeichert sind. Der Standard lässt aber auch Big Endian zu.
    Wenn der Threadersteller will, kann er also mit ein wenig Sucherei und Lesen das Dateiformat recht problemlos aufdröseln, lesen und verstehen :prost:

    Beitrag zuletzt geändert: 27.1.2017 17:56:14 von burgi
  8. Autor dieses Themas

    chst

    chst hat kostenlosen Webspace.

    Hallo!

    Zunächst vielen Dank für eure konstruktive Unterstützung! Die Dokumentation zum Dicom-Format ist wohl ganz gut, ein tieferes Verständnis ist aber wohl eher ein Lebenswerk. Ich habe also einerseits noch Auszüge aus der Dokumentation, und andererseits Informationen zu den verschiedenen Funktionen in Matlab gelesen und bin zu einer Lösung gekommen.

    Sollte noch jemand auf der Suche danach sein: Die Tags werden im HEX-Format angegeben. Man darf aber nicht nach dem angegebenen Tag abcd,efgh suchen, sondern muss die Reihenfolge umkehren zu cd ab gh ef. Danach kommen dann noch zusätzliche Angaben wie die Anzahl der auszulesenden Bytes und die Daten selbst. Achtung, auch hier kann (zB bei Zahlen) die Reihenfolge verdreht sein.

    Es ist also geschafft - vielen Dank für eure Hilfe!

    Liebe Grüße,
    Christoph
  9. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!