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

Sarthak P scapegoat.sarthak at gmail.com
Thu Mar 9 10:26:47 EST 2017


So the thing is that even the origin isn't picked up when reading the DICOM
image (it is always 0,0,0) so I am guessing I am doing something wrong when
writing into the tag 0020|0032 itself. Once that is rectified, the spacing
information (should) correct itself.

Best,
Sarthak

On Thu, Mar 9, 2017 at 10:25 AM, Sarthak P <scapegoat.sarthak at gmail.com>
wrote:

> Hi Matt,
>
> Yes I do know that. I have tried to put the spacing information from the
> itk::Image using various combinations with the tags 0018|0088 (slice
> thickness) and 0018|0050 (spacing between slices) but to no avail.
>
> Thanks for your help,
> Sarthak
>
> On Thu, Mar 9, 2017 at 9:47 AM, Matt McCormick <matt.mccormick at kitware.com
> > wrote:
>
>> HI Sarthak,
>>
>> The slice thickness is different from the spacing between slices. In
>> DICOM, slice thickness is related to the point spread function of the
>> imaging system and slice spacing is related to digital sampling.
>>
>> Hope this helps,
>> Matt
>>
>> On Thu, Mar 9, 2017 at 9:30 AM, Sarthak P <scapegoat.sarthak at gmail.com>
>> wrote:
>> > Hi Matt,
>> >
>> > Thanks for the response.
>> >
>> > I don't think I am having issues with writing into the tags since I am
>> able
>> > to read the correct information I am writing (for instance, the tag
>> > "0020|0032" is always populated with the physical coordinate of the
>> specific
>> > slice in a correct manner both during writing and reading). In an
>> example,
>> > the slice thickness should be "2" and the separation between the dicom
>> > slices is "2", which is correct. But when ITK is reading this
>> collection, it
>> > keeps the slice thickness at "1". I am seeing the same behavior in other
>> > applications as well (ITK-SNAP, etc.).
>> >
>> > Could there be some tag I am missing to write? Since my last post, I
>> tried
>> > writing only to the tag "0020|0032"; the output dictionary array gets
>> > populated properly but the file is still not written as expected. I am
>> using
>> > ITK 4.11, BTW.
>> >
>> > Best,
>> > Sarthak
>> >
>> > On Thu, Mar 9, 2017 at 9:20 AM, Matt McCormick <
>> matt.mccormick at kitware.com>
>> > wrote:
>> >>
>> >> 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
>> >> >
>> >
>> >
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/community/attachments/20170309/dbbdb1ba/attachment.html>
-------------- next part --------------
_____________________________________
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 Community mailing list