[Insight-users] AnalyzeIO and TIFFIO for 2D images (ITK 3.0)

Tom Vercauteren tom.vercauteren at m4x.org
Wed Dec 27 04:17:05 EST 2006


Hi Julien,

In fact, you can also use an ImageIOBase object to get the information
about the image you want to read. This can then be used in a switch.

I have put such a code here. It simply reads an input image and write
it to an output file.

Best,
Tom


%%%%%%%%%%%%%%%%%%
% Sample Code
%%%%%%%%%%%%%%%%%%

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

#include <getopt.h>
#include <iostream>

struct arguments
{
   std::string  inputImageFile;  /* -i option */
   std::string  outputImageFile; /* -o option */

   arguments () :
      inputImageFile(""),
      outputImageFile("output-image.mha")
   {
   }

   friend std::ostream& operator<< (std::ostream& o,
                                    const arguments& args)
   {
      return o
         <<"Arguments structure:"<<std::endl
         <<"  Input image file: "<<args.inputImageFile<<std::endl
         <<"  Output image file: "<<args.outputImageFile<<std::endl;
   }
};

static const char *optString = "i:o:h?";

static const struct option longOpts[] = {
   { "input-image", required_argument, NULL, 'i' },
   { "output-image", optional_argument, NULL, 'o' },
   { "help", no_argument, NULL, 'h' },
   { NULL, no_argument, NULL, 0 }
};

/* Display program usage, and exit.
 */
void display_usage( const std::string progname )
{
   struct arguments defargs = arguments();

   std::cout<<std::endl;
   std::cout<<progname<<" - Process an image"<<std::endl;
   std::cout<<"Usage: "<<progname<<" [OPTION...]"<<std::endl;

   std::cout<<"  -i/--input-image=STRING    Input image filename - mandatory"
            <<std::endl;
   std::cout<<"  -o/--output-image=STRING   Output image filename - default: "
            <<defargs.outputImageFile<<std::endl;

   std::cout<<"  -h/--help                  Display this message and exit"
            <<std::endl;

   std::cout<<std::endl;

	exit( EXIT_FAILURE );
}



void parseOpts (int argc, char **argv, struct arguments & args)
{
   const std::string progname("ITKTestProgram");

   if (argc == 1)
   {
      display_usage(progname);
   }

   // Default values.
   args = arguments();

   int opt = 0; /* it's actually going to hold a char */
   int longIndex = 0;

   while ( (opt = getopt_long(argc, argv, optString,
                              longOpts, &longIndex)) != -1 )
   {
      switch( opt ) {
      case 'i':
         if (! optarg) display_usage(progname);
         args.inputImageFile = optarg;
         break;

      case 'o':
         if (! optarg) display_usage(progname);
         args.outputImageFile = optarg;
         break;

      case '?':   /* fall-through is intentional */
         std::cout<<"Invalid option"<<std::endl<<std::endl;
      case 'h':	/* fall-through is intentional */
      default:
         display_usage(progname);
         break;
		}
   }

   // Check if the user provided an input image
   if ( args.inputImageFile.empty() )
   {
      std::cout<<"You need to provide an input image"
               <<std::endl<<std::endl;
      display_usage(progname);
   }

   // Sanity check: Check if the output image file is not empty
   if ( args.outputImageFile.empty() )
   {
      std::cout<<"The output image name should not be empty"
               <<std::endl<<std::endl;
      display_usage(progname);
   }
}




template <class InputPixelType, unsigned int Dimension>
void ProcessingFunction( arguments args )
{
   // Some typedefs
   typedef itk::Image< InputPixelType, Dimension > ImageType;

   // Set up the file readers
   typedef typename itk::ImageFileReader< ImageType > ImageReaderType;

   typename ImageReaderType::Pointer imageReader
      = ImageReaderType::New();

   imageReader->SetFileName( args.inputImageFile.c_str() );

   // Update the reader
   try
   {
      imageReader->Update();
   }
   catch( itk::ExceptionObject& err )
   {
      std::cout << "Could not read the input image." << std::endl;
      std::cout << err << std::endl;
      exit( EXIT_FAILURE );
   }

   typename ImageType::Pointer inputImage = imageReader->GetOutput();


   //Do the processing here
   typename ImageType::Pointer outputImage = inputImage;


   // Write image to file
   typedef itk::ImageFileWriter< ImageType >  WriterType;
   typename WriterType::Pointer writer =  WriterType::New();
   writer->SetFileName( args.outputImageFile.c_str() );
   writer->SetInput( outputImage );
   //writer->SetUseCompression( true );

   try
   {
      writer->Update();
   }
   catch( itk::ExceptionObject& err )
   {
      std::cout << "Unexpected error." << std::endl;
      std::cout << err << std::endl;
      exit( EXIT_FAILURE );
   }
}


int main( int argc, char *argv[] )
{
   struct arguments args;
   parseOpts (argc, argv, args);

   std::cout<<"Processing with the following arguments:"<<std::endl;
   std::cout<<args<<std::endl<<std::endl;

   // Get the image dimension and pixel type
   itk::ImageIOBase::Pointer imageIO =
      itk::ImageIOFactory::CreateImageIO(
         args.inputImageFile.c_str(), itk::ImageIOFactory::ReadMode);
   imageIO->SetFileName(args.inputImageFile.c_str());

   try
   {
      imageIO->ReadImageInformation();
   }
   catch( itk::ExceptionObject& err )
   {
      std::cout << "Could not read the input image information."
                << std::endl;
      std::cout << err << std::endl;
      exit( EXIT_FAILURE );
   }


   // Check if the image is a scalar field
   if ( imageIO->GetPixelType() != itk::ImageIOBase::SCALAR )
   {
      std::cerr << "Unsuported input image pixel type" << std::endl;
      exit( EXIT_FAILURE );
   }

   std::cout<<"Input image dimension: "
            <<imageIO->GetNumberOfDimensions()<<std::endl;
   std::cout<<"Input image component type: "
            <<imageIO->GetComponentTypeAsString(
               imageIO->GetComponentType())<<std::endl;

   switch ( imageIO->GetNumberOfDimensions() )
   {
   case 2:
   {
      switch ( imageIO->GetComponentType() )
      {
      case itk::ImageIOBase::SHORT:
      {
         ProcessingFunction<short, 2>(args);
         break;
      }
      case itk::ImageIOBase::FLOAT:
      {
         ProcessingFunction<float, 2>(args);
         break;
      }
      default:
      {
         std::cerr << "Unsuported input image pixel type" << std::endl;
         exit( EXIT_FAILURE );
         // Note that we could also fallback to a Default IO pixeltype e.g.
         // ProcessingFunction<short, 2>(args);
      }
      }
      break;
   }
   case 3:
   {
      switch ( imageIO->GetComponentType() )
      {
      case itk::ImageIOBase::SHORT:
      {
         ProcessingFunction<short, 3>(args);
         break;
      }
      case itk::ImageIOBase::FLOAT:
      {
         ProcessingFunction<float, 3>(args);
         break;
      }
      default:
      {
         std::cerr << "Unsuported input image pixel type" << std::endl;
         exit( EXIT_FAILURE );
         // Note that we could also fallback to a Default IO pixeltype e.g.
         // ProcessingFunction<short, 2>(args);
      }
      }
      break;
   }
   default:
   {
      std::cerr << "Unsuported input image dimension" << std::endl;
      exit( EXIT_FAILURE );
   }
   }
	
	return EXIT_SUCCESS;
}


More information about the Insight-users mailing list