Closed ashgillman closed 6 years ago
Hello,
Thanks for reporting this and sorry for the delayed response.
I think this bug has sprung from my own hacky workaround here: https://github.com/moloney/dcmstack/blob/master/src/dcmstack/dcmstack.py#L766
I added that crappy workaround since we tend to make heavy use of the program fslview
for viewing Nifti images, and it crashes on unsigned integer data...
I guess the least bad option is to check if this overflow is going to happen, and only do the work around if it won't overflow.
Ah, that looks like the culprit. Perhaps the type hack should be performed after populating vox_array
.
if stack_dtype == np.uint16 and np.all(vox_array > 0):
vox_array.astype(np.int16)
As an aside, could https://github.com/moloney/dcmstack/blob/master/src/dcmstack/dcmstack.py#L794 be replaced with:
vox_array = vox_array.squeeze()
Or are you trying to keep the implementation robust by only squeezing dims 3 and 4?
I think this should be fixed in commit eb042f19bcb6898c95713b86f205d09b5235650b. I took a slightly different approach to your PR and added some tests. Sorry for letting this sit for so long.
I have the same issue, when converting a PET image to nifti I get negative values and I am using dcmstack version 0.6.2,can it be because of this?
The fix is in version 0.7, which is finally on PYPI (i.e. you can do 'pip install dcmstack').
Thank you for the reply. Do you think it's possible to have this version in anaconda as well?
I just looked into the code of the 0.7 version and I can't really see how it's changed, since I still see these lines that are responsible for the negative values :
if stack_dtype == np.uint16 and bits_stored < 16: stack_dtype = np.int16
I just used the code available online and copied, it is working now, I don't get the negative values, however, I would like to have the slope and intercept taken in consideration, this doesn't seem to exist in Dcmstack, if I see correctly? But then, why when I make a nifti out of my stack (to_nifti plain or with embed_meta=True ), the same voxel value changes? The orientation?
I have no plans to package it for Anaconda (can't you pip install into an Anaconda environment?).
You can pass an empty string to --voxel-order
to avoid any reorientation.
I believe the output should be pre-scaled floating point (i.e. slope/intercept transform is already applied).
Thank you, setting the voxel_order='' helped, now I have the same values in nifti and the dicom stack, which are indeed floating point. And after verification, it is Nibabel that scales the data and it is used in dcmstack. So, in case it might be useful for others, in Nibabel get_pixel_array returns the raw data and get_data gives the scaled data.
Sorry, I am being stubborn with this. But I found that in Nibabel there is a possibility to get unscaled data (img.dataobj.get_unscaled()). However, it only works for nifti data directly loaded from the disk and not with to_nifti for instance, and what is worse is that it still gives the scaled data. Would it mean that to_nifti does not preserve the unscaled data? How can one access such data with Dcmstack then?
Yeah I noticed when I fixed this bug that dcmstack will never save the unscaled data into the Nifti (copying over the slope/intercept from the DICOM data). I was thinking about adding this in, but didn't have the time. It really would just be a space saving optimization.
I opened a new issue (#62 ) to track this, but fixing it isn't a priority for me. I would accept a well written PR though...
What is PR? Converting a two-hundred set of DICOMs I see that I still have the negative values problem. I don't know where it comes from considering there is not more bit of the code you used for FSL. I am thinking of using something else (dcm2niix?)
Negative values aren't necessarily indicative of a bug. What are the slope/intercept values in the DICOM files when you get negative values?
They shouldn't be negative : ('Slope ', 3.0932071993164, 'Intercept ', 0.0) I compared one image pixel values by accessing the image data different ways and getting their dtype, here are some lines to avoid ambiguity and their outputs :
Some conclusions I make out of it :
If you have some explanation on this, or you want an image example and/or the code before, I can provide them. I can make it all with Dcm2niix, as I am pretty sure it works well, even though it's not a very elegant solution to my taste.
A part from this issue, I have some CSA field troubles (Siemens scanners).
Thank you for your help.
I am having a hard time following the code in your comment. Can you share a minimal script and data set that demonstrates the issue?
I don't see any negative values, but maybe there is some sort of precision loss?
I am also not sure why you are including the voxel_order in your permutations, it has no bearing on how the voxel intensities are scaled (it just affects how they are indexed).
It certainly is possible there is still some bug in how I am handling this in dcmstack, and if that is true I would like to fix it.
I am having a hard time following the code in your comment. Can you share a minimal script and data set that demonstrates the issue?
Sorry, here is the code and one dicom folder attached.
I don't see any negative values, but maybe there is some sort of precision loss?
You can't see them in the pixel value I tested, but they do exist, and as you see, we get int and not unsigned int.
I am also not sure why you are including the voxel_order in your permutations, it has no bearing on how the voxel intensities are scaled (it just affects how they are indexed).
The voxel order was used as I had a different orientation compared to other patient's files (segmentation, masks and so on).
Hi, When converting some PET images I get negative intensities in the output NIfTI for voxels with intensities > 2^15 on the original DICOM (i.e., probably a signed int overflow). I believe this is probably an upstream issue (pydicom or nibabel), and I am happy to report there and track. I am hoping first to see your thoughts on the issue.
Below is the DICOM header data of an offending image for reference: