<div dir="ltr">Hi Matt,<div><br></div><div>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.</div><div><br></div><div>Thanks for your help,</div><div>Sarthak </div><div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 9, 2017 at 9:47 AM, Matt McCormick <span dir="ltr"><<a href="mailto:matt.mccormick@kitware.com" target="_blank">matt.mccormick@kitware.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">HI Sarthak,<br>
<br>
The slice thickness is different from the spacing between slices. In<br>
DICOM, slice thickness is related to the point spread function of the<br>
imaging system and slice spacing is related to digital sampling.<br>
<br>
Hope this helps,<br>
Matt<br>
<div class="gmail-HOEnZb"><div class="gmail-h5"><br>
On Thu, Mar 9, 2017 at 9:30 AM, Sarthak P <<a href="mailto:scapegoat.sarthak@gmail.com">scapegoat.sarthak@gmail.com</a>> wrote:<br>
> Hi Matt,<br>
><br>
> Thanks for the response.<br>
><br>
> I don't think I am having issues with writing into the tags since I am able<br>
> to read the correct information I am writing (for instance, the tag<br>
> "0020|0032" is always populated with the physical coordinate of the specific<br>
> slice in a correct manner both during writing and reading). In an example,<br>
> the slice thickness should be "2" and the separation between the dicom<br>
> slices is "2", which is correct. But when ITK is reading this collection, it<br>
> keeps the slice thickness at "1". I am seeing the same behavior in other<br>
> applications as well (ITK-SNAP, etc.).<br>
><br>
> Could there be some tag I am missing to write? Since my last post, I tried<br>
> writing only to the tag "0020|0032"; the output dictionary array gets<br>
> populated properly but the file is still not written as expected. I am using<br>
> ITK 4.11, BTW.<br>
><br>
> Best,<br>
> Sarthak<br>
><br>
> On Thu, Mar 9, 2017 at 9:20 AM, Matt McCormick <<a href="mailto:matt.mccormick@kitware.com">matt.mccormick@kitware.com</a>><br>
> wrote:<br>
>><br>
>> Hi Sarthak,<br>
>><br>
>> DICOM export requires improved typing to produce a valid set of tags.<br>
>> This work has been started here:<br>
>><br>
>>   <a href="https://github.com/KitwareMedical/ITKDICOM" rel="noreferrer" target="_blank">https://github.com/<wbr>KitwareMedical/ITKDICOM</a><br>
>><br>
>> but the implementation is in initial stages. I would be happy to<br>
>> provide guidance if you would like to move it forward.<br>
>><br>
>> Thanks,<br>
>> Matt<br>
>><br>
>> On Wed, Mar 8, 2017 at 3:11 PM, Sarthak P <<a href="mailto:scapegoat.sarthak@gmail.com">scapegoat.sarthak@gmail.com</a>><br>
>> wrote:<br>
>> > Hello All,<br>
>> ><br>
>> > I am trying to write a DICOM image but I want to preserve the properties<br>
>> > from the input image (origin, direction, spacing, etc.). The ITK<br>
>> > examples do<br>
>> > not show how to do this properly and anything I have done with the dicom<br>
>> > tags hasn't worked. Any help would be much appreciated.<br>
>> ><br>
>> > Here is what I have so far:<br>
>> ><br>
>> > //////////<br>
>> >   const std::string dataDir = argv[1];<br>
>> >   const std::string inputFile = dataDir + "/inputImage.nii.gz";<br>
>> >   const std::string outputDir = dataDir + "/test/";<br>
>> ><br>
>> >   using ImageTypeToRead = itk::Image< float, 3 >;<br>
>> >   using ImageTypeToWrite = itk::Image< short, 3 >;<br>
>> >   auto inputImage = cbica::ReadImageWithOrientFix< itk::Image< float, 3<br>
>> > ><br>
>> >>(inputFile);<br>
>> >   auto imageToWrite = inputImage;<br>
>> ><br>
>> >   auto dicomIO = itk::GDCMImageIO::New();<br>
>> ><br>
>> >   auto seriesWriter = itk::ImageSeriesWriter< ImageTypeToWrite,<br>
>> > itk::Image<ImageTypeToWrite::<wbr>PixelType, 2> >::New();<br>
>> ><br>
>> >   auto namesGenerator = itk::NumericSeriesFileNames::<wbr>New();<br>
>> >   auto start = imageToWrite-><wbr>GetLargestPossibleRegion().<wbr>GetIndex();<br>
>> >   auto size = imageToWrite-><wbr>GetLargestPossibleRegion().<wbr>GetSize();<br>
>> >   namesGenerator-><wbr>SetSeriesFormat((outputDir +<br>
>> > "/image%03d.dcm").c_str());<br>
>> >   namesGenerator->SetStartIndex(<wbr>start[2]);<br>
>> >   namesGenerator->SetEndIndex(<wbr>start[2] + size[2] - 1);<br>
>> >   namesGenerator-><wbr>SetIncrementIndex(1);<br>
>> ><br>
>> >   auto castFilter = itk::CastImageFilter<<wbr>ImageTypeToRead,<br>
>> > ImageTypeToWrite>::New();<br>
>> >   castFilter->SetInput(<wbr>imageToWrite);<br>
>> >   castFilter->Update();<br>
>> ><br>
>> >   seriesWriter->SetInput(<wbr>castFilter->GetOutput());<br>
>> >   seriesWriter->SetImageIO(<wbr>dicomIO);<br>
>> >   seriesWriter->SetFileNames(<wbr>namesGenerator->GetFileNames()<wbr>);<br>
>> ><br>
>> >   typename itk::ImageSeriesReader< ImageTypeToRead<br>
>> > >::DictionaryArrayType<br>
>> > outputArray;<br>
>> ><br>
>> >   // this doesn't work at all - was kind of hoping it would do the heavy<br>
>> > lifting for me<br>
>> >   //dicomIO->SetOrigin(0, imageToWrite->GetOrigin()[0]);<br>
>> >   //dicomIO->SetOrigin(1, imageToWrite->GetOrigin()[1]);<br>
>> >   //dicomIO->SetOrigin(2, imageToWrite->GetOrigin()[2]);<br>
>> >   //dicomIO->SetSpacing(0, imageToWrite->GetSpacing()[0])<wbr>;<br>
>> >   //dicomIO->SetSpacing(1, imageToWrite->GetSpacing()[1])<wbr>;<br>
>> >   //dicomIO->SetSpacing(2, imageToWrite->GetSpacing()[2])<wbr>;<br>
>> >   //dicomIO->SetDimensions(0,<br>
>> > imageToWrite-><wbr>GetLargestPossibleRegion().<wbr>GetSize()[0]);<br>
>> >   //dicomIO->SetDimensions(1,<br>
>> > imageToWrite-><wbr>GetLargestPossibleRegion().<wbr>GetSize()[1]);<br>
>> >   //dicomIO->SetDimensions(2,<br>
>> > imageToWrite-><wbr>GetLargestPossibleRegion().<wbr>GetSize()[2]);<br>
>> >   // this doesn't work at all<br>
>> ><br>
>> >   for (size_t i = 0; i <<br>
>> > imageToWrite-><wbr>GetLargestPossibleRegion().<wbr>GetSize()[2]; i++)<br>
>> >   {<br>
>> >     auto dict = new itk::ImageSeriesReader< ImageTypeToRead<br>
>> >>::DictionaryType;<br>
>> >     typename ImageTypeToWrite::PointType position;<br>
>> >     typename ImageTypeToWrite::IndexType index;<br>
>> >     index[0] = 0;<br>
>> >     index[1] = 0;<br>
>> >     index[2] = i;<br>
>> >     imageToWrite-><wbr>TransformIndexToPhysicalPoint(<wbr>index, position);<br>
>> >     // tags extracted from dicom lookup<br>
>> > <a href="http://dicomlookup.com/lookup.asp" rel="noreferrer" target="_blank">http://dicomlookup.com/lookup.<wbr>asp</a><br>
>> >     itk::EncapsulateMetaData<std::<wbr>string>(*dict, "0020|0032",<br>
>> > std::to_string(position[0]) + "\\" + std::to_string(position[1]) + "\\"<br>
>> > +<br>
>> > std::to_string(position[2])); // patient position<br>
>> >     itk::EncapsulateMetaData<std::<wbr>string>(*dict, "0018|5100",<br>
>> > std::to_string(position[0]) + "\\" + std::to_string(position[1]) + "\\"<br>
>> > +<br>
>> > std::to_string(position[2]));<br>
>> >     itk::EncapsulateMetaData<std::<wbr>string>(*dict, "2020|0010",<br>
>> > std::to_string(position[0]) + "\\" + std::to_string(position[1]) + "\\"<br>
>> > +<br>
>> > std::to_string(position[2]));<br>
>> >     itk::EncapsulateMetaData<std::<wbr>string>(*dict, "0018|5101",<br>
>> > std::to_string(position[0]) + "\\" + std::to_string(position[1]) + "\\"<br>
>> > +<br>
>> > std::to_string(position[2]));<br>
>> >     itk::EncapsulateMetaData<std::<wbr>string>(*dict, "0018|0050",<br>
>> > std::to_string(imageToWrite-><wbr>GetSpacing()[2])); // Slice Thickness<br>
>> >     itk::EncapsulateMetaData<std::<wbr>string>(*dict, "0018|0088",<br>
>> > std::to_string(imageToWrite-><wbr>GetSpacing()[2])); // Spacing Between<br>
>> > Slices<br>
>> >     itk::EncapsulateMetaData<std::<wbr>string>(*dict, "0008|0008",<br>
>> > "DERIVED\\SECONDARY"); // Image Type<br>
>> >     itk::EncapsulateMetaData<std::<wbr>string>(*dict, "0008|0064", "DV"); //<br>
>> > Conversion Type<br>
>> ><br>
>> >     outputArray.push_back(dict);<br>
>> >   }<br>
>> ><br>
>> >   seriesWriter-><wbr>SetMetaDataDictionaryArray(&<wbr>outputArray); // no<br>
>> > dictionary<br>
>> > information present without seriesReader<br>
>> ><br>
>> >   try<br>
>> >   {<br>
>> >     seriesWriter->Write();<br>
>> >   }<br>
>> >   catch (itk::ExceptionObject &e)<br>
>> >   {<br>
>> >     std::cerr << "Error occurred while trying to write the image '" <<<br>
>> > outputDir << "': " << e.what() << "\n";<br>
>> >     exit(EXIT_FAILURE);<br>
>> >   }<br>
>> ><br>
>> > //////////<br>
>> ><br>
>> > Thanks a ton,<br>
>> > Sarthak<br>
>> ><br>
>> > ______________________________<wbr>_______<br>
>> > Powered by <a href="http://www.kitware.com" rel="noreferrer" target="_blank">www.kitware.com</a><br>
>> ><br>
>> > Visit other Kitware open-source projects at<br>
>> > <a href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer" target="_blank">http://www.kitware.com/<wbr>opensource/opensource.html</a><br>
>> ><br>
>> > Kitware offers ITK Training Courses, for more information visit:<br>
>> > <a href="http://www.kitware.com/products/protraining.php" rel="noreferrer" target="_blank">http://www.kitware.com/<wbr>products/protraining.php</a><br>
>> ><br>
>> > Please keep messages on-topic and check the ITK FAQ at:<br>
>> > <a href="http://www.itk.org/Wiki/ITK_FAQ" rel="noreferrer" target="_blank">http://www.itk.org/Wiki/ITK_<wbr>FAQ</a><br>
>> ><br>
>> > Follow this link to subscribe/unsubscribe:<br>
>> > <a href="http://public.kitware.com/mailman/listinfo/insight-users" rel="noreferrer" target="_blank">http://public.kitware.com/<wbr>mailman/listinfo/insight-users</a><br>
>> ><br>
><br>
><br>
</div></div></blockquote></div><br></div></div></div>