[ITK] [ITK-users] Writing a DICOM file while preserving input image properties
Sarthak P
scapegoat.sarthak at gmail.com
Thu Mar 9 10:54:06 EST 2017
Found recorded bugs related to this:
https://issues.itk.org/jira/browse/ITK-3176 (spacing)
https://issues.itk.org/jira/browse/ITK-3407 (origin)
Guess we wait and watch.
Thanks a ton for your help,
Sarthak
On Thu, Mar 9, 2017 at 10:26 AM, Sarthak P <scapegoat.sarthak at gmail.com>
wrote:
> 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/7369d117/attachment-0001.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