I am trying to read this file using SimpleITK but I am getting the following error message:
File "/Users/odin/anaconda/lib/python2.7/site-packages/SimpleITK/SimpleITK.py", line 8332, in ReadImage
return _SimpleITK.ReadImage(*args)
RuntimeError: Exception thrown in SimpleITK ReadImage: /scratch/dashboards/SimpleITK-OSX10.6-intel-pkg/SimpleITK/Code/IO/src/sitkImageReaderBase.cxx:285:
sitk::ERROR: Only Complex image with float and double are supported!
However I can perfectly read segmentation files with one segment. Is this a limitation of the current version?
When looking at the NRRD headers:
So I know I have my two segments there (first index of sizes gives the number of segments) and that actually matches with the data array.
Does anyone know about this problem?
How was this image created? I’m guessing the “type” is some thing like “unsigned short”. Seems not appropriate to save a multi-segmentation image with a “complex type”.
Technically in C++ std::complex_short has undefined behavior. So SimpleITK only support std::complex of float and double as the error message says.
Perhaps the NRRD author (@glk) or a Slicer developer (@fedorov@lassoan) could tell us if that is a normal file type or not.
@Diego_C to solve your immediate problem, you can export individual segments as label maps using Segmentations module of Slicer, and save those in separate 3-d files that ITK will know how to deal with.
You can even export both of the segments into a single label map 3d file, since they do not overlap.
I totally get the workaround you propose it makes sense since having separate nrrd files for each segment will give SimpleITK easily recognizable nrrd headers. However I can’t implement it! I have about 900+ segmentations already from 3 different radiologists… so I couldn’t possibly do this by hand.
Last night I develop code that reads these multi-segment segmentations which in nrrd terms means a 4-dimensional array where the first index indicates the segment s (like this [s, x, y, z])
And generates a SimpleITK image with for each segment. I made sure that the metadata for each image was preserved so each image has its origin, spacing, direction, etc.
I wonder if there is a way for me to contribute this code ??
multi-volume nrrd (like in this case) seems to be a current limitation for sitk.ReadImage
Thanks Bradley I will give it a try and let you know. I am away from my computer for Easter Friday (typing all of this on my phone) will check this weekend.
When Slicer saves segmentation (4D volume) to file then it uses vtkTeemNRRDWriter, which unfortunately tries to be smart and guess the axis type from the number of vector components - for 2 components it assumes that it is a complex number (https://github.com/Slicer/Slicer/blob/master/Libs/vtkTeem/vtkTeemNRRDWriter.cxx#L90). I’ll fix this in Slicer - it’ll always use “vector” as axis kind.
I am pondering if SimpleITK should automatically load complex of integers as plain vector images with a warning, or the produces error should just suggest adding the “outputPixelType” parameter.
How long has Slicer been producing this type of image?
How long has Slicer been producing this type of image?
For about a year. The problem occurs only when there are two (or few other) components. Also, many people kept using the old editor and simple labelmap format for a while. So, probably the number of “complex” files are quite low. However, it would be still useful to make SimpleITK be able to load any kinds of axis.
The problem is that SimpleITK supports complex type, but that image is not a kind of complex type SimpleITK supports (and appropriately gives an error message). Segmentations module should always write vector or list for the first dimension.
Existing segmentation file that have two segments (and thus the incorrect “complex” kind) can be fixed by loading the file into Slicer and saving it.
If SimpleITK can only support complex with float components then when a complex image with int components is read then you can convert the values to float. However, such images should be very rare, so supporting this may not worth the implementation, testing, and maintenance effort.
Thank you @lassoan for your help. I have 900+ segmentations by 3 radiologist at the moment so doing this change in the headers by loading each file in Slicer is not feasible. However, as I mentioned before I wrote some code that handles these multi-segmentations correctly and generates a SimpleITK image for each. I would be happy to contribute this code as a work around for people with the same problem.
Actually that was going to be my next script while you guys and gals update Slicer .
No, this code loads the multi-segment segmentation NRRD using pynrrd and then for each volume creates a SimpleITK image observing the appropriate metadata.