dgobbi / vtk-dicom

A set of classes for using DICOM in VTK.
BSD 3-Clause "New" or "Revised" License
243 stars 93 forks source link

Reading multi-pass CT series #220

Open dgobbi opened 1 year ago

dgobbi commented 1 year ago

Recently I've seen more and more CT scans that include multiple passes within the same series. Logically, each pass forms a separate stack, but with legacy DICOM files there's no clear indication of which files belong to which stack. However, it should be possible to detect discontinuities in the spacing and use these to identify the transitions from one pass to the next.

dgobbi commented 11 months ago

Further notes on this problem. When dicomtonifti encounters these multi-pass images, then if all images have the same orientation, it forces all the images to into a single stack. The resulting stack is distorted (stretched in the overlap region and compressed elsewhere) and definitely cannot be considered a valid/correct conversion.

So far, for all the multi-pass CT's that I've seen, each pass has a different AcquisitionNumber. And by splitting the series according to acquisition number before reconstruction, I'm able to generate a separate (and correct) volume for each stack. However, I don't know if this will always work.

eightysix commented 1 month ago

Further notes on this problem. When dicomtonifti encounters these multi-pass images, then if all images have the same orientation, it forces all the images to into a single stack. The resulting stack is distorted (stretched in the overlap region and compressed elsewhere) and definitely cannot be considered a valid/correct conversion.

So far, for all the multi-pass CT's that I've seen, each pass has a different AcquisitionNumber. And by splitting the series according to acquisition number before reconstruction, I'm able to generate a separate (and correct) volume for each stack. However, I don't know if this will always work.

Hello David. Can you provide a code example on how to split the series according to acquisition number?

dgobbi commented 1 month ago

There's two ways to do this. One is to separate the acquisitions into different directories before reading them. This requires using the command-line tools. Let's say that the DICOMS are in a directory called "series_folder":

$ dicomtocsv --all-unique -k AcquisitionNumber -k SeriesInstanceUID series_folder/
"1\2\3","1.3.6.1.4.1.5962.1.3.50.1.1166562673.14401"
"4\5\6","1.3.6.1.4.1.5962.1.3.50.2.1166562673.14401"

This indicates two series (identified by their UIDs), where one series has acquisitions 1,2,3 and the other has acquisitions 4,5,6. The first acquisition can be split into a new directory like this:

$ mkdir acq_folder1
$ dicompull -k AcquisitionNumber=1 -o acq_folder1/ series_folder/

If you want to do the separation in a C++ program, the vtkDICOMDirectory class can be used to select the DICOM files that belong to just one of the acquisitions:

  // specify the acquisition number to read
  vtkDICOMItem query;
  query.Set(DC::AcquisitionNumber, 1);

  auto selector = vtkSmartPointer<vtkDICOMDirectory>::New();
  selector->SetFindQuery(query);
  selector->SetDirectoryName(dirname);
  selector->Update();

  auto reader = vtkSmartPointer<vtkDICOMReader>::New();
  reader->SetFileNames(selector->GetFileNamesForSeries(0));