[Insight-users] Converting NIfTI volume to dcm series using ImageReadDicomSeriesWrite.cxx

Jason.Dowling at csiro.au Jason.Dowling at csiro.au
Mon Mar 1 02:07:07 EST 2010


Hi,

I'm trying to convert a (generated) CT NIfTi volume to a .dcm series and have an annoying problem:.  The .nii volume has been pixel type of unsigned short.   I am trying to write an intensity range between 0-2510 (and then update the rescale intercept tag to -1024).  ImageReadDicomSeriesWrite compiles and runs without problems, however the image data in the output .dcm files is always truncated to 8 bits.  Any tags I specify seem to be ignored (eg. "0008|0060" Modality  or "0028|1052" rescale intercept.  I'm using itk-3.16.0 and I've used both the itk gdcm and also my local build of gdcm2 (2.0.12).

Here is the code:

/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: ImageReadDicomSeriesWrite.cxx,v $
  Language:  C++
  Date:      $Date: 2009-03-17 20:36:50 $
  Version:   $Revision: 1.2 $

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

#include "itkGDCMImageIO.h"
#include "itkNumericSeriesFileNames.h"
#include "itkImageFileReader.h"
#include "itkImageSeriesWriter.h"
#include "itkMetaDataObject.h"

#include <vector>
#include <itksys/SystemTools.hxx>

//  Software Guide : BeginLatex
//
//  This example illustrates how to read a 3D image from a non DICOM file and write it as a series of DICOM slices.
//  with some changed header information. Header
//  
//  Please note that modifying the content of a DICOM header is a very risky
//  operation. The Header contains fundamental information about the patient
//  and therefore its consistency must be protected from any data corruption.
//  Before attempting to modify the DICOM headers of your files, you must make
//  sure that you have a very good reason for doing so, and that you can ensure
//  that this information change will not result in a lower quality of health
//  care to be delivered to the patient.
//
//  \index{DICOM!Writing Series}
//
//  Software Guide : EndLatex 


int main( int argc, char* argv[] )
{

  if( argc < 3 )
    {
    std::cerr << "Usage: " << argv[0];
    std::cerr << "InputImage  OutputDicomDirectory" << std::endl;
    return EXIT_FAILURE;
    }


  typedef signed short       PixelType;
    const unsigned int      Dimension = 3;

  //typedef float    OutputPixelType;
  typedef signed short   OutputPixelType;
    const unsigned int      OutputDimension = 2;

  
  typedef itk::Image< PixelType, Dimension >      ImageType;
  typedef itk::ImageFileReader< ImageType >       ReaderType;

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

  reader->SetFileName( argv[1] );

  try
    {
    reader->Update();
    }
  catch (itk::ExceptionObject &excp)
    {
    std::cerr << "Exception thrown while writing the image" << std::endl;
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
    }

  typedef itk::GDCMImageIO                        ImageIOType;
  typedef itk::NumericSeriesFileNames             NamesGeneratorType;

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

  const char * outputDirectory = argv[2];

  itksys::SystemTools::MakeDirectory( outputDirectory );



  typedef itk::Image< OutputPixelType, OutputDimension >    Image2DType;

  typedef itk::ImageSeriesWriter< 
                         ImageType, Image2DType >  SeriesWriterType;

		 
			 
  NamesGeneratorType::Pointer namesGenerator = NamesGeneratorType::New();

  
  itk::MetaDataDictionary & dict = gdcmIO->GetMetaDataDictionary();
  std::string tagkey, value;

  
  tagkey = "0008|0060"; // Modality   - this tag is ignored?
  value = "CT";
  itk::EncapsulateMetaData<std::string>(dict, tagkey, value );
      
  tagkey = "0008|0008"; // Image Type
  value = "DERIVED\\SECONDARY";
  itk::EncapsulateMetaData<std::string>(dict, tagkey, value);
  
  tagkey = "0010|0010"; // Patient Name
  value = "Pseudo_CT_B032";
  itk::EncapsulateMetaData<std::string>(dict, tagkey, value);
  
  tagkey = "0008|0064"; // Conversion Type
  value = "DV";
  itk::EncapsulateMetaData<std::string>(dict, tagkey, value);
  
//Tried 
//   tagkey = "0028|1052"; // Rescale Intercept
//   value = "-1024";
// //   itk::EncapsulateMetaData<std::string>(dict, tagkey, value );
// //   
//   tagkey = "0028|1053"; // 
//   value = "1";
//   itk::EncapsulateMetaData<std::string>(dict, tagkey, value );
// 
//   
  
  
/*(0028,1050) ?? (DS) [40]                                          # 2,1-n Window Center
(0028,1051) ?? (DS) [400 ]                                        # 4,1-n Window Width
(0028,1052) ?? (DS) [-1024 ]                                      # 6,1 Rescale Intercept
(0028,1053) ?? (DS) [1 ]                                          # 2,1 Rescale Slope
*/
  

  SeriesWriterType::Pointer seriesWriter = SeriesWriterType::New();

  seriesWriter->SetInput( reader->GetOutput() );
  seriesWriter->SetImageIO( gdcmIO );


  ImageType::RegionType region = 
     reader->GetOutput()->GetLargestPossibleRegion();

  ImageType::IndexType start = region.GetIndex();
  ImageType::SizeType  size  = region.GetSize();


  std::string format = outputDirectory;
  
  format += "/image%03d.dcm";

  namesGenerator->SetSeriesFormat( format.c_str() );

  namesGenerator->SetStartIndex( start[2] );
  namesGenerator->SetEndIndex( start[2] + size[2] - 1 );
  namesGenerator->SetIncrementIndex( 1 );


  seriesWriter->SetFileNames( namesGenerator->GetFileNames() );

  
  try
    {
    seriesWriter->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << "Exception thrown while writing the series " << std::endl;
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
    }


  return EXIT_SUCCESS;
}


If I use gdcmdump to check the tags I can see (0028,0100), etc are  incorrect ...

 Dicom-Meta-Information-Header
# Used TransferSyntax:
(0002,0000) UL 226                                                # 4,1 File Meta Information Group Length
(0002,0001) OB 00\01                                              # 2,1 File Meta Information Version
(0002,0002) UI [1.2.840.10008.5.1.4.1.1.7]                        # 26,1 Media Storage SOP Class UID
(0002,0003) UI [1.2.826.0.1.3680043.2.1143.144340669267.20100301165201270.354553]         # 64,1 Media Storage SOP Instance UID
(0002,0010) UI [1.2.840.10008.1.2.1]                              # 20,1 Transfer Syntax UID
(0002,0012) UI [1.2.826.0.1.3680043.2.1143.147.144.143.155.1.2.4]         # 48,1 Implementation Class UID
(0002,0013) SH [ITK/GDCM 1.2.4]                                   # 14,1 Implementation Version Name

# Dicom-Data-Set
# Used TransferSyntax: 1.2.840.10008.1.2.1
(0008,0012) DA [20100301]                                         # 8,1 Instance Creation Date
(0008,0013) TM [165201]                                           # 6,1 Instance Creation Time
(0008,0016) UI [1.2.840.10008.5.1.4.1.1.7]                        # 26,1 SOP Class UID
(0008,0018) UI [1.2.826.0.1.3680043.2.1125.1.144340669267.20100301165201270.2832]         # 64,1 SOP Instance UID
(0008,0020) DA [20100301]                                         # 8,1 Study Date
(0008,0030) TM [165201]                                           # 6,1 Study Time
(0008,0050) SH (no value)                                         # 0,1 Accession Number
(0008,0060) CS [OT]                                               # 2,1 Modality
(0008,0064) CS [SYN ]                                             # 4,1 Conversion Type
(0008,0070) LO [GDCM Factory]                                     # 12,1 Manufacturer
(0008,0080) LO [GDCM Hospital ]                                   # 14,1 Institution Name
(0008,0090) PN (no value)                                         # 0,1 Referring Physician's Name
(0010,0010) PN [GDCM^Patient]                                     # 12,1 Patient's Name
(0010,0020) LO [GDCM ID ]                                         # 8,1 Patient ID
(0010,0030) DA (no value)                                         # 0,1 Patient's Birth Date
(0010,0040) CS (no value)                                         # 0,1 Patient's Sex
(0018,1164) DS [1.718750\1.718750 ]                               # 18,2 Imager Pixel Spacing
(0020,000d) UI [1.2.826.0.1.3680043.2.1125.1.144340669267.20100301165201270.8651]         # 64,1 Study Instance UID
(0020,000e) UI [1.2.826.0.1.3680043.2.1125.1.144340669267.20100301165201270.9892]         # 64,1 Series Instance UID
(0020,0010) SH (no value)                                         # 0,1 Study ID
(0020,0011) IS (no value)                                         # 0,1 Series Number
(0020,0013) IS (no value)                                         # 0,1 Instance Number
(0020,0020) CS [L\P ]                                             # 4,2 Patient Orientation
(0020,0032) DS [-189.871994\-244.897003\0.000000]                 # 32,3 Image Position (Patient)
(0020,0037) DS [1.000000\0.000000\0.000000\0.000000\1.000000\0.000000 ]         # 54,6 Image Orientation (Patient)
(0028,0002) US 1                                                  # 2,1 Samples per Pixel
(0028,0004) CS [MONOCHROME2 ]                                     # 12,1 Photometric Interpretation
(0028,0010) US 256                                                # 2,1 Rows
(0028,0011) US 256                                                # 2,1 Columns
(0028,0030) DS [1.718750\1.718750 ]                               # 18,2 Pixel Spacing
(0028,0100) US 8                                                  # 2,1 Bits Allocated
(0028,0101) US 8                                                  # 2,1 Bits Stored
(0028,0102) US 7                                                  # 2,1 High Bit
(0028,0103) US 0                                                  # 2,1 Pixel Representation
(7fe0,0000) UL 65548                                              # 4,1 Generic Group Length



Here are the 0028 tags I want to have in my final volume but cannot set ( unless I use something like dcmodify)
(0028,0002) ?? (US) 1                                             # 2,1 Samples per Pixel
(0028,0004) ?? (CS) [MONOCHROME2 ]                                # 12,1 Photometric Interpretation
(0028,0010) ?? (US) 256                                           # 2,1 Rows
(0028,0011) ?? (US) 256                                           # 2,1 Columns
(0028,0030) ?? (DS) [1.035156\1.035156 ]                          # 18,2 Pixel Spacing
(0028,0100) ?? (US) 16                                            # 2,1 Bits Allocated
(0028,0101) ?? (US) 16                                            # 2,1 Bits Stored
(0028,0102) ?? (US) 15                                            # 2,1 High Bit
(0028,0103) ?? (US) 0                                             # 2,1 Pixel Representation
(0028,1050) ?? (DS) [40]                                          # 2,1-n Window Center
(0028,1051) ?? (DS) [400 ]                                        # 4,1-n Window Width
(0028,1052) ?? (DS) [-1024 ]                                      # 6,1 Rescale Intercept

Does anyone have suggestions or some sample code to get this working ?


Thanks,
Jason


    





More information about the Insight-users mailing list