Hi.<div><br></div><div>In my group are working with ITK 4 in order to detect ROIs in high resolution CTs from LIDC database using fuzzy clustering algorithms.</div><div><br></div><div>We are having the same problem reported by Mr. Srna. When we write a DICOM series the value of z in Image Patient Position (0020,0032) is always fixed to zero, ignoring the correct value.</div>
<div><br></div><div>We tested this problem using the example DIcomSeriesReadSeriesWrite and the result is the same reported.</div><div><br></div><div>We, also, debug the code and we believe the problem could be located in the itkGDCMImageIO.cxx.</div>
<div><br></div><div>Can someone help with this problem?</div><div><br></div><div>Thanks in advance. All help is appreciated.</div><div><br></div><div>Best regards.</div><div><br></div><div>Alberto Rey</div><div>Dept. of Information and Communications Technologies</div>
<div>Faculty of Computer Science</div><div>University of A Coruna</div><div><br><div class="gmail_quote">2011/4/14 Bc. Michal Srna <span dir="ltr"><<a href="mailto:michal@srna.info">michal@srna.info</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hello,<br><br>I have used part of this code to generate MetaDataDictionary:<br><br><a href="http://www.itk.org/Wiki/ITK/Examples/DICOM/ResampleDICOM" target="_blank">http://www.itk.org/Wiki/ITK/Examples/DICOM/ResampleDICOM</a><br>
<br>Everything works, as I need, but I have just one problem in part regarding saving Image Position (origin) for "z" axis. "x,y" are stored well, but "z" value of Image Position is 0.<br>
<br>Here is that part of the code for saving the Image position:<br><br> ImageType::PointType position;<br> ImageType::IndexType index;<br> index[0] = 0;<br>
index[1] = 0;<br> index[2] = f;<br> reader->GetOutput()->TransformIndexToPhysicalPoint(index, position);<br> <br> value.str("");<br>
value << position[0] << "\\" << position[1] << "\\" << position[2];<br><br> itk::EncapsulateMetaData<std::string>(*dict,"0020|0032", value.str()); //WHY NOT WORKING??<br>
<br>position[2] contains the correct value, but I don't know, why is that value not saved and instead of that value is stored just 0?<br><br>I think I should add also the whole code for generating my MetaDataDictionary for see my problem in context.<br>
<br>At first it opens original data, from which I read original meta data. Then I modify some parts of those meta data in for cycle creating meta data for each slice. <br><br>I confirmed, that original data contains correct value of Image Position in "z" axis. But I need to recalculate that value and store new value. Problem is, as I told, that this value is not saved and instead of it, there is just 0.<br>
<br>Here is the whole code, spacing[x] is derived from other part of the whole code, I don't want to copy here:<br><br>/*opening original data for getting meta data dictionry for saving it into output 2D series files*/<br>
typedef itk::GDCMImageIO ImageIOType;<br> typedef itk::GDCMSeriesFileNames NamesGeneratorType;<br> typedef itk::ImageSeriesReader< ImageType > ReaderType;<br><br> ImageIOType::Pointer gdcmIO = ImageIOType::New();<br>
ReaderType::Pointer reader = ReaderType::New();<br><br> NamesGeneratorType::Pointer namesGenerator = NamesGeneratorType::New();<br> namesGenerator->SetInputDirectory( StudyFolderName );<br>
const ReaderType::FileNamesContainer & filenames = namesGenerator->GetInputFileNames();<br> <br> reader->SetImageIO( gdcmIO );<br> reader->SetFileNames( filenames );<br><br>
reader->Update();<br> <br> /*creating MetaDataDictionary for each slice*/<br> <br> /*Copy the dictionary from the first image and override slice specific fields*/<br> ReaderType::DictionaryRawPointer inputDictionary = (*(reader->GetMetaDataDictionaryArray()))[0];<br>
ReaderType::DictionaryArrayType dictionaryOutputArray;<br><br> /*To keep the new series in the same study as the original we need to keep the same study UID. But we need new series and frame of reference UID's.*/<br>
#if ITK_VERSION_MAJOR >= 4<br> gdcm::UIDGenerator suid;<br> std::string seriesUID = suid.Generate();<br> gdcm::UIDGenerator fuid;<br> std::string frameOfReferenceUID = fuid.Generate();<br>
#else<br> std::string seriesUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());<br> std::string frameOfReferenceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());<br>
#endif<br> std::string studyUID;<br> std::string sopClassUID;<br> itk::ExposeMetaData<std::string>(*inputDictionary, "0020|000d", studyUID);<br>
itk::ExposeMetaData<std::string>(*inputDictionary, "0008|0016", sopClassUID);<br> gdcmIO->KeepOriginalUIDOn();<br> <br> for (unsigned int f = 0; f < size[2]; f++)<br>
{<br> // Create a new dictionary for this slice<br> ReaderType::DictionaryRawPointer dict = new ReaderType::DictionaryType;<br> <br> // Copy the dictionary from the first slice<br>
CopyDictionary (*inputDictionary, *dict);<br> <br> // Set the UID's for the study, series, SOP and frame of reference<br> itk::EncapsulateMetaData<std::string>(*dict,"0020|000d", studyUID);<br>
itk::EncapsulateMetaData<std::string>(*dict,"0020|000e", seriesUID);<br> itk::EncapsulateMetaData<std::string>(*dict,"0020|0052", frameOfReferenceUID);<br>
<br> #if ITK_VERSION_MAJOR >= 4<br> gdcm::UIDGenerator sopuid;<br> std::string sopInstanceUID = sopuid.Generate();<br> #else<br>
std::string sopInstanceUID = gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());<br> #endif<br> itk::EncapsulateMetaData<std::string>(*dict,"0008|0018", sopInstanceUID);<br>
itk::EncapsulateMetaData<std::string>(*dict,"0002|0003", sopInstanceUID);<br><br> // Change fields that are slice specific<br> itksys_ios::ostringstream value;<br>
value.str("");<br> value << f + 1;<br><br> // Image Number<br> itk::EncapsulateMetaData<std::string>(*dict,"0020|0013", value.str());<br>
<br> // Series Description - Append new description to current series description<br> std::string oldSeriesDesc;<br> itk::ExposeMetaData<std::string>(*inputDictionary, "0008|103e", oldSeriesDesc);<br>
<br> value.str("");<br> value << oldSeriesDesc<br> << spacing[0] << ", " <br> << spacing[1] << ", " <br>
<< spacing[2];<br><br> // This is an long string and there is a 64 character limit in the standard<br> unsigned lengthDesc = value.str().length();<br>
<br> std::string seriesDesc( value.str(), 0,<br> lengthDesc > 64 ? 64<br> : lengthDesc);<br> itk::EncapsulateMetaData<std::string>(*dict,"0008|103e", seriesDesc);<br>
<br> // Series Number<br> value.str("");<br> value << 1001;<br> itk::EncapsulateMetaData<std::string>(*dict,"0020|0011", value.str());<br>
<br> //Image Position Patient: This is calculated by computing the physical coordinate of the first pixel in each slice.<br> ImageType::PointType position;<br> ImageType::IndexType index;<br>
index[0] = 0;<br> index[1] = 0;<br> index[2] = f;<br> reader->GetOutput()->TransformIndexToPhysicalPoint(index, position);<br>
<br> value.str("");<br> value << position[0] << "\\" << position[1] << "\\" << position[2];<br>
<br> itk::EncapsulateMetaData<std::string>(*dict,"0020|0032", value.str()); //WHY NOT WORKING??<br><br> // Slice Location: For now, we store the z component of the Image Position Patient.<br>
value.str("");<br> value << position[2];<br> itk::EncapsulateMetaData<std::string>(*dict,"0020|1041", value.str()); <br>
<br> // Spacing Between Slices<br> value.str("");<br> value << spacing[2];<br> itk::EncapsulateMetaData<std::string>(*dict,"0018|0088", value.str());<br>
<br> // Change specific values<br> // itk::EncapsulateMetaData<std::string>(*dict, "0028|0100", "16" );<br><br><br> // Save the dictionary<br>
dictionaryOutputArray.push_back(dict);<br> }<br><br>Thanks guys in advance...<br clear="all"><font color="#888888"><br>-- <br>S pozdravem Bc. Michal Srna<br><br>Fotografické portfolio:<br>
<a href="http://michalsrna.cz" target="_blank">http://michalsrna.cz</a><br>
</font><br>_____________________________________<br>
Powered by <a href="http://www.kitware.com" 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" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Kitware offers ITK Training Courses, for more information visit:<br>
<a href="http://www.kitware.com/products/protraining.html" target="_blank">http://www.kitware.com/products/protraining.html</a><br>
<br>
Please keep messages on-topic and check the ITK FAQ at:<br>
<a href="http://www.itk.org/Wiki/ITK_FAQ" target="_blank">http://www.itk.org/Wiki/ITK_FAQ</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="http://www.itk.org/mailman/listinfo/insight-users" target="_blank">http://www.itk.org/mailman/listinfo/insight-users</a><br>
<br></blockquote></div><br></div>