Page MenuHomePhabricator

Load DICOM slices at actual positions (handle unequally spaced slices and possible gaps)
Closed, ResolvedPublic

Description

Problem

A weakness of the current DICOM loading implementation is the process that loads a collection of 2D DICOM slices into a single image volume. This process sorts files to some extent into belonging volumens (differentiating groups of different orientation, size or slice thickness). However, it does not check consistent slice distance. Instead it takes the first two slices of a group (spatially sorted), calculates the origin and slice distance for a whole image block and then fills in all remaining slices without checking that they actually fit in the assigned position.

Possible problem: with this logic, some slices might be displayed to the user in a 3D position where they do not actually belong. I.e. the DICOM information would report position A, while the corresponding mitk::Image slice would report a different position B.

This behavior is a possible source of error, when secondary data (e.g. ROI measurements) is generated for 3D positions that mismatch with DICOM positions. The error only becomes apparent when later the previously missing slice is added and some of the mitk::Image slices would be loaded from different DICOM slices.

Attached is some ASCII "art" depiciting a possible error.

Suggested Solution

We need to improve the class DicomSeriesReader, which implements the loading of a series of DICOM files into mitk::Images. The class should be able to handle the situation above correctly by

  • either 'fill in' the gap with slices clearly marked as artificial
  • or separate the two parts into separate mitk::Images

This should be done depending on how big the gap is. Clearly, filling in more slices than the actual two parts cover is not meaningful. A sensible algorithm should be implemented to decide between the two options.

Event Timeline

A second aspect that is missing in description above: slices sorted into the same group might be spaced unequally. These cases should be detected and the sorting should be updated to get groups of equally spaced slices.

(In reply to comment #0)

a series of DICOM files into mitk::Images. The class should be able to handle
the situation above correctly by

  • either 'fill in' the gap with slices clearly marked as artificial
  • or separate the two parts into separate mitk::Images

This should be done depending on how big the gap is. Clearly, filling in more
slices than the actual two parts cover is not meaningful. A sensible algorithm
should be implemented to decide between the two options.

Correction: to simplify things (for implementation and algorithms), we will never insert artificial slices.

Wrote down internal structure of DicomSeriesReader to get a better idea of where exactly to put a check for appropriate inter-slice distances.

Added a method to load a list of explicit file names instead of directories
only.

Implemented a seemingly working solution for splitting up image blocks when the slice distance does not match the expectations of ITK's ImageSeriesReader.

Next, some good test images need to be found / produced.

Current solution seems promising. Still needs a little cleaning.

Just noticed, I forgot the dear 3D+t capabilities... will need a solution for that

Worked out a viable solution to the 3D+t problem:

  • first sorting sorts files into blocks that form a single 3D block, without any two slices occupying the same position in space.
  • second sorting pass (optional, but default) attempts to re-group blocks into "3D+t" blocks
    • make an extremly simple assumtion:
      • blocks that form a 3D+t block must all contain an identical number of slices

Above mentioned solution now works. All test cases still work. 3D+t handling seems to work.

Still TODO:

  • document interface and design changes
  • adapt existing client code to not use SortSeriesSlices() anymore (done by GetSeries now)
  • integrate and fix complaints
  • drop GDCM < 2.0.14 support

[3bafc4]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Merged commits:

2011-05-03 09:18:56 Daniel Maleike [db7d2b]
Link to test documentation

Merged into master mostly with bug-3700-dicom-loading-tests

Documentation will appear here:

http://docs.mitk.org/nightly-qt4/classmitk_1_1DicomSeriesReader.html

The code could now need more cleaning regarding 3D+t loading (such data is sorted two times, instead of only once, T8022), but functionality is completely implemented, tests are running.

[69d00e]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Merged commits:

2011-05-03 09:43:49 Daniel Maleike [954e93]
Force sorting until code is cleaned up

Tested on many more real-world images: tolerance for expected-actual origin was too sensitive, resulted in many splits for some series.

A tolerated error of 0.005mm seems to be acceptable. Such an offset is still irrelevant for "normal" measurements (would result in an error of 1/10 mm when measurement is taken accross 20 slices).

[131d09]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Merged commits:

2011-05-03 14:47:58 Daniel Maleike [310db7]
Increase tolerated error for expected origin positions

[f2643f]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Merged commits:

2011-05-03 15:35:27 Daniel Maleike [0d6a68]
Be less verbose

[bde486]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Conflicts:
Co

Merged commits:

2011-05-05 16:11:43 Daniel Maleike [50404a]
Put filenames of individual slices into a property of mitk::Image

Last commit added the file names of individial slices as a property. This would allow applications to at least know which slice is which

Reopen to integrate minor changes from Markus' review

[02f740]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Merged commits:

2011-05-06 17:51:13 Daniel Maleike [71ee6e]
Consistently number implementation parts; rename map to groupsOfSimilarImages


2011-05-06 17:50:46 Daniel Maleike [8d242b]
Remove redundant documentation


2011-05-06 17:50:35 Daniel Maleike [940ab5]
Remove unreadable code


2011-05-06 17:50:13 Daniel Maleike [e896f8]
Add a little documentation


2011-05-06 17:50:04 Daniel Maleike [eda36b]
Correct doc


2011-05-06 17:49:22 Daniel Maleike [44d288]
Merge branch 'bug-7620-bye-DICOMIO' into bug-7285-ensure-correct-slice-positions

Conflicts:
Core/Code/IO/mitkDicomSeriesReader.h

Just found out that the test cases were all formulated wrongly. The current reader produces mostly 3D+t data, even from single slices or 3D slice stacks.

[d22135]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Merged commits:

2011-05-10 15:16:54 Daniel Maleike [c55f3d]
Correctly load 3D image volumes as 3D, not 3D+t with a single time step

Corrected loading routine, which now requires at least 2 volumes for loading as 3D+t. Also adapted test cases in MITK-Data.

[139aed]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Merged commits:

2011-05-10 17:51:44 Daniel Maleike [4adcad]
Temporarily deactivate tests

Deactivated tests, don't pass on Windows. Don't see an obvious reason...

[9f9951]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Merged commits:

2011-05-11 09:30:02 Daniel Maleike [062100]
Activate tests again


2011-05-11 09:29:52 Daniel Maleike [5cc4fa]
Implement value based string comparison function to handle minor platform differences

The reason for the failing tests was obvious :

Something like expected string "1.23e-32", actual string "1.23e-032".

Fixed this by actually implementing the value based comparison function, which now tokenizes strings and compares them by float value if possible. This should fix the problem.

Just found another interesting case from reality..

Series that contain two volumes with slices that are interleaved, such as z positions (with equal x/y positions)

05.8
06.8
07.8
08.1
08.8
09.1
09.8
10.1
10.8
11.1
12.1
13.1

Would be sorted into two bigger blocks and lots of two-slices blocks by the current implementation. This is formally ok, because all slices are still loaded at their correct positions. However, a modified sorting approach would yield bigger volumes, i.e. it would be more radiologist-compatible.

I implemented a slightly modified approach, which could be described as optimistic or greedy (as in regular expressions):

Instead of splitting a volume at the first sight of a slice that does not match the volume's expected slice-distance pattern, we can simply just ignore files that do not fit into this distance pattern and analyze them later.

This approach results in bigger consecutive slice groups, so I think this fits radiologists more.

[07c2f4]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Merged commits:

2011-05-11 16:19:50 Daniel Maleike [07bb06]
Describe the added test case


2011-05-11 16:19:42 Daniel Maleike [5a457e]
Describe the optimistic / greedy sorting approach


2011-05-11 16:12:41 Daniel Maleike [0eaf22]
Implement an optimistic / greedy approach for slice sorting.

This version does not split a volume as soon as some files does not match its expectations.
In contrast, it just skips such files and checks for remaining files that DO fit.
This approach results in more probable image volumes with series that contain interleaved volumes.
(details in documentation)

Problem seems solved with last fix. I'll let bug open for a day more until I have checked more candidates from the real world.

[118231]: Merge branch 'bug-7285-ensure-correct-slice-positions'

Merged commits:

2011-05-12 16:06:44 Daniel Maleike [61d5ca]
Reformat warning and debug messages to make sense for interested readers

Closing this finally.

I've now checked enough real world cases to be confident that this loading code will work for long enough. As a last change I've just modified the debug and warning messages so that possible readers could understand what is going on.