[Insight-users] z-axis ImagePositionPatient information lost on DICOM series write

Alexandre GOUAILLARD agouaillard at gmail.com
Tue Aug 9 07:23:01 EDT 2011


Dear edward,

this is a known bug you can follow here. It should be addressed within 10 days.
https://itk.icts.uiowa.edu/jira/browse/ITK-182

regards,

alex.


On Mon, Aug 8, 2011 at 10:42 AM, Somer, Edward <edward.somer at kcl.ac.uk> wrote:
> Dear All,
>
> I'm trying to write a DICOM series using ImageSeriesWriter. My code is based
> upon the resampleDICOM example but I have a problem with the
> ImagePositionPatient field. The contents of each slice's metaDataDictionary
> are correct when printed to the screen but when I save and retrieve the data
> the z-axis value is zero for all slices. Other values, such as slice
> location are stored correctly.
>
> I hare ITK-3.20.0, GDCM-2.0.14, I build within the Qt development
> environment with min-gw on 64-bit Ubuntu.
>
> I've been chewing it over for a week. Can anybody help?
>
> The offending code is below.
>
> Thanks,
>
> Ed
>
> Typedefs
>
>    typedef signed short int OutputPixelType;
>    typedef itk::Image<OutputPixelType, 3> OutputImageType;
>    typedef itk::Image<OutputPixelType, 2> OutputImage2DType;
>    typedef itk::ShiftScaleImageFilter<ImageType, OutputImageType>
> ShiftScaleFilterType;
>    typedef itk::ImageSeriesWriter<OutputImageType, OutputImage2DType>
> WriterType;
>    typedef itk::GDCMImageIO ImageIOType;
>    typedef itk::MetaDataDictionary   DictionaryType;
>    typedef itk::MetaDataObject<std::string> MetaDataStringType;
>    typedef itk::NumericSeriesFileNames OutputNamesGeneratorType;
>
> Some stuff to rescale the data and cast it to signed short then...
>
>    OutputNamesGeneratorType::Pointer namesGenerator =
> OutputNamesGeneratorType::New();
>    namesGenerator->SetSeriesFormat( format.c_str() );
>    namesGenerator->SetStartIndex( 1 );
>    namesGenerator->SetEndIndex( matrixSize[2] );
>    namesGenerator->SetIncrementIndex( 1 );
>
>    itksys_ios::ostringstream sValue;
>    std::string tagkey;
>    sValue.str("");
>
>    WriterType::DictionaryArrayType dictArray;
>
>    gdcm::UIDGenerator suid;
>    std::string seriesUID = suid.Generate();
>    gdcm::UIDGenerator fuid;
>    std::string frameOfReferenceUID = fuid.Generate();
>
>    std::string studyUID;
>    std::string sopClassUID;
>    itk::ExposeMetaData<std::string>(*(gis->metaDataDictionary()),
> "0020|000d", studyUID);
>    itk::ExposeMetaData<std::string>(*(gis->metaDataDictionary()),
> "0008|0016", sopClassUID);
>
>    // Create a dictionary for each slice
>    for ( unsigned int slice=0; slice<  matrixSize[2]; slice++ ) {
>
>        WriterType::DictionaryRawPointer sliceDict = new
> WriterType::DictionaryType;
>        copyDictionary(*(gis->metaDataDictionary()), *sliceDict);
>
>        // Set the UID's for the study, series, SOP  and frame of reference
>        itk::EncapsulateMetaData<std::string>(*sliceDict,"0020|000d",
> studyUID);
>        itk::EncapsulateMetaData<std::string>(*sliceDict,"0020|000e",
> seriesUID);
>        itk::EncapsulateMetaData<std::string>(*sliceDict,"0020|0052",
> frameOfReferenceUID);
>
>        gdcm::UIDGenerator sopuid;
>        std::string sopInstanceUID = sopuid.Generate();
>        itk::EncapsulateMetaData<std::string>(*sliceDict,"0008|0018",
> sopInstanceUID);
>        itk::EncapsulateMetaData<std::string>(*sliceDict,"0002|0003",
> sopInstanceUID);
>
>  //       tagkey = "0008|0008"; // Image Type
>  //       value = "DERIVED";
>  //       itk::EncapsulateMetaData<std::string>(*sliceDict, tagkey, value);
>
>  //       tagkey = "0008|0016"; // SOP Class (.2 CT, .7 OT (secondary
> capture), .128 PT Image Storage)
>  //       value = "1.2.840.10008.5.1.4.1.1.2";
>  //       itk::EncapsulateMetaData<std::string>(*sliceDict, tagkey, value);
>
>        tagkey = "0018|0050"; // Slice Thickness
>        sValue.str("");
>        sValue<<  pixelSize.GetElement(2);
>        itk::EncapsulateMetaData<std::string>(*sliceDict, tagkey,
> sValue.str());
>
>        sValue.str("");
>        tagkey = "0020|0013"; // Image Number
>        sValue<<  (slice + 1);
>        itk::EncapsulateMetaData<std::string>(*sliceDict, tagkey,
> sValue.str() );
>
>        tagkey = "0020|0032"; // Image Position Patient
>        ImageType::IndexType index;
>        ImageType::PointType position;
>        index[0] = 0;
>        index[1] = 0;
>        index[2] = slice;
>        gis->image()->TransformIndexToPhysicalPoint(index, position);
>        sValue.str("");
>        sValue<<  position[0]<<  "\\"<<  position[1]<<  "\\"<<  position[2];
>        itk::EncapsulateMetaData<std::string>(*sliceDict, tagkey,
> sValue.str() );
>
>        sValue.str("");
>        tagkey = "0020|1041"; // Slice Location
>        sValue<<  position[2];
>        itk::EncapsulateMetaData<std::string>(*sliceDict, tagkey,
> sValue.str() );
>
>        //std::cerr<<  "Slice: "<<  slice + 1<<  " Image Position: "<<
>  position<<  std::endl;
>
>        sValue.str("");
>        tagkey = "0028|1052"; // Rescale Intercept
>        sValue<<  0;
>        itk::EncapsulateMetaData<std::string>(*sliceDict, tagkey,
> sValue.str());
>
>        sValue.str("");
>        tagkey = "0028|1053"; // Rescale Slope
>        //sValue<<  1/dataTypeScale;
>        sValue<<  1;
>        itk::EncapsulateMetaData<std::string>(*sliceDict, tagkey,
> sValue.str());
>
>        //sliceDict->Print(std::cerr);
>        dictArray.push_back(sliceDict);
>    }
>
>    WriterType::Pointer writer = WriterType::New();
>    writer->SetInput( shiftScaleFilter->GetOutput() );
>    writer->SetFileNames( namesGenerator->GetFileNames() );
>
>    ImageIOType::Pointer gdcmIO = ImageIOType::New();
>    writer->SetImageIO( gdcmIO );
>
>    writer->SetMetaDataDictionaryArray(&dictArray );
>
>    try {
>        writer->Update();
>    }
>    catch ( itk::ExceptionObject&ex ) {
>        statusBar()->showMessage( QString(ex.GetDescription()) );
>        return;
>    }
>
>    gdcmIO->Print(std::cerr);
>
> After the writer->Update the imageIO and writer looke like this...
>
> GDCMImageIO (0x1cc62a0)
>  RTTI typeinfo:   itk::GDCMImageIO
>  Reference Count: 1
>  Modified Time: 8394
>  Debug: Off
>  Observers:
>    none
>  AbortGenerateData: Off
>  Progress: 0
>  FileName:
>  FileType: Binary
>  ByteOrder: LittleEndian
>  IORegion:
>    ImageIORegion (0x1cc6330)
>      Dimension: 2
>      Index: 0 0
>      Size: 0 0
>  Number of Components/Pixel: 1
>  Pixel Type: scalar
>  Component Type: unknown
>  Dimensions: ( 0 0 0 )
>  Origin: ( 0 0 0 )
>  UseCompression: Off
>  UseStreamedReading: Off
>  UseStreamedWriting: Off
>  Internal Component Type: unknown
>  RescaleSlope: 1
>  RescaleIntercept: 0
>  MaxSizeLoadEntry: 4095
>  KeepOriginalUID:Off
>  UIDPrefix: 1.2.826.0.1.3680043.2.1125.1
>  StudyInstanceUID:
>  SeriesInstanceUID:
>  FrameOfReferenceInstanceUID:
>  LoadSequences:1
>  LoadPrivateTags:1
>  CompressionType:1
>  Patient Name:
>  Patient ID:
>  Patient Sex:
>  Patient Age:
>  Study ID:
>  Patient DOB:
>  Study Description:
>  Body Part:
>  Number Of Series In Study:
>  Number Of Study Related Series:
>  Study Date:
>  Modality:
>  Manufacturer:
>  Institution Name:
>  Model:
>  Scan Options:
> ImageSeriesWriter (0x1b24240)
>  RTTI typeinfo:   itk::ImageSeriesWriter<itk::Image<short, 3u>,
> itk::Image<short, 2u> >
>  Reference Count: 1
>  Modified Time: 8397
>  Debug: Off
>  Observers:
>    none
>  Number Of Required Inputs: 0
>  Number Of Required Outputs: 0
>  Number Of Threads: 8
> WARNING: In
> /usr/local/InsightToolkit-3.20.0/Code/Common/itkProcessObject.cxx, line 518
> ImageSeriesWriter (0x1b24240): Output doesn't exist!
>
>  ReleaseDataFlag: Off
>  ReleaseDataBeforeUpdateFlag: On
>  Input 0: (0x1555020)
>  No Output
>  AbortGenerateData: Off
>  Progress: 1
>  Multithreader:
>    RTTI typeinfo:   itk::MultiThreader
>    Reference Count: 1
>    Modified Time: 8380
>    Debug: Off
>    Observers:
>      none
>    Thread Count: 8
>    Global Maximum Number Of Threads: 128
>    Global Default Number Of Threads: 8
>  Image IO: GDCMImageIO (0x1a759b0)
>  RTTI typeinfo:   itk::GDCMImageIO
>  Reference Count: 4
>  Modified Time: 14913
>  Debug: Off
>  Observers:
>    none
>  AbortGenerateData: Off
>  Progress: 0
>  FileName: /home/eds/DICOM/image325.dcm
>  FileType: Binary
>  ByteOrder: LittleEndian
>  IORegion:
>    ImageIORegion (0x1a75a40)
>      Dimension: 2
>      Index: 0 0
>      Size: 512 512
>  Number of Components/Pixel: 1
>  Pixel Type: scalar
>  Component Type: short
>  Dimensions: ( 512 512 )
>  Origin: ( -349.316 -508.316 )
>  UseCompression: Off
>  UseStreamedReading: On
>  UseStreamedWriting: Off
>  Internal Component Type: unknown
>  RescaleSlope: 1
>  RescaleIntercept: 0
>  MaxSizeLoadEntry: 4095
>  KeepOriginalUID:Off
>  UIDPrefix: 1.2.826.0.1.3680043.2.1125.1
>  StudyInstanceUID:
> 1.2.826.0.1.3680043.2.1125.1.51189139806629899025040847923657328
>  SeriesInstanceUID:
> 1.2.826.0.1.3680043.2.1125.1.59002386129002343896766337658152548
>  FrameOfReferenceInstanceUID:
> 1.2.826.0.1.3680043.2.1125.1.63454546757695454502945692527374226
>  LoadSequences:1
>  LoadPrivateTags:1
>  CompressionType:1
>  Patient Name:ANON218197005250
>  Patient ID:ANON218197005250
>  Patient Sex:M
>  Patient Age:042Y
>  Study ID:ANON218197005250
>  Patient DOB:
>  Study Description:PET-halvkropp
>  Body Part:
>  Number Of Series In Study:
>  Number Of Study Related Series:
>  Study Date:20100519
>  Modality:CT
>  Manufacturer:SIEMENS
>  Institution Name:
>  Model:HERMES Workstation
>  Scan Options:
>  StartIndex: 1
>  IncrementIndex: 1
>  SeriesFormat: %d
>  MetaDataDictionaryArray: 0x7ffffd704010
>  Compression: Off
>
> --
> Edward Somer, PhD.
> Senior PET Methodologist
> The PET Imaging Centre
> St Thomas' Hospital
> London, UK
> SE1 7EH
>
> work tel: +44 (0) 20 7188 1497
> work fax: +44 (0) 20 7620 0790
> e-mail: Edward.Somer at kcl.ac.uk / Edward.Somer at googlemail.com
>
> _____________________________________
> 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.html
>
> 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://www.itk.org/mailman/listinfo/insight-users
>


More information about the Insight-users mailing list