[Insight-users] Problem with saving Image Position value in "z" axis

Bc. Michal Srna michal at srna.info
Thu Apr 14 05:16:35 EDT 2011


Hello,

I have used part of this code to generate MetaDataDictionary:

http://www.itk.org/Wiki/ITK/Examples/DICOM/ResampleDICOM

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.

Here is that part of the code for saving the Image position:

                        ImageType::PointType position;
                        ImageType::IndexType index;
                        index[0] = 0;
                        index[1] = 0;
                        index[2] = f;

reader->GetOutput()->TransformIndexToPhysicalPoint(index, position);

                        value.str("");
                        value << position[0] << "\\" << position[1] << "\\"
<< position[2];


itk::EncapsulateMetaData<std::string>(*dict,"0020|0032", value.str()); //WHY
NOT WORKING??

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?

I think I should add also the whole code for generating my
MetaDataDictionary for see my problem in context.

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.

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.

Here is the whole code, spacing[x] is derived from other part of the whole
code, I don't want to copy here:

/*opening original data for getting meta data dictionry for saving it into
output 2D series files*/
            typedef itk::GDCMImageIO ImageIOType;
            typedef itk::GDCMSeriesFileNames NamesGeneratorType;
            typedef itk::ImageSeriesReader< ImageType > ReaderType;

            ImageIOType::Pointer gdcmIO = ImageIOType::New();
            ReaderType::Pointer reader = ReaderType::New();

            NamesGeneratorType::Pointer namesGenerator =
NamesGeneratorType::New();
            namesGenerator->SetInputDirectory( StudyFolderName );
            const ReaderType::FileNamesContainer & filenames =
namesGenerator->GetInputFileNames();

            reader->SetImageIO( gdcmIO );
            reader->SetFileNames( filenames );

            reader->Update();

        /*creating MetaDataDictionary for each slice*/

            /*Copy the dictionary from the first image and override slice
specific fields*/
                ReaderType::DictionaryRawPointer inputDictionary =
(*(reader->GetMetaDataDictionaryArray()))[0];
                ReaderType::DictionaryArrayType dictionaryOutputArray;

            /*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.*/
                #if ITK_VERSION_MAJOR >= 4
                  gdcm::UIDGenerator suid;
                  std::string seriesUID = suid.Generate();
                  gdcm::UIDGenerator fuid;
                  std::string frameOfReferenceUID = fuid.Generate();
                #else
                  std::string seriesUID = gdcm::Util::CreateUniqueUID(
gdcmIO->GetUIDPrefix());
                  std::string frameOfReferenceUID =
gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
                #endif
                  std::string studyUID;
                  std::string sopClassUID;
                  itk::ExposeMetaData<std::string>(*inputDictionary,
"0020|000d", studyUID);
                  itk::ExposeMetaData<std::string>(*inputDictionary,
"0008|0016", sopClassUID);
                  gdcmIO->KeepOriginalUIDOn();

                for (unsigned int f = 0; f < size[2]; f++)
                {
                    // Create a new dictionary for this slice
                        ReaderType::DictionaryRawPointer dict = new
ReaderType::DictionaryType;

                    // Copy the dictionary from the first slice
                        CopyDictionary (*inputDictionary, *dict);

                    // Set the UID's for the study, series, SOP  and frame
of reference

itk::EncapsulateMetaData<std::string>(*dict,"0020|000d", studyUID);

itk::EncapsulateMetaData<std::string>(*dict,"0020|000e", seriesUID);

itk::EncapsulateMetaData<std::string>(*dict,"0020|0052",
frameOfReferenceUID);

                    #if ITK_VERSION_MAJOR >= 4
                        gdcm::UIDGenerator sopuid;
                        std::string sopInstanceUID = sopuid.Generate();
                    #else
                        std::string sopInstanceUID =
gdcm::Util::CreateUniqueUID( gdcmIO->GetUIDPrefix());
                    #endif

itk::EncapsulateMetaData<std::string>(*dict,"0008|0018", sopInstanceUID);

itk::EncapsulateMetaData<std::string>(*dict,"0002|0003", sopInstanceUID);

                    // Change fields that are slice specific
                        itksys_ios::ostringstream value;
                        value.str("");
                        value << f + 1;

                    // Image Number

itk::EncapsulateMetaData<std::string>(*dict,"0020|0013", value.str());

                    // Series Description - Append new description to
current series description
                        std::string oldSeriesDesc;
                        itk::ExposeMetaData<std::string>(*inputDictionary,
"0008|103e", oldSeriesDesc);

                        value.str("");
                        value << oldSeriesDesc
                              << spacing[0] << ", "
                              << spacing[1] << ", "
                              << spacing[2];

                    // This is an long string and there is a 64 character
limit in the standard
                        unsigned lengthDesc = value.str().length();

                        std::string seriesDesc( value.str(), 0,
                                                lengthDesc > 64 ? 64
                                                : lengthDesc);

itk::EncapsulateMetaData<std::string>(*dict,"0008|103e", seriesDesc);

                    // Series Number
                        value.str("");
                        value << 1001;

itk::EncapsulateMetaData<std::string>(*dict,"0020|0011", value.str());

                    //Image Position Patient: This is calculated by
computing the physical coordinate of the first pixel in each slice.
                        ImageType::PointType position;
                        ImageType::IndexType index;
                        index[0] = 0;
                        index[1] = 0;
                        index[2] = f;

reader->GetOutput()->TransformIndexToPhysicalPoint(index, position);

                        value.str("");
                        value << position[0] << "\\" << position[1] << "\\"
<< position[2];


itk::EncapsulateMetaData<std::string>(*dict,"0020|0032", value.str()); //WHY
NOT WORKING??

                    // Slice Location: For now, we store the z component of
the Image Position Patient.
                        value.str("");
                        value << position[2];

itk::EncapsulateMetaData<std::string>(*dict,"0020|1041", value.str());

                    // Spacing Between Slices
                        value.str("");
                        value << spacing[2];

itk::EncapsulateMetaData<std::string>(*dict,"0018|0088", value.str());

                    // Change specific values
                        //  itk::EncapsulateMetaData<std::string>(*dict,
"0028|0100", "16" );


                    // Save the dictionary
                        dictionaryOutputArray.push_back(dict);
                  }

Thanks guys in advance...

-- 
S pozdravem Bc. Michal Srna

Fotografické portfolio:
http://michalsrna.cz
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20110414/b98e1324/attachment.htm>


More information about the Insight-users mailing list