-
-
Notifications
You must be signed in to change notification settings - Fork 686
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ITK SpatialOrientation is opposite of DICOM and ITK annotation. #1163
Comments
This issue has been automatically marked as stale because it has not had recent activity. Thank you for your contributions. |
Would moving https://github.com/InsightSoftwareConsortium/ITKSimpleITKFilters/blob/master/include/itkDICOMOrientImageFilter.h here resolve this issue? |
We face a similar issue when trying to convert MRI DWI and T1 and T2 series to nifti using SimpleITK. We found out that especially some of the DWI-Series need to be flipped across an axis (mostly z-axis) so that the resulting niftis are displayed correctly. The axis across which needs to be flipped can be determined by some heurisitc, depending on the directions of the origins. For example, the reference T1 is:
The corresponding DWI is:
-> Heuristic: the z-components of the origin point into different directions thus the DWI needs to be flipped across this axis. This is pretty robust, although we also encountered some cases where the z-component is also negative (e.g. -25) but it needs to be flipped as well. Is there any possibility to find out more robulsty when series need to be flipped? Using the DICOMOrientImageFilter shows "LPS" for both sequences so it doesn't help us. We have the assumption that somehow the origin needs to be taken into account in order to determine if a volume need to be flipped (according to a reference image) or not. Would anyone have an idea how to continue on from this? Thanks in advance, Lorenz |
You seem to be dealing with a case of wrong metadata. There is no good solution to this. One possibility is for a human to review this, and flip axes as necessary. Another is to compute registration similarity metric between the DWI and T1/T2, both with and without axis flips and try to determine if a flip is needed. |
Hi @dzenanz , Thanks for your reply. You are right, we have now found out that the volumes corresponding to the different b-values of the DWI were read in false direction, leading to the above mentioned behaviour. In our case, all slices of the different b-values that belong to the same DWI are stored inside one single series-folder. In order to allocate slices to a specific b-value, we implemented some logic that was kind of: def tag_reader(slicepath):
reader = sitk.ImageFileReader()
reader.SetFileName(slicepath)
reader.LoadPrivateTagsOn()
reader.ReadImageInformation()
return reader
dicoms = sitk.ImageSeriesReader_GetGDCMSeriesFileNames(filepath)
b_value_list = []
file_dict = {}
for dcm in dicoms:
metadata_reader = tag_reader(slicepath=dcm)
# set dicom tag for b-values
bval_dicom_tag = "0019|100c" # Diffusion b-value, at least for siemens scanners
try:
bval = int(metadata_reader.GetMetaData(bval_dicom_tag).strip())
b_value_list.append(bval)
except Exception:
raise RuntimeError("no b-values found for this series")
if bval in file_dict.keys():
file_dict[bval].append(dcm)
else:
file_dict[bval] = [dcm] This When providing the values of this dict-items directly to the imageseriesreader, the resulting sitk-image (and nifti) are flipped across the z-axis: for _bval, _dcmlist in file_dict.items():
reader = sitk.ImageSeriesReader()
reader.SetFileNames(_dcmlist)
img = reader.Execute() However, what we have then identified is that the resulting dcm-path-lists in the The latter leads also to the correct / expected results, thus the sorting of the list of filenames provided to For us, this is solved now; however, the reason why I described our approach in this detail is that we were wondering, if this is something that can be solved more easily (maybe this "correct" sorting is already implemented somewhere) or if this finding can somehow help to improve existing code. |
@blowekamp or @issakomi might have some opinions. |
Hello @kapsner, This is a feature not a bug 😉 . The Possibly take a look at the SimpleITK code in the characterize_data.py script, specifically the inspect_series function. It traverses a directory structure and aggregates all the files that belong to each series into a list. You could do something similar with the key being Also look at how the inspect_single_series reads each series (creating a temp dir and softlinking or copying the original files) - this may be overkill for your case. It does address the situation where slices from the same series are in different directories and have the same file name (e.g. a/1.dcm b/1.dcm). Welcome to the wonderful world of DICOM. |
@blowekamp Following only applies to the first post in the thread: ITK identity is RAI, not RIP. I am sure that you know the rest of this post, just for the record. The "from" and "to" (Right-to-left vs. right-to-Left) terminology diverged long ago. The ITK space is the same as the DICOM space. But the ITK's identity is RAI-Code RAI is
the same as DICOM image with direction cosines RAI-Code LPS is
is not defined in DICOM space, because DICOM does not provide 3rd vector, 3rd vector is defined as right-hand cross product of the 1st and 2nd |
A new AnatomicalOrientaion class was added to clearly describe orientations: #4804 |
The spatial orientation enums are defined in the following file:
https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/Common/include/itkSpatialOrientation.h#L39-L40
DICOM is defined in LPS, where L indication from right-to-left. However, the enums are documented as
R
meaning right-to-left. And the tool converted an ITK's identity direction intoRIP
, where we are documented as being inLPS
.The
itk::OrientImageFilter
uses these enums and labeling. The filter and tools with the SpatialOrientation namespace are consistent, but they are defined in the opposite direction as DICOM, and common medial imaging standards.😕
The text was updated successfully, but these errors were encountered: