[Insight-users] DICOM import doesn't work properly

Raphael Hoever hoever at vision.ee.ethz.ch
Wed May 10 12:20:11 EDT 2006


Hi,
I am trying to import DICOM images with ITK. I tested 
itk::DICOMImageIO2, itk::DicomImageIO and itk::GDCMImageIO for the 
import interface but no matter what I do the pixel values of the images 
are shifted by a very large number (64,512 = 11111100 00000000) and 
since the InputPixelType is unsigned short (the DICOM images allocated 
16 bit per pixel and use the lower 12 bit for the data) I observe 
overflows at high intensity values. So for instance if the original 
pixel intensity is 4095 the pixel value in the output image is (4095 + 
64512)mod216 = 3071.

I am using ITK 2.6 and the DICOM images are from a Siemens Sensation 64 
scanner.
Here is my code for reading just one DICOM image (the result is the same 
if I read the whole sequence) and exporting it as a 16 bit tif image 
(also unsigned char, so the cast filter is not mandatory):


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

 // check number of command line arguments
 if( argc < 6 ) {
   std::cerr << "Usage: " << std::endl;
   std::cerr << argv[0] << " DicomDirectory  outputFileName  factorX  
factorY  factorZ"
             << std::endl;
   return EXIT_FAILURE;
 }

 //parse command line to variables
 const char *directoryName  = argv[1];
 const char *outputFileName = argv[2];
 const double factorX = atof( argv[3] );
 const double factorY = atof( argv[4] );
 const double factorZ = atof( argv[5] );

 //set number of image dimensions
 const   unsigned int   Dimension = 3;

 //set data format of pixels
 typedef unsigned short InputPixelType;
 typedef unsigned short OutputPixelType;

 //create objects for input and output images
 typedef itk::Image< InputPixelType,    Dimension > InputImageType;
 typedef itk::Image< OutputPixelType,   Dimension > OutputImageType;

 //create reader object for image
 typedef itk::ImageFileReader< InputImageType > ReaderType;
 ReaderType::Pointer reader = ReaderType::New();

 //create IO interface for DICOM images
 typedef itk::DICOMImageIO2   ImageIOType;
 ImageIOType::Pointer dicomIO = ImageIOType::New();

 //connect reader object with DICOM IO interface
 reader->SetImageIO( dicomIO );

 //create object to generate DICOM file names
 typedef itk::GDCMSeriesFileNames NamesGeneratorType;
 NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();

 //tell nameGenerator the DICOM directory
 nameGenerator->SetDirectory( directoryName );

 try {

   std::cout << std::endl << "The directory: " << std::endl;
   std::cout << std::endl << directoryName << std::endl << std::endl;
   std::cout << "Contains the following DICOM Series: ";
   std::cout << std::endl << std::endl;
     //generate container object with DICOM series UIDs
   typedef std::vector< std::string > SeriesIdContainer;
   const SeriesIdContainer &seriesUID = nameGenerator->GetSeriesUIDs();
     //loop over DICOM series UIDs and print them
   SeriesIdContainer::const_iterator seriesItr = seriesUID.begin();
   SeriesIdContainer::const_iterator seriesEnd = seriesUID.end();
   while( seriesItr != seriesEnd ) {
     std::cout << seriesItr->c_str() << std::endl;
     seriesItr++;
   }

   //get first DICOM series UID
   std::string seriesIdentifier;
   seriesIdentifier = seriesUID.begin()->c_str();

   std::cout << std::endl << std::endl;
   std::cout << "Now reading series: " << std::endl << std::endl;
   std::cout << seriesIdentifier << std::endl;
   std::cout << std::endl << std::endl;

   //generate container with all DICOM file names of the current series
   typedef std::vector< std::string > FileNamesContainer;
   FileNamesContainer fileNames;
   fileNames = nameGenerator->GetFileNames( seriesIdentifier );

   //tell reader file names
   reader->SetFileName( fileNames.begin()->c_str() );

   //read files from disk
   try {
     reader->Update();
   }
   catch (itk::ExceptionObject &ex) {
     std::cout << ex << std::endl;
     return EXIT_FAILURE;
   }
     //create cast filter to cast inputImage into output image data 
structure
   typedef itk::CastImageFilter< InputImageType,  OutputImageType> 
CastFilterType;
   CastFilterType::Pointer caster = CastFilterType::New();

   //set input of caster to inputImage
   caster->SetInput( reader->GetOutput() );

   //create image file writer
   typedef itk::ImageFileWriter< OutputImageType > WriterType;
   WriterType::Pointer writer = WriterType::New();
     //tell writer output file name and connect it to caster
   writer->SetFileName( outputFileName );
   writer->SetInput( caster->GetOutput() );

   std::cout  << "Writing the image as " << std::endl << std::endl;
   std::cout  << outputFileName << std::endl << std::endl;
     //write output file
   try {
     writer->Update();
   }
   catch (itk::ExceptionObject &ex) {
     std::cout << ex << std::endl;
     return EXIT_FAILURE;
   }

 }
 catch (itk::ExceptionObject &ex) {
   std::cout << ex << std::endl;
   return EXIT_FAILURE;
 }

 return EXIT_SUCCESS;
}



If I use the same code (without the DICOM import interface) for 
importing tif images it works without any problems. I already thought 
about a problwm with the byte order (little endian <-> big endian) but 
this wouldn't make sense either. I would appreciate your help since I 
have no clue where that bug comes from.

Cheers,
Raphael

-------------- next part --------------
A non-text attachment was scrubbed...
Name: hoever.vcf
Type: text/x-vcard
Size: 354 bytes
Desc: not available
Url : http://public.kitware.com/pipermail/insight-users/attachments/20060510/b395669a/hoever.vcf


More information about the Insight-users mailing list