[ITK-users] Writing a DICOM file while preserving input image properties

Matt McCormick matt.mccormick at kitware.com
Thu Mar 9 09:20:49 EST 2017


Hi Sarthak,

DICOM export requires improved typing to produce a valid set of tags.
This work has been started here:

  https://github.com/KitwareMedical/ITKDICOM

but the implementation is in initial stages. I would be happy to
provide guidance if you would like to move it forward.

Thanks,
Matt

On Wed, Mar 8, 2017 at 3:11 PM, Sarthak P <scapegoat.sarthak at gmail.com> wrote:
> Hello All,
>
> I am trying to write a DICOM image but I want to preserve the properties
> from the input image (origin, direction, spacing, etc.). The ITK examples do
> not show how to do this properly and anything I have done with the dicom
> tags hasn't worked. Any help would be much appreciated.
>
> Here is what I have so far:
>
> //////////
>   const std::string dataDir = argv[1];
>   const std::string inputFile = dataDir + "/inputImage.nii.gz";
>   const std::string outputDir = dataDir + "/test/";
>
>   using ImageTypeToRead = itk::Image< float, 3 >;
>   using ImageTypeToWrite = itk::Image< short, 3 >;
>   auto inputImage = cbica::ReadImageWithOrientFix< itk::Image< float, 3 >
>>(inputFile);
>   auto imageToWrite = inputImage;
>
>   auto dicomIO = itk::GDCMImageIO::New();
>
>   auto seriesWriter = itk::ImageSeriesWriter< ImageTypeToWrite,
> itk::Image<ImageTypeToWrite::PixelType, 2> >::New();
>
>   auto namesGenerator = itk::NumericSeriesFileNames::New();
>   auto start = imageToWrite->GetLargestPossibleRegion().GetIndex();
>   auto size = imageToWrite->GetLargestPossibleRegion().GetSize();
>   namesGenerator->SetSeriesFormat((outputDir + "/image%03d.dcm").c_str());
>   namesGenerator->SetStartIndex(start[2]);
>   namesGenerator->SetEndIndex(start[2] + size[2] - 1);
>   namesGenerator->SetIncrementIndex(1);
>
>   auto castFilter = itk::CastImageFilter<ImageTypeToRead,
> ImageTypeToWrite>::New();
>   castFilter->SetInput(imageToWrite);
>   castFilter->Update();
>
>   seriesWriter->SetInput(castFilter->GetOutput());
>   seriesWriter->SetImageIO(dicomIO);
>   seriesWriter->SetFileNames(namesGenerator->GetFileNames());
>
>   typename itk::ImageSeriesReader< ImageTypeToRead >::DictionaryArrayType
> outputArray;
>
>   // this doesn't work at all - was kind of hoping it would do the heavy
> lifting for me
>   //dicomIO->SetOrigin(0, imageToWrite->GetOrigin()[0]);
>   //dicomIO->SetOrigin(1, imageToWrite->GetOrigin()[1]);
>   //dicomIO->SetOrigin(2, imageToWrite->GetOrigin()[2]);
>   //dicomIO->SetSpacing(0, imageToWrite->GetSpacing()[0]);
>   //dicomIO->SetSpacing(1, imageToWrite->GetSpacing()[1]);
>   //dicomIO->SetSpacing(2, imageToWrite->GetSpacing()[2]);
>   //dicomIO->SetDimensions(0,
> imageToWrite->GetLargestPossibleRegion().GetSize()[0]);
>   //dicomIO->SetDimensions(1,
> imageToWrite->GetLargestPossibleRegion().GetSize()[1]);
>   //dicomIO->SetDimensions(2,
> imageToWrite->GetLargestPossibleRegion().GetSize()[2]);
>   // this doesn't work at all
>
>   for (size_t i = 0; i <
> imageToWrite->GetLargestPossibleRegion().GetSize()[2]; i++)
>   {
>     auto dict = new itk::ImageSeriesReader< ImageTypeToRead
>>::DictionaryType;
>     typename ImageTypeToWrite::PointType position;
>     typename ImageTypeToWrite::IndexType index;
>     index[0] = 0;
>     index[1] = 0;
>     index[2] = i;
>     imageToWrite->TransformIndexToPhysicalPoint(index, position);
>     // tags extracted from dicom lookup http://dicomlookup.com/lookup.asp
>     itk::EncapsulateMetaData<std::string>(*dict, "0020|0032",
> std::to_string(position[0]) + "\\" + std::to_string(position[1]) + "\\" +
> std::to_string(position[2])); // patient position
>     itk::EncapsulateMetaData<std::string>(*dict, "0018|5100",
> std::to_string(position[0]) + "\\" + std::to_string(position[1]) + "\\" +
> std::to_string(position[2]));
>     itk::EncapsulateMetaData<std::string>(*dict, "2020|0010",
> std::to_string(position[0]) + "\\" + std::to_string(position[1]) + "\\" +
> std::to_string(position[2]));
>     itk::EncapsulateMetaData<std::string>(*dict, "0018|5101",
> std::to_string(position[0]) + "\\" + std::to_string(position[1]) + "\\" +
> std::to_string(position[2]));
>     itk::EncapsulateMetaData<std::string>(*dict, "0018|0050",
> std::to_string(imageToWrite->GetSpacing()[2])); // Slice Thickness
>     itk::EncapsulateMetaData<std::string>(*dict, "0018|0088",
> std::to_string(imageToWrite->GetSpacing()[2])); // Spacing Between Slices
>     itk::EncapsulateMetaData<std::string>(*dict, "0008|0008",
> "DERIVED\\SECONDARY"); // Image Type
>     itk::EncapsulateMetaData<std::string>(*dict, "0008|0064", "DV"); //
> Conversion Type
>
>     outputArray.push_back(dict);
>   }
>
>   seriesWriter->SetMetaDataDictionaryArray(&outputArray); // no dictionary
> information present without seriesReader
>
>   try
>   {
>     seriesWriter->Write();
>   }
>   catch (itk::ExceptionObject &e)
>   {
>     std::cerr << "Error occurred while trying to write the image '" <<
> outputDir << "': " << e.what() << "\n";
>     exit(EXIT_FAILURE);
>   }
>
> //////////
>
> Thanks a ton,
> Sarthak
>
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.php
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://public.kitware.com/mailman/listinfo/insight-users
>


More information about the Insight-users mailing list