DICOM Images read with GDCMSeriesFileNames or list of paths

simpleitk read dicom
sitk

I am using SimpleITK to analyse Dynamic PET Data. I have a folder with 148 * N images (with N the number of frames of my Dynamic PET) and I want to separate the images of each frames. Firstly, I created one subfolder for each frame with the corresponding images.

>folder #Folder of dynamic data
   >subfolder1 #Subfolder with images of Frame 1
      >image1, image2, ..., image148
   >subfolder2 #Subfolder with images of Frame 2
      >image149 image 150, ..., image296

I was reading my images as following:

series_reader = sitk.ImageSeriesReader()
image = sitk.ReadImage(series_reader.GDCMSeriesFileNames(path_subfolder1))

Creating all these subfolders is not very user-friendly so I try to store all the paths of the images in lists :

frame1 = [image1, ..., image148]
frame2 = [image149, ..., image296]
...
frame_list = [frame1, frame2, ..., frameN]

And reading images like this:

image = sitk.ReadImage(frame_list[0])

The problem is that when I am looking at the value of a voxel located in the same coordinates (x, y, z), I don't get the same value with the 2 methods. It seems that with series_reader.GDCMSeriesFileNames() SimpleITK retrieve some information about the DICOM image like the Origin.

Which information are retrieved by SimpleITK to create his images with series_reader.GDCMSeriesFileNames() that I need to have the exactly same image? Or is there another way to have the same image using list of paths?

P.S. : In this post, all the variables named with 'image' are the paths to the images not a SimpleITK Image object.

Edit : In my case, all of my frames have got the same series number so I can't use series_reader.GDCMSeriesFileNames(path_folder, series_ID)

As far as I've understood your question, you have got a folder with all Dicom slices and you want to read them as a single volume so that you could access voxel values at any given coordinate. Try reading your Dicom images by this code snippet:

reader = sitk.ImageSeriesReader()
dicom_names = reader.GetGDCMSeriesFileNames(path_subfolder1)
reader.SetFileNames(dicom_names)
image = reader.Execute()

Now, image is your 3D volume containing all slices present in path_subfolder1 and you can access voxel values, spacing, directions, origin etc.

I hope this helps, if not feel free to comment down below.

Read DICOM Series and Write 3D Image, This example reads all the DICOM series in a given folder argv[1] and writes them in the using NamesGeneratorType = itk::GDCMSeriesFileNames; New​() outFileName = os.path.join(dirName, seriesIdentifier + '.nrrd') if  Read DICOM Series and Write 3D Image¶ Synopsis ¶ This example reads all the DICOM series in a given folder argv[1] and writes them in the same folder with following file pattern: seriesIdentifier.nrrd

There is no need to split the series into separate directories. You can get the list of seriesIDs in a directory with the itk::simple::ImageSeriesReader::GetGDCMSeriesIDs method.

You can easily create a map for seriesID to file lists with the following one liner: series_dic = { series_id: reader.GetGDCMSeriesFileNames(path, series_id) for series_id in reader.GetGDCMSeriesIDs(path) }

By using the GetGDCMSeriesFileNames method you should get all the files is the proper order sorted by their physical locations, with your manual method you are not.

If this automatic approach does not work for your particular scanner or acquisition process, you will have to manually load the DICOMS dictionaries, separate them by series_id, and then properly sort them based on the proper DICOM tags for your acquisition.

Examples/IO/DicomSeriesReadSeriesWrite.cxx, This example illustrates how to read a DICOM series into a volume and then. // save this volume back the image using the information from the input DICOM files. //. // Please note that using NamesGeneratorType = itk::​GDCMSeriesFileNames; image. // IO object to be used with it, and set the list of filenames to read. Data source that reads image data from a series of disk files. This class builds an n-dimension image from multiple n-1 dimension image files. The files stored in a vector of strings are read using the ImageFileReader. File format may vary between the files, but the image data must have the same Size for all dimensions. See. GDCMSeriesFileNames

The temporary solution I find is the following one :

1) Creating lists containing every slice as Image Object using sitk.ImageFileReader():

frame1 = [Image1, ..., Image148]
frame2 = [Image149, ..., Image296]
...
frame_list = [frame1, frame2, ..., frameN]

NB : Here we deal with sitk Image Object and not images path as in my first post

2) Modifying every images seriesID in the DICOM header:

count = 1
for frames in frame_list:
  for images in frames:
    newID = images.GetMetaData('0020|000e') + str(count)
    images.SetMetaData('0020|000e', newID)
  count += 1

3) Writing the images with their new seriesID in a buffer folder using writer = sitk.ImageFileWriter() and writer.KeepOriginalImageUIDOn()

4) Storing in a dictionnary all the different series ID with the associated images path using @blowekamp method :

series_dic = { series_id: reader.GetGDCMSeriesFileNames(path, series_id) for series_id in reader.GetGDCMSeriesIDs(path) }

5) Reading the series and store them in a list:

for keys in series_dic:
  Img_list.append(sitk.ReadImage(series_dic[keys]))

6) Finally I remove the buffer folder with shutil.rmtree(path, ignore_errors=True)

This is not very optimized because I must write new images then delete it. If you have a better answer feel free to comment!

Grassroots DICOM / List gdcm-developers Archives, BTW you should read what I am doing in itk::GDCMImageIO, because the But one difficult thing is that it is rare to find the > color dicom image file of MRI especially typedef itk::Image <float, 3> ImageType; typedef itk::​GDCMSeriesFileNames 133679 Callgrind does not write path names to sources with dwarf debug info  1 Answer 1. It's better if you resize the images first. This is because image registration algorithms will try to find a transformation that optimizes the match of the images. If you know the proper size of the images, it will be easier for the algorithms to find such transformation.

Read DICOM directory, This example shows how to read DICOM directory. /project/pydicom/data/​test_files/dicomdirtests/77654033/CR1/6154'] Patient Names in images. license : MIT from os.path import dirname, join from pprint import pprint import pydicom from  // actually read and write the DICOM images, and the // \doxygen{GDCMSeriesFileNames} object that will generate and order all the // filenames for the slices composing the volume dataset. Once we have the // types, we proceed to create instances of both objects. // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet

Read DICOM directory, This example shows how to read DICOM directory. /project/pydicom/data/​test_files/dicomdirtests/77654033/CR1/6154'] Patient Names in images. license : MIT from os.path import dirname, join from pprint import pprint import pydicom from  // very common therefore for image analysts to have to process volumetric // images that are stored in the form of a set of DICOM files belonging to a // common DICOM series. // // The following example illustrates how to use ITK functionalities in order // to read a DICOM series into a volume and then save this volume in NIFTI // file format. //

DICOM series private tag, The DICOM directory contains several serieses corresponding to time frames, and I'm trying to read them in separately 3D images. The GDCMSeriesFileNames​  Frames to read, specified as an integer scalar, a vector of integers, or 'all'. When f is numeric, dicomread reads only the specified frame numbers from the image. By default, dicomread reads all frames of the DICOM image.

Comments
  • Thanks for your answer. In fact it is what I am doing with my 1st method but it is maybe not understandable. The problem with this way is that I must modify the input data by creating subfolders in which I will move the corresponding files. In my opinion, it's not very user-friendly. That's why I want to deal with lists of paths instead but it doesn't product the same results. I find out that for example the Origin of the image generated by the 2 methods is different.
  • Unfortunately, this isn't working for me as all my images have got the same ID. You mean that it is possible to sort them out using another DICOM tag than Series ID? Will it work in reader.GetGDCMSeriesFileNames(path, series_id) if series_id is another DICOM tag ? An other way is maybe to modify the DICOM header to allocate new series ID to my images but I prefer not to if it's possible