Simple ITK Write to File Resampled DICOM

Hi,

The crude code written below is used to (1) read in a set of DICOM files, (2) resample and then (3)write back out the resampled data to DICOM files. Steps 1 and 2, seem to be OK, but step (3) fails with the following error:-

libc++abi.dylib: terminating with uncaught exception of type itk::simple::GenericException: /opt/SimpleITK/Code/IO/src/sitkImageSeriesWriter.cxx:233:

sitk::ERROR: ImageSeriesWriter does not support writing a DICOM series!

The error seems fairly straight forward, but I though that it was capable of writing out a DICOM series. Can anyone point me in the right direction on this one?

Regards, Nick.

The code is attached below:

#include <SimpleITK.h>
#include "itkImageSeriesReader.h"
#include "itkImageSeriesWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkDCMTKImageIO.h"
#include "itkDCMTKSeriesFileNames.h"

#include <filesystem>

namespace fs = std::filesystem;
namespace sitk = itk::simple;

int main(int argc, char * argv[])
{
  if (argc < 3)
  {
    std::cerr << "Usage: " << argv[0] << " DicomDirectory  outputFile" << std::endl;
    return EXIT_FAILURE;
  }

    std::vector<std::string> dicomFiles;
    std::vector<std::string> metaData;
    std::map<std::string, float> unsortedDicomData;
    std::vector<std::string> sortedDicomData;
    
    bool firstPass = true;
    std::string comparativeSeriesUID;
    
    for (const auto & entry : fs::directory_iterator(argv[1])) {
        
        if (entry.is_regular_file() && (entry.path().extension().compare(".dcm") == 0 ) ) {
            sitk::ImageFileReader reader;
            reader.SetFileName(entry.path());
        
            sitk::Image image = reader.Execute();
            std::string seriesUID = image.GetMetaData("0020|000e");
            
            if (!firstPass) {
                comparativeSeriesUID = seriesUID;
            } else {
                if (seriesUID.compare(comparativeSeriesUID) == 0) {
                    std::cout << "ERROR: There are mixed SeriesUID's in this directory. Not all DICOM scans are from the same series!" << std::endl;
                }
            }
            
            float zPosition = image.GetOrigin()[2];
            dicomFiles.push_back(entry.path());
            unsortedDicomData.insert(std::pair<std::string, float>(entry.path(),zPosition));
        }
        firstPass = false;
    }
    
    // Now the series needs to be sorted
    std::map<std::string,float>::iterator it = unsortedDicomData.begin();
    for (it=unsortedDicomData.begin(); it!=unsortedDicomData.end(); ++it)
//       std::cout << it->first << " => " << it->second << '\n';
       sortedDicomData.push_back(it->first);
    
    // Read the DICOM data
    sitk::ImageSeriesReader reader;
    reader.SetFileNames(sortedDicomData);
    sitk::Image image = reader.Execute();
    
    
    std::cout << image.GetSize()[0] << " " << image.GetSize()[1] << " " << image.GetSize()[2] << std::endl;

    double rescaleFactor = 4.0;
    double rescaleFactorZ = 1.0;
    
    std::vector<double> spacing;
    spacing.push_back(image.GetSpacing()[0]*rescaleFactor);
    spacing.push_back(image.GetSpacing()[1]*rescaleFactor);
    spacing.push_back(image.GetSpacing()[2]*rescaleFactorZ);
    
    std::cout << spacing[0] <<" "<<spacing[1]<<" " << spacing[2] << std::endl;
    
    std::vector<uint32_t> size = {128,128,112};
    
    sitk::ResampleImageFilter filter;
    filter.SetReferenceImage(image);
    filter.SetInterpolator(itk::simple::sitkLinear);
    filter.SetOutputDirection(image.GetDirection());
    filter.SetOutputOrigin(image.GetOrigin());
    filter.SetSize(size);
    filter.SetOutputSpacing(spacing);
    image = filter.Execute(image);
    
    
    std::vector<std::string> resampledFileNames;
    // Write out the resampled image
    for (int i=0;i<image.GetSize()[2];i++) {
        std::string filenameOutput = std::string(argv[2])+std::string("/")+std::string("File_")+std::to_string(i)+std::string(".dcm");
        resampledFileNames.push_back(filenameOutput);
    }
    
    sitk::ImageSeriesWriter writer;
    writer.SetFileNames(resampledFileNames);
    
    writer.Execute(image);
    
    return 0;
}

Hello @nppatt,

Please take a look at this example on read-the-docs. It is available in Python and R but should be readily translatable for your C++ needs.

1 Like