8
$\begingroup$

When I try to import DICOM files from Siemens MR, I can successfully import the MetaInformation, but importing the image itself fails.

I have posted a small example dicom file: DICOM example

In version 10.4 (Windows) or 11.2 (MacOS) I get the following:

Import["example.dcm"]
(*Output:
Import::fmterr: "Cannot import data as DICOM format."
Import::fmterr: "Cannot import data as DICOM format."
Import::nodta: "Insufficient data found for DICOM format."
*)

Importing MetaInformation kind of works:

meta=Import["example.dcm", "MetaInformation"];
(*Output:
Import::fmterr: "Cannot import data as DICOM format."
Import::fmterr: "Cannot import data as DICOM format."
*)

But a lot of tag names are not resolved, which are listed in the DICOM standard.

I've contacted Wolfram support more than a year ago, but didn't get a helpful resonse except

you may be able to use BinaryReadList

Has anyone else come across this issue?

$\endgroup$
  • $\begingroup$ I don't know what that means but ref/format/dicom says "fully support DICOM files conforming to Section PS 3.10 of the DICOM standard." so if your images use this standard I can add a bug tag. $\endgroup$ – Kuba Mar 21 '18 at 11:55
  • $\begingroup$ Section PS 3.10 is only one part of the standard. Data sets are described in section PS 3.5. The example DICOM file follows this standard. $\endgroup$ – AxelF Mar 21 '18 at 12:27
9
$\begingroup$

After a bit of digging into the internals of Import I figured that some value representations were not handled correctly, as required by the DICOM standard. I would call this a bug, but don't have the reputation to set the flag. If I load the package for importing DICOM files manually

(*Pre-load the DICOM import package to be able to overwrite it. *)
Get[FileNameJoin[{$InstallationDirectory, "SystemFiles", "Kernel", "SystemResources", $SystemID, "Convert", "Dicom.mx"}]]

I can overwrite the function ReadData to fix the problem:

(* Overwrite ReadData to fix the Switch Statement *)
System`Convert`DicomDump`ReadData[
  System`Convert`DicomDump`s_,
  System`Convert`DicomDump`info_,
  System`Convert`DicomDump`ExplicitVR,
  System`Convert`DicomDump`rules_
  ] := Module[
  {
   System`Convert`DicomDump`len,
   System`Convert`DicomDump`VR
   },

  System`Convert`DicomDump`VR = 
   BinaryReadList[System`Convert`DicomDump`s, "Character8", 2];
  If[
   MemberQ[System`Convert`DicomDump`VR, EndOfFile]
   ,
   Return[EndOfFile]
   ];
  System`Convert`DicomDump`VR = 
   StringJoin[System`Convert`DicomDump`VR];

  System`Convert`DicomDump`len = Switch[
    System`Convert`DicomDump`VR,
    (*Alternatives["OB","OW","SQ","UN","UT"],*)
    Alternatives["OB", "OD", "OF", "OL", "OW", "SQ", "UC", "UN", "UR",
      "UT"],
        Last[
     BinaryRead[
      System`Convert`DicomDump`s, {"Character8", "Character8", 
       "UnsignedInteger32"}]],
    Alternatives["AE",
                "AS", "AT", "CS", "DA", "DS", "DT", "FL", "FD", "IS", "LO", 
     "LT", "PN",
                "SH", "SL", "SS", "ST", "TM", "UI", "UL", "US"(*, "UT"*)
            ],
        BinaryRead[System`Convert`DicomDump`s, "UnsignedInteger16"],
    _,
        System`Convert`DicomDump`VR = "UN";
        BinaryRead[System`Convert`DicomDump`s, "UnsignedInteger16"]
    ];
  If[
   System`Convert`DicomDump`len === EndOfFile
   ,
   Return[EndOfFile]
   ];

  System`Convert`DicomDump`read[
   System`Convert`DicomDump`s,
   System`Convert`DicomDump`info,
   System`Convert`DicomDump`VR,
   System`Convert`DicomDump`len,
   System`Convert`DicomDump`rules
   ]
  ]

Note that I've left the incomplete set of alternatives as a comment.

With this modification, I can import the DICOM file correctly.

The unresolved tag names can be resolved with an additional set of replacement rules, which I've posted here:

tagnames.m

I couldn't figure out how to inject this into the import package, so I've simply added it as an additional replacement:

meta = Import["example.dcm", "MetaInformation"];
(* Remove one long private meta information to make things nicer *)
metaShort =  meta /. tagNames /. ("(0021,1019)" -> l_List) :> ("(0021,1019)" -> Short[l]);
metaShort //. l : {_Rule ..} :> Grid[l //. (a_ -> b_) :> {a, b}
   , Alignment -> {Left, Top}
   , Frame -> True
   , Background -> {None, {{GrayLevel[0.9], GrayLevel[0.95]}}}
   ]

The result is a readable version of the meta information, only the private tag names are unresolved, as expected.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.