[Insight-users] Re: Reading and writing out DICOM images

Luis Ibanez luis.ibanez at kitware.com
Tue, 30 Dec 2003 04:17:00 -0500


Hi Radhika,

The DICOMImageIO by itself can only read 2D slices.

In order to read volumes from Dicom files you should
use the ImageSeriesReader in combination with the
DICOMSeriesFileNames class.

An example has been added to the repository for
illustrating how to do this. You will find this
example under

  Insight/Examples/IO/DicomSeriesReadImageWrite.cxx

Note that this example is using "unsigned short" as
pixel type. If your Dicom files are coming from
CT they are likely of pixel type "signed short".
You may want to modify the code according to the
real encoding of your data.

The code is pasted below:

--------------------------------------------------

#include "itkDICOMImageIO2.h"
#include "itkImageSeriesReader.h"
#include "itkDICOMSeriesFileNames.h"
#include "itkImageFileWriter.h"

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

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

   typedef itk::Image<unsigned short,3>            ImageType;
   typedef itk::ImageSeriesReader< ImageType >     ReaderType;

   itk::DICOMImageIO2::Pointer dicomIO = itk::DICOMImageIO2::New();

   // Get the DICOM filenames from the directory
   itk::DICOMSeriesFileNames::Pointer nameGenerator = 
itk::DICOMSeriesFileNames::New();
   nameGenerator->SetDirectory( argv[1] );


   typedef std::vector<std::string> seriesIdContainer;
   const seriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();

   seriesIdContainer::const_iterator seriesItr = seriesUID.begin();
   seriesIdContainer::const_iterator seriesEnd = seriesUID.end();

   std::cout << std::endl << "The directory: " << std::endl;
   std::cout << std::endl << argv[1] << std::endl << std::endl;
   std::cout << "Contains the following DICOM Series: ";
   std::cout << std::endl << std::endl;

   while( seriesItr != seriesEnd )
     {
     std::cout << seriesItr->c_str() << std::endl;
     seriesItr++;
     }

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

   typedef std::vector<std::string> fileNamesContainer;
   fileNamesContainer fileNames;

   if( argc < 4 ) // If no optional third argument
     {
     std::cout << seriesUID.begin()->c_str() << std::endl;
     fileNames = nameGenerator->GetFileNames();
     }
   else
     {
     std::cout << argv[3] << std::endl;
     fileNames = nameGenerator->GetFileNames( argv[3] );
     }
   std::cout << std::endl << std::endl;

   ReaderType::Pointer reader = ReaderType::New();
   reader->SetFileNames( fileNames );
   reader->SetImageIO( dicomIO );

   try
     {
     reader->Update();
     }
   catch (itk::ExceptionObject &ex)
     {
     std::cout << ex << std::endl;
     return EXIT_FAILURE;
     }

   typedef itk::ImageFileWriter< ImageType > WriterType;
   WriterType::Pointer writer = WriterType::New();

   std::cout  << "Writing the image as " << std::endl << std::endl;
   std::cout  << argv[2] << std::endl << std::endl;

   writer->SetFileName( argv[2] );

   writer->SetInput( reader->GetOutput() );

   try
     {
     writer->Update();
     }
   catch (itk::ExceptionObject &ex)
     {
     std::cout << ex;
     return EXIT_FAILURE;
     }


   return EXIT_SUCCESS;

}



--------------------------------------------------


In order to use this program from the command line
you must provide as first argument the directory
where your DICOM slices are located, and as a second
argument the filename of the output image. In order
to produce Analyze you just need to provide an output
filename with extension ".hdr". You could produce
VTK files by using .vtk, or MetaImages by using .mhd.

Note that you may have multiple DICOM series in the
same directory. The current program will simply take
the first series.  If you want to select a particular
series you can provide the optional third parameter
with the string identifying the desired series.  If the
optional parameter is missing, this example will print
out all the available series and simply read the first
one.



Please let us know if you have further questions,


    Thanks


      Luis


---------------------------------
Radhika Sivaramakrishna wrote:
> Hi Luis,
> 
> I was trying to modify the example in the Software guide to use an 
> ImageIO class explicitly to read a DICOM series and write it out as a 3D 
> Analyze format
> 
> image. I am not sure how to specify the DICOM series in the input file 
> name. I tried giving one of the files in the sequence [this only wrote 
> out that particular slice]
> 
>  as well as tried to use a *.dcm wildcard method which gave an error. I 
> have the same doubt for writing out a DICOM series. How do I specify the 
> filename?
> 
>  
> 
> Thanks
> 
> Radhika
> 
>  
> 
> -----------------------------------------------------
> 
> Confidentiality Notice.
> 
> This email message is for the sole use of the intended recipient(s) and 
> may contain confidential and privileged information. Any unauthorized 
> review, use, disclosure or distribution is prohibited. If you are not 
> the intended recipient, please contact the sender by reply email and 
> destroy all copies of the original message. If you are the intended 
> recipient, please be advised that the content of this message is subject 
> to access, review and disclosure by the sender's Email System Administrator.
>