Loading dicom directory into scene and obtaining master volume node

Heya once again~

I am trying to get three things working.

  1. Load a dicom directory and have it render in the scene. Right now I have it working with a specific patient id, but I wanted to know if there is a better way of doing this. Ideally, in a manner which loads it without needing to input a patient id.
  2. Obtain the master volume node of this dicom directory, so that it segments and displays the segmentation in the scene.
  3. Be able to set the color of the segmentation to one of the preset colors. I have it set to bone, but it still appears as green.

Any and all resources and advice would be much appreciated~

dicom2

1 and 2) Here’s what I do (when I know the seriesInstanceUID)

    seriesNodeIDs = DICOMUtils.loadSeriesByUID([seriesInstanceUID,])
    seriesVolumeNode = slicer.util.getNode(seriesNodeIDs[0])
    storageNode = seriesVolumeNode.CreateDefaultStorageNode()
    slicer.mrmlScene.AddNode(storageNode)
    seriesVolumeNode.SetAndObserveStorageNodeID(storageNode.GetID())
    storageNode.SetFileName(slicer.dicomDatabase.fileForInstance(sopInstanceUID))
  1. This uses the series volume as master
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
# To show segment editor widget (useful for debugging): segmentEditorWidget.show()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)

segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
slicer.mrmlScene.AddNode(segmentEditorNode)
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setMasterVolumeNode(seriesVolumeNode)
  1. this add a segment with a custom color
lesionSegment = slicer.vtkSegment()
lesionSegment.SetName("Lesion Seeds")
lesionSegment.SetColor([0.0,1.0,0.0])
segmentationNode.GetSegmentation().AddSegment(lesionSegment,"lesionSeeds")
1 Like

This example shows how to import and load all DICOM series in a file folder into the scene:

https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository#How_to_load_DICOM_files_into_the_scene_from_a_folder

1 Like

Wow, thank you so much! I am new to the forum and I have to say you all are so responsive and helpful.

I did the following below:

seriesInstanceUID = '2.16.840.1.114151.3.1.20566.9261759.7592.1584719071.211'
    sopInstanceUID = '2.16.840.1.114151.3.1.20566.9261759.7592.1584719071.212'

    seriesNodeIDs = DICOMUtils.loadSeriesByUID([seriesInstanceUID,])
    seriesVolumeNode = slicer.util.getNode(seriesNodeIDs[0])
    storageNode = seriesVolumeNode.CreateDefaultStorageNode()
    slicer.mrmlScene.AddNode(storageNode)
    seriesVolumeNode.SetAndObserveStorageNodeID(storageNode.GetID())
    storageNode.SetFileName(slicer.dicomDatabase.fileForInstance(sopInstanceUID))

And I get an error

  File "Z:/LoadSegMod/Dicom/SegmentDicom/SegmentDicom.py", line 166, in LoadSegment
    seriesVolumeNode = slicer.util.getNode(seriesNodeIDs[0])
TypeError: 'bool' object has no attribute '__getitem__'

Seems as if the issue is with the seriesNodeIDs[0]

For something like this it’s usually easiest just to add print statements to check all the return values and then check through the source code to see if you can figure out what’s going on.

If that doesn’t work you can also use debuggers.

Good luck!

1 Like

The code snippet in the “Nightly” sccript repository page requires latest Slicer Preview Release. Yours may be a couple of weeks old (or even older).

1 Like

Ohh my! I am using the latest official version rather than the latest preview release.
Do you know of any documentation on loading from a seriesUID using the version I am currently on?

Version: 4.10.2

DICOM loading has been completely reworked in Slicer Preview Releases (Slicer-4.11). We plan to release Slicer-4.11 as the new stable release within a couple of weeks, so I would not recommend to implement any DICOM processing script for Slicer-4.10.

Thanks for the advice. I have installed the latest preview version, but I have run into issues.

# Import and load dicom from directory
dicomDataDir = "Z:/Dicom2Text/LumbarCTforMagicLeap"
loadedNodeIDs = []

from DICOMLib import DICOMUtils
with DICOMUtils.TemporaryDICOMDatabase() as db:
  DICOMUtils.importDicom(dicomDataDir, db)
  patientUIDs = db.patients()
for patientUID in patientUIDs:
  loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID))

When I run this code there are two things that arise:

  1. I need to get the master volume node from this info. And when I try using slicer.util.getNode(loadedNodeIDs[0]) then it crashes the app.
  2. Running this code sometimes gives me an error stating:
    OSError: No patient found with DICOM database UID 1

Also when I try the code below I get have an empty seriesNodeIDs = []

    seriesInstanceUID = '2.16.840.1.114151.3.1.20566.9261759.7592.1584719071.211'
    sopInstanceUID = '2.16.840.1.114151.3.1.20566.9261759.7592.1584719071.212'

    seriesNodeIDs = DICOMUtils.loadSeriesByUID([seriesInstanceUID,])
    self.delayDisplay(seriesNodeIDs)
    seriesVolumeNode = slicer.util.getNode(seriesNodeIDs[0])
    storageNode = seriesVolumeNode.CreateDefaultStorageNode()
    slicer.mrmlScene.AddNode(storageNode)
    seriesVolumeNode.SetAndObserveStorageNodeID(storageNode.GetID())
    storageNode.SetFileName(slicer.dicomDatabase.fileForInstance(sopInstanceUID))

I’ve just tried it in Slicer-4.11.0-2020-03-23 (revision 28875 / e5c1f6e) win-amd64 and it worked well:

>>> from DICOMLib import DICOMUtils
>>> DICOMUtils.loadSeriesByUID(['1.3.6.1.4.1.14519.5.2.1.8421.4009.100453996512067231032804863467'])
Loading with imageIOName: GDCM
['vtkMRMLScalarVolumeNode1']