I recently discovered beautiful things that can be achieved with AnatomyPlot3D. How can I apply this function to DICOM images from my local machine? Thanks in anticipation of your suggestions.
1 Answer
You use AnatomyPlot3D
to plot anatomy entities, but it also works with other mesh primitives. DICOM images are slices so you could visualize them as an Image3D
, but not using AnatomyPlot3D
because you don't have a mesh.
For example, I used this dental sample DICOM of a class III malocclusion "underbite". First I unpacked the archive then I imported into Mathematica after sorting the file list properly:
dcmfiles = FileNames["Class-3-malocclusion\\Class 3 malocclusion\\DICOM\\I*"];
sortedfiles =
SortBy[dcmfiles,
ToExpression@
First@StringCases[Last@FileNameSplit@#, DigitCharacter ..] &];
slices = Import /@ sortedfiles;
i3d = Image3D[slices, ColorFunction -> "XRay"]
To get it into a form appropriate for AnatomyPlot3D
we need to convert it into a mesh. You could use this tool: https://github.com/AOT-AG/DicomToMesh . Note you have to build it yourself on Windows. There's also Slicer. I had no luck with dicom2mesh so I tried Slicer but it was far too complicated for me as a first time user. Maybe you will have more success.
However, you can get a crude mesh out of Mathematica, and you can then feed this into AnatomyPlot3D
(beware this process is hideously slow):
mesh = ImageMesh[ImageResize[Threshold[i3d, 0.5], 200],
Method -> "DualMarchingCubes"]
-
$\begingroup$ many thanks for your excellent answer. Unfortunately, my Image3D did not give me something similar to what you got. ImageMesh threw some errors as well but displayed many slices that confirm the data is actually dental sample. I suspect that the problem is probably from me not fully understanding your second to the last sentence. I have not used Slicer in about a year and I am hoping I could just do meshing from the slices in Mathematica straight up. Also, I like to know where you are calling "i3d" from. $\endgroup$– DeanAug 14, 2020 at 17:24
-
$\begingroup$ The errors: Threshold::wlist: Argument i3d should be one of rectangular array of any depth, image, sound, or sampled sound list. ImageResize::imginv: Expecting an image or graphics instead of Threshold[i3d,0.5]. ImageMesh::imginv: Expecting an image or graphics instead of ImageResize[Threshold[i3d,0.5],200]. $\endgroup$– DeanAug 14, 2020 at 17:25
-
1$\begingroup$ i3d is the Image3D result - I updated the answer:
i3d = Image3D[slices, ColorFunction -> "XRay"]
$\endgroup$– flintyAug 14, 2020 at 17:28 -
1$\begingroup$ I will only add that one could use
Raster3D[]
if one wishes to display 3D images alongside other 3D primitives. $\endgroup$ Aug 14, 2020 at 22:56 -
$\begingroup$ @flinty, many thanks. I am still working through the steps. $\endgroup$– DeanAug 16, 2020 at 21:09