Cranial and caudal directions are opposite when loading sequence of DICOM images

@pieper

  1. The CT scanner is from Siemens, but the same problem happened on Toshiba CT. So, this problem is not related to the kind of CT scanner.
  2. I used “Load Data” (not “Load DICOM Data”). But when I loaded images using “Load DICOM Data”, image orientation (z direction) became correct.
  3. When I renamed the DICOM files in reverse order (i.e., change from 1, 2, 3, 4 to 4, 3, 2, 1), ordering of slices was inverted (changed from inverted view to correct view). So, maybe this problem is related to loading order of image files.

@xackey, does the Slicer DICOM module warn you about geometry issues with this data?

If it’s really the case that ITK is using the file name rather than the Image Position Patient tags in the dicom header to sort the images this is a terrible regression. I haven’t really thought about it since the discussion on the ITK issue tracker last summer, but I’m really surprised this hasn’t been fixed. @lassoan what do you think?

In GDCM IPP/IOP ordering is the first choice (there is also an option for user-derined ordering, but is unused), if it fails then Image Number tag is used, if it fails too then file names. The change was to use Image Number. There is a link to GDCM commit in ITK issue discussion above.

S. gdcmSerieHelper.cxx

I could not reproduce the flipping issue by specifying a single DICOM file for ITK. Slicer’s frame sorter works well, too. The problem only occurs when somebody uses the “Add data” dialog in Slicer to load DICOM data - it somehow uses the ITK DICOM reader in an incorrect way.

I’ve never really understood how DICOM loading via “Add data” dialog is supposed to work and why it is so complex. I think the best would be to remove this loading method, as it has many other limitations anyway.

2 Likes

@pieper

does the Slicer DICOM module warn you about geometry issues with this data?
→Do you mean viewing a “Error log”? I show a log after loading the DICOM files.

If this problem can be resolved by changing application settings of 3D Slicer, could you tell me how to do it.
Thank you!

I tried public DICOM images, but I have the same result; version 4.10.2 is correct view, but 4.13.0 is flipped.

I attached the link of the DICOM images below. Could you check whether the issue will be reproduced?

https://drive.google.com/drive/folders/14s0U2WJyVQ0u-Ni5U8ulet0Yy0fAccZc?usp=sharing

I could not reproduce the problem in Slicer (and in my app too).

Edit:

@xackey

Oops, i have reproduced, in fact, with “Load Data” dialog (select a folder)

Screenshot at 2021-05-06 20-30-20

Yes, I think now (as part of slicer5) we stop letting people load dicom via that legacy Add Data code. For now I would at least way we should consider it ill-advised.

I’d still argue this must be a regression in ITK because the dataset that reproduces the issue does have valid ImagePostiionPatient values that Slicer is able to parse, but for some reason the newer ITK ignores in favor of using the filenames. Very odd.

@issakomi
Thank you for trying.
Version 4.10.2 has no such issue even when choosing “Load Data” dialog.
I think there is something difference in data loading systems between version 4.10.2 and 4.13.0.

1 Like

This ITK example - ReadDICOMSeriesAndWrite3DImage works fine, sorted by IPP as expected. I have tried C++ version with ITK master and above data set, result - nrrd file - is correct. Here is this example with cmake and data set shared above.

I have also compared vtkITKArchetypeImageSeriesReader.cxx from 4.10.2 and from master, they are very different. 100+ lines were changed, specially parts related to DICOM were updated.

I am still not sure what the problem is. I am building Slicer, may be i shall find the source of the problem and report.

3 Likes

Thanks very much for your help with this @issakomi :pray:

1 Like

I can confirm that ITK examples work well, that’s why I did not ask ITK developers to investigate this change in behavior. There is something special about how Slicer uses ITK’s DICOM reader, and considering how complex that code part is, it is quite possible that Slicer does not use the API correctly.

@pieper You’re welcome.

Highly likely the problem is in vtkITKArchetypeImageSeriesReader.cxx, i have built Slicer master and have done very quick and dirty port of that file (and .h file) from 4.10.2 (only added things related to new VoxelVectorType). And there is no flip. I shall try to find out what exactly is the issue, but it can take several days, and confirm if it will work.
Here is tiny (20 s) video:

1 Like

This bug is in Slicer since commit 12 Jan 2020. New function itk::ImageIOBase::Pointer vtkITKArchetypeImageSeriesReader::GetImageIO was added. In the function a list of files is assembled before check for DICOM IO. And later, in vtkITKArchetypeImageSeriesReader::RequestInformation, the point, where itk::GDCMSeriesFileNames is called, is not reached.
// if user already set up FileNames, we do not try to find candidate files if ( this->GetNumberOfFileNames() > 0 )

1 Like

Nice detective work!

This sounds fixable, but we should still consider removing the option to load dicom via that class. That archetype series code is so hard to maintain and it surely needs a redesign after so many years of patching.

1 Like

@issakomi, thanks a lot for this investigation!

It seems that we have 3 slice sorting implementations:

  • GDCM: probably robust but most likely it only supports simple cases (e.g., cannot handle 4D volumes with variable spacing)
  • vtkITKArchetypeImageSeriesReader: very basic implementation, not robust and currently broken. It can be fixed with these changes, but it would require much more work.
  • DICOMScalarVolumePlugin (and other plugins for 2D+t, 3D+t, etc.): can handle very complex cases. It uses vtkITKArchetypeImageSeriesReader to load a file list.

Potential next steps:

  • We should remove the sorter in vtkITKArchetypeImageSeriesReader to reduce redundancy and maintenance workload.
  • We should also simplify and fix vtkITKArchetypeImageSeriesReader and all subclasses to make errors such as this one easier to avoid in the future. Probably merge all subclasses (vtkITKArchetypeDiffusionTensorImageReaderFile, vtkITKArchetypeImageSeriesReader, vtkITKArchetypeImageSeriesScalarReader, vtkITKArchetypeImageSeriesVectorReaderFile, vtkITKArchetypeImageSeriesVectorReaderSeries) in a single class replace macros by templated functions, etc.
  • To reduce chance of use errors, we should probably redirect users to the DICOM module for loading DICOM data. Maybe the image reader plugin could detect DICOM data sets and import them to the DICOM database.

@pieper @jcfr @cpinter @fedorov What do you think?

2 Likes

Each of the steps you listed makes complete sense to me. After many such queries I think it is high time we detect DICOM loading and only allow it via the browser. Also it would be great simplifying the vtkITKArchetypeImageSeriesReader adjacent code.

1 Like

One historical note: a lot of the logic in these classes is split out because all the template instantiations led to memory issue in old compilers.

2 Likes

Hi.
The issue has not been fixed yet in the latest 3D slicer (4.13.0).
Could you tell me the current status?
Thank you for your help.

DICOM loading using the Load Data Dialog (which is typically used for loading all other files in Slicer) is planned to be disabled. See Disable DICOM import from "Add data" dialog · Issue #5726 · Slicer/Slicer · GitHub.

You should load DICOM data using the DICOM module. See more details at Data Loading and Saving — 3D Slicer documentation.

1 Like