[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