[Insight-users] castconvert program

Marius Staring marius at isi.uu.nl
Tue Sep 6 05:52:00 EDT 2005


Dear ITK users,

we have made a little program to convert between the different 
file-formats (jpg, tiff, mhd, etc) supported by the ITK. Casting the 
pixel component type is also possible. The castconvert program currently 
only supports SCALAR pixel types. the program is called as:

    castconvert inputfilename outputfilename [outputPixelComponentType]

or

    castconvert dicomDirectory outputfilename [outputPixelComponentType]

in case of dicoms. Use the [outputPixelComponentType] option only if a 
cast is required.

We want to contribute this to the community. If it is found useful, 
someone can commit it to the Insight Applications.

Regards,

Stefan Klein and Marius Staring

-- 
Marius Staring
Image Sciences Institute
University Medical Centre Utrecht
Heidelberglaan 100, 3584 CX Utrecht, The Netherlands
phone: +31 (0)30 250 3186, fax: +31 (0)30 251 3399
marius at isi.uu.nl, http://www.isi.uu.nl/People/Marius

-------------- next part --------------
/**
 * castconvert
 *
 * This program converts and possibly casts images.
 *
 * This is done by reading in an image, possibly casting of the image,
 * and subsequently writing the image to some format.
 * With converting we mean changing the extension of the image,
 * such as bmp, mhd, etc. With casting we mean changing the component
 * type of a voxel, such as short, unsigned long, float.
 *
 * Casting is currently done using the ShiftScaleImageFilter,
 * where values are mapped to itself, leaving the intensity range
 * the same. NOTE that when casting to a component type with a
 * smaller dynamic range, information might get lost. In this case
 * we might use the RescaleIntensityImageFilter to linearly
 * rescale the image values.
 *
 * Currently only supported are the SCALAR pixel types.
 * Input images can be in all file formats ITK supports and for which
 * the ImageFileReader works, and additionally single 3D dicom series
 * using the ImageSeriesReader. The pixel component type should
 * of course be a component type supported by the file format.
 * Output images can be in all file formats ITK supports and for which
 * the ImageFileReader works, so no dicom output is currently supported.
 *
 */

/** Basic Image support. */
#include "itkImage.h"
#include "itkImageIORegion.h"

/** For the support of RGB voxels. */
//#include "itkRGBPixel.h"

/** Reading and writing images. */
#include "itkImageFileReader.h"
#include "itkImageSeriesReader.h"
#include "itkImageFileWriter.h"

/** DICOM headers. */
#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"

/** One of these is used to cast the image. */
#include "itkShiftScaleImageFilter.h"
#include "itkRescaleIntensityImageFilter.h"

/** In order to determine if argv[1] is a directory or a file,
 * so that we can distinguish between dicom and other files.
 */
#include <itksys/SystemTools.hxx>

/** Declare a function to do the actual conversion.
 * ReadCastWriteImage() is for non-dicom images.
 */
template<	class	InputImageType,	class	OutputImageType	>
void ReadCastWriteImage( std::string inputFileName,	std::string	outputFileName );

/** Declare a function to do the actual conversion.
 * ReadDicomSeriesCastWriteImage() is for dicom images. */
template<	class	InputImageType,	class	OutputImageType	>
void ReadDicomSeriesCastWriteImage( std::string inputDirectoryName,	std::string	outputFileName );

/** Declare a function to print image information. */
template<	class	ReaderType,	class	WriterType >
void PrintInfo(	ReaderType reader, WriterType	writer );

/** Macros are used in order to make the code in main() look cleaner. */

/** callCorrectReadWriterMacro:
 * A macro to call the conversion function.
 */

#define callCorrectReadWriterMacro(typeIn,typeOut,dim) \
	if ( inputPixelComponentType == #typeIn && outputPixelComponentType == #typeOut && inputDimension == dim) \
		{ \
			typedef	itk::Image< typeIn, dim >		InputImageType; \
			typedef	itk::Image< typeOut, dim >	OutputImageType; \
			ReadCastWriteImage< InputImageType, OutputImageType >( inputFileName, outputFileName ); \
		}

/** callCorrectReadDicomWriterMacro:
 * A macro to call the dicom-conversion function.
 */

#define callCorrectReadDicomWriterMacro(typeIn,typeOut) \
	if ( inputPixelComponentType == #typeIn && outputPixelComponentType == #typeOut ) \
		{ \
			typedef	itk::Image< typeIn, 3 >		InputImageType; \
			typedef	itk::Image< typeOut, 3 >	OutputImageType; \
			ReadDicomSeriesCastWriteImage< InputImageType, OutputImageType >( inputDirectoryName, outputFileName ); \
		}

//-------------------------------------------------------------------------------------

int	main(	int	argc,	char *argv[] )
{
	/** TASK 1:
	 * Check arguments.
	 * *******************************************************************
	 */
	if ( argc	< 3 || argv[ 1 ] == "--help" )
	{
		std::cout	<< "Usage:"	<< std::endl;
		std::cout	<< "\tpxcastconvert inputfilename outputfilename [outputPixelComponentType]" << std::endl;
		std::cout	<< "\tpxcastconvert dicomDirectory outputfilename [outputPixelComponentType]" << std::endl;
		std::cout	<< "\twhere outputPixelComponentType is one of:" << std::endl;
		std::cout	<< "\t\t- unsigned_char" << std::endl;
		std::cout	<< "\t\t- char" << std::endl;
		std::cout	<< "\t\t- unsigned_short" << std::endl;
		std::cout	<< "\t\t- short" << std::endl;
		std::cout	<< "\t\t- unsigned_int" << std::endl;
		std::cout	<< "\t\t- int" << std::endl;
		std::cout	<< "\t\t- unsigned_long" << std::endl;
		std::cout	<< "\t\t- long" << std::endl;
		std::cout	<< "\t\t- float" << std::endl;
		std::cout	<< "\t\t- double" << std::endl;
		std::cout	<< "\tprovided that the outputPixelComponentType is supported by the output file format." << std::endl;
		std::cout	<< "\tBy default the outputPixelComponentType is set to the inputPixelComponentType." << std::endl;
		return 1;
	}

	/**	Get	the	inputs. */
	std::string	input = argv[ 1 ];
	std::string outputFileName = argv[ 2 ];
	std::string outputPixelComponentType = "";
	if ( argc == 4 ) outputPixelComponentType = argv[ 3 ];

	/** Make sure last character of input != "/".
	 * Otherwise FileIsDirectory() won't work.
	 */
	if ( input.rfind( "/" ) == input.size() - 1 )
	{
		input.erase( input.size() - 1, 1 );
	}

	/** Check if input is a file or a directory. */
	bool exists = itksys::SystemTools::FileExists( input.c_str() );
	bool isDir = itksys::SystemTools::FileIsDirectory( input.c_str() );
	bool isDICOM = false;
	std::string inputFileName, inputDirectoryName;

	if ( exists && !isDir )
	{
		/** Input is a file, and we use the ImageFileReader. */
		inputFileName = input;
	}
	else if ( exists && isDir )
	{
		/** Input is a directory, and we use the ImageSeriesReader. */
		inputDirectoryName = input;
		isDICOM = true;
	}
	else
	{
		/** Something is wrong. */
		std::cerr << "ERROR: first input argument does not exist!" << std::endl;
		return 1;
	}

	/** Check outputPixelType. */
	if ( outputPixelComponentType != ""
		&& outputPixelComponentType != "unsigned_char"
		&& outputPixelComponentType != "char"
		&& outputPixelComponentType != "unsigned_short"
		&& outputPixelComponentType != "short"
		&& outputPixelComponentType != "unsigned_int"
		&& outputPixelComponentType != "int"
		&& outputPixelComponentType != "unsigned_long"
		&& outputPixelComponentType != "long"
		&& outputPixelComponentType != "float"
		&& outputPixelComponentType != "double" )
	{
		/** In this case an illegal outputPixelComponentType is given. */
		std::cerr << "The given outputPixelComponentType is \"" << outputPixelComponentType
			<< "\", which is not supported." << std::endl;
		return 1;
	}

	/** TASK 2:
	 * Typedefs and test reading to determine correct image types.
	 * *******************************************************************
	 */

	/**	Initial image type. */
	const	unsigned int	Dimension	=	3;
	typedef	short				PixelType;

	/**	Some typedef's.	*/
	typedef	itk::Image<	PixelType, Dimension >			ImageType;
	typedef	itk::ImageFileReader<	ImageType	>				ReaderType;
	typedef	itk::ImageIOBase												ImageIOBaseType;
	typedef itk::GDCMImageIO                        GDCMImageIOType;
	typedef itk::GDCMSeriesFileNames								GDCMNamesGeneratorType;
	typedef std::vector< std::string >							FileNamesContainerType;

	/** Create a testReader. */
	ReaderType::Pointer	testReader = ReaderType::New();
	
	/** Setup the testReader. */
	if ( !isDICOM )
	{
		/** Set the inputFileName in the testReader. */
		testReader->SetFileName( inputFileName.c_str() );
	}
	else
	{
		/** Get a name of a 2D image. */
		GDCMNamesGeneratorType::Pointer nameGenerator = GDCMNamesGeneratorType::New();
		nameGenerator->SetInputDirectory( inputDirectoryName.c_str() );
		FileNamesContainerType fileNames = nameGenerator->GetInputFileNames();
		std::string fileName = fileNames[ 0 ];

		/** Create a dicom ImageIO and set it in the testReader. */
		GDCMImageIOType::Pointer dicomIO = GDCMImageIOType::New();
		testReader->SetImageIO( dicomIO );

		/** Set the name of the 2D dicom image in the testReader. */
		testReader->SetFileName( fileName.c_str() );

	} // end isDICOM
	
	/** Generate all information. */
	testReader->GenerateOutputInformation();

	/** Extract the ImageIO from the testReader. */
	ImageIOBaseType::Pointer testImageIOBase = testReader->GetImageIO();

	/**	Get	the	component	type,	number of	components,	dimension	and	pixel	type.	*/
	unsigned int inputDimension = testImageIOBase->GetNumberOfDimensions();
	unsigned int numberOfComponents	=	testImageIOBase->GetNumberOfComponents();
	std::string	inputPixelComponentType	=	testImageIOBase->GetComponentTypeAsString(
		testImageIOBase->GetComponentType()	);
	std::string	pixelType	=	testImageIOBase->GetPixelTypeAsString(
		testImageIOBase->GetPixelType()	);
	
	/** TASK 3:
	 * Do some preparations.
	 * *******************************************************************
	 */

	/** Check outputPixelType. */
	if ( outputPixelComponentType == "" )
	{
		/** In this case this option is not given, and by default
		 * we set it to the inputPixelComponentType.
		 */
		outputPixelComponentType = inputPixelComponentType;
	}

	/** Get rid of the "_" in inputPixelComponentType and outputPixelComponentType. */
	std::basic_string<char>::size_type pos = inputPixelComponentType.find( "_" );
	static const std::basic_string<char>::size_type npos = -1;
	if ( pos != npos )
	{
		inputPixelComponentType.replace( pos, 1, " " );
	}
	pos = outputPixelComponentType.find( "_" );
	if ( pos != npos )
	{
		outputPixelComponentType.replace( pos, 1, " " );
	}

	/** TASK 4:
	 * Now we are ready to check on image type and subsequently call the
	 * correct ReadCastWrite-function.
	 * *******************************************************************
	 */

	if ( !isDICOM )
	{
		/**
		 * ****************** Support for SCALAR pixel types. **********************************
		 */
		if ( strcmp( pixelType.c_str(),	"scalar" ) == 0	&& numberOfComponents	== 1 )
		{
			/** Support for 2D images. */
			if ( inputDimension == 2 )
			{
				/** From unsigned char to something else. */
				callCorrectReadWriterMacro( unsigned char, unsigned char, 2 );
				callCorrectReadWriterMacro( unsigned char, char, 2 );
				callCorrectReadWriterMacro( unsigned char, unsigned short, 2 );
				callCorrectReadWriterMacro( unsigned char, short, 2 );
				callCorrectReadWriterMacro( unsigned char, unsigned int, 2 );
				callCorrectReadWriterMacro( unsigned char, int, 2 );
				callCorrectReadWriterMacro( unsigned char, unsigned long, 2 );
				callCorrectReadWriterMacro( unsigned char, long, 2 );
				callCorrectReadWriterMacro( unsigned char, float, 2 );
				callCorrectReadWriterMacro( unsigned char, double, 2 );

				/** From char to something else. */
				callCorrectReadWriterMacro( char, unsigned char, 2 );
				callCorrectReadWriterMacro( char, char, 2 );
				callCorrectReadWriterMacro( char, unsigned short, 2 );
				callCorrectReadWriterMacro( char, short, 2 );
				callCorrectReadWriterMacro( char, unsigned int, 2 );
				callCorrectReadWriterMacro( char, int, 2 );
				callCorrectReadWriterMacro( char, unsigned long, 2 );
				callCorrectReadWriterMacro( char, long, 2 );
				callCorrectReadWriterMacro( char, float, 2 );
				callCorrectReadWriterMacro( char, double, 2 );

				/** From unsigned short to something else. */
				callCorrectReadWriterMacro( unsigned short, unsigned char, 2 );
				callCorrectReadWriterMacro( unsigned short, char, 2 );
				callCorrectReadWriterMacro( unsigned short, unsigned short, 2 );
				callCorrectReadWriterMacro( unsigned short, short, 2 );
				callCorrectReadWriterMacro( unsigned short, unsigned int, 2 );
				callCorrectReadWriterMacro( unsigned short, int, 2 );
				callCorrectReadWriterMacro( unsigned short, unsigned long, 2 );
				callCorrectReadWriterMacro( unsigned short, long, 2 );
				callCorrectReadWriterMacro( unsigned short, float, 2 );
				callCorrectReadWriterMacro( unsigned short, double, 2 );

				/** From short to something else. */
				callCorrectReadWriterMacro( short, unsigned char, 2 );
				callCorrectReadWriterMacro( short, char, 2 );
				callCorrectReadWriterMacro( short, unsigned short, 2 );
				callCorrectReadWriterMacro( short, short, 2 );
				callCorrectReadWriterMacro( short, unsigned int, 2 );
				callCorrectReadWriterMacro( short, int, 2 );
				callCorrectReadWriterMacro( short, unsigned long, 2 );
				callCorrectReadWriterMacro( short, long, 2 );
				callCorrectReadWriterMacro( short, float, 2 );
				callCorrectReadWriterMacro( short, double, 2 );

				/** From unsigned int to something else. */
				callCorrectReadWriterMacro( unsigned int, unsigned char, 2 );
				callCorrectReadWriterMacro( unsigned int, char, 2 );
				callCorrectReadWriterMacro( unsigned int, unsigned short, 2 );
				callCorrectReadWriterMacro( unsigned int, short, 2 );
				callCorrectReadWriterMacro( unsigned int, unsigned int, 2 );
				callCorrectReadWriterMacro( unsigned int, int, 2 );
				callCorrectReadWriterMacro( unsigned int, unsigned long, 2 );
				callCorrectReadWriterMacro( unsigned int, long, 2 );
				callCorrectReadWriterMacro( unsigned int, float, 2 );
				callCorrectReadWriterMacro( unsigned int, double, 2 );

				/** From int to something else. */
				callCorrectReadWriterMacro( int, unsigned char, 2 );
				callCorrectReadWriterMacro( int, char, 2 );
				callCorrectReadWriterMacro( int, unsigned short, 2 );
				callCorrectReadWriterMacro( int, short, 2 );
				callCorrectReadWriterMacro( int, unsigned int, 2 );
				callCorrectReadWriterMacro( int, int, 2 );
				callCorrectReadWriterMacro( int, unsigned long, 2 );
				callCorrectReadWriterMacro( int, long, 2 );
				callCorrectReadWriterMacro( int, float, 2 );
				callCorrectReadWriterMacro( int, double, 2 );

				/** From unsigned long to something else. */
				callCorrectReadWriterMacro( unsigned long, unsigned char, 2 );
				callCorrectReadWriterMacro( unsigned long, char, 2 );
				callCorrectReadWriterMacro( unsigned long, unsigned short, 2 );
				callCorrectReadWriterMacro( unsigned long, short, 2 );
				callCorrectReadWriterMacro( unsigned long, unsigned int, 2 );
				callCorrectReadWriterMacro( unsigned long, int, 2 );
				callCorrectReadWriterMacro( unsigned long, unsigned long, 2 );
				callCorrectReadWriterMacro( unsigned long, long, 2 );
				callCorrectReadWriterMacro( unsigned long, float, 2 );
				callCorrectReadWriterMacro( unsigned long, double, 2 );

				/** From long to something else. */
				callCorrectReadWriterMacro( long, unsigned char, 2 );
				callCorrectReadWriterMacro( long, char, 2 );
				callCorrectReadWriterMacro( long, unsigned short, 2 );
				callCorrectReadWriterMacro( long, short, 2 );
				callCorrectReadWriterMacro( long, unsigned int, 2 );
				callCorrectReadWriterMacro( long, int, 2 );
				callCorrectReadWriterMacro( long, unsigned long, 2 );
				callCorrectReadWriterMacro( long, long, 2 );
				callCorrectReadWriterMacro( long, float, 2 );
				callCorrectReadWriterMacro( long, double, 2 );

				/** From float to something else. */
				callCorrectReadWriterMacro( float, unsigned char, 2 );
				callCorrectReadWriterMacro( float, char, 2 );
				callCorrectReadWriterMacro( float, unsigned short, 2 );
				callCorrectReadWriterMacro( float, short, 2 );
				callCorrectReadWriterMacro( float, unsigned int, 2 );
				callCorrectReadWriterMacro( float, int, 2 );
				callCorrectReadWriterMacro( float, unsigned long, 2 );
				callCorrectReadWriterMacro( float, long, 2 );
				callCorrectReadWriterMacro( float, float, 2 );
				callCorrectReadWriterMacro( float, double, 2 );

				/** From double to something else. */
				callCorrectReadWriterMacro( double, unsigned char, 2 );
				callCorrectReadWriterMacro( double, char, 2 );
				callCorrectReadWriterMacro( double, unsigned short, 2 );
				callCorrectReadWriterMacro( double, short, 2 );
				callCorrectReadWriterMacro( double, unsigned int, 2 );
				callCorrectReadWriterMacro( double, int, 2 );
				callCorrectReadWriterMacro( double, unsigned long, 2 );
				callCorrectReadWriterMacro( double, long, 2 );
				callCorrectReadWriterMacro( double, float, 2 );
				callCorrectReadWriterMacro( double, double, 2 );

			} // end support for 2D images
			/** Support for 3D images. */
			else if ( inputDimension == 3 )
			{
				/** From unsigned char to something else. */
				callCorrectReadWriterMacro( unsigned char, unsigned char, 3 );
				callCorrectReadWriterMacro( unsigned char, char, 3 );
				callCorrectReadWriterMacro( unsigned char, unsigned short, 3 );
				callCorrectReadWriterMacro( unsigned char, short, 3 );
				callCorrectReadWriterMacro( unsigned char, unsigned int, 3 );
				callCorrectReadWriterMacro( unsigned char, int, 3 );
				callCorrectReadWriterMacro( unsigned char, unsigned long, 3 );
				callCorrectReadWriterMacro( unsigned char, long, 3 );
				callCorrectReadWriterMacro( unsigned char, float, 3 );
				callCorrectReadWriterMacro( unsigned char, double, 3 );

				/** From char to something else. */
				callCorrectReadWriterMacro( char, unsigned char, 3 );
				callCorrectReadWriterMacro( char, char, 3 );
				callCorrectReadWriterMacro( char, unsigned short, 3 );
				callCorrectReadWriterMacro( char, short, 3 );
				callCorrectReadWriterMacro( char, unsigned int, 3 );
				callCorrectReadWriterMacro( char, int, 3 );
				callCorrectReadWriterMacro( char, unsigned long, 3 );
				callCorrectReadWriterMacro( char, long, 3 );
				callCorrectReadWriterMacro( char, float, 3 );
				callCorrectReadWriterMacro( char, double, 3 );

				/** From unsigned short to something else. */
				callCorrectReadWriterMacro( unsigned short, unsigned char, 3 );
				callCorrectReadWriterMacro( unsigned short, char, 3 );
				callCorrectReadWriterMacro( unsigned short, unsigned short, 3 );
				callCorrectReadWriterMacro( unsigned short, short, 3 );
				callCorrectReadWriterMacro( unsigned short, unsigned int, 3 );
				callCorrectReadWriterMacro( unsigned short, int, 3 );
				callCorrectReadWriterMacro( unsigned short, unsigned long, 3 );
				callCorrectReadWriterMacro( unsigned short, long, 3 );
				callCorrectReadWriterMacro( unsigned short, float, 3 );
				callCorrectReadWriterMacro( unsigned short, double, 3 );

				/** From short to something else. */
				callCorrectReadWriterMacro( short, unsigned char, 3 );
				callCorrectReadWriterMacro( short, char, 3 );
				callCorrectReadWriterMacro( short, unsigned short, 3 );
				callCorrectReadWriterMacro( short, short, 3 );
				callCorrectReadWriterMacro( short, unsigned int, 3 );
				callCorrectReadWriterMacro( short, int, 3 );
				callCorrectReadWriterMacro( short, unsigned long, 3 );
				callCorrectReadWriterMacro( short, long, 3 );
				callCorrectReadWriterMacro( short, float, 3 );
				callCorrectReadWriterMacro( short, double, 3 );

				/** From unsigned int to something else. */
				callCorrectReadWriterMacro( unsigned int, unsigned char, 3 );
				callCorrectReadWriterMacro( unsigned int, char, 3 );
				callCorrectReadWriterMacro( unsigned int, unsigned short, 3 );
				callCorrectReadWriterMacro( unsigned int, short, 3 );
				callCorrectReadWriterMacro( unsigned int, unsigned int, 3 );
				callCorrectReadWriterMacro( unsigned int, int, 3 );
				callCorrectReadWriterMacro( unsigned int, unsigned long, 3 );
				callCorrectReadWriterMacro( unsigned int, long, 3 );
				callCorrectReadWriterMacro( unsigned int, float, 3 );
				callCorrectReadWriterMacro( unsigned int, double, 3 );

				/** From int to something else. */
				callCorrectReadWriterMacro( int, unsigned char, 3 );
				callCorrectReadWriterMacro( int, char, 3 );
				callCorrectReadWriterMacro( int, unsigned short, 3 );
				callCorrectReadWriterMacro( int, short, 3 );
				callCorrectReadWriterMacro( int, unsigned int, 3 );
				callCorrectReadWriterMacro( int, int, 3 );
				callCorrectReadWriterMacro( int, unsigned long, 3 );
				callCorrectReadWriterMacro( int, long, 3 );
				callCorrectReadWriterMacro( int, float, 3 );
				callCorrectReadWriterMacro( int, double, 3 );

				/** From unsigned long to something else. */
				callCorrectReadWriterMacro( unsigned long, unsigned char, 3 );
				callCorrectReadWriterMacro( unsigned long, char, 3 );
				callCorrectReadWriterMacro( unsigned long, unsigned short, 3 );
				callCorrectReadWriterMacro( unsigned long, short, 3 );
				callCorrectReadWriterMacro( unsigned long, unsigned int, 3 );
				callCorrectReadWriterMacro( unsigned long, int, 3 );
				callCorrectReadWriterMacro( unsigned long, unsigned long, 3 );
				callCorrectReadWriterMacro( unsigned long, long, 3 );
				callCorrectReadWriterMacro( unsigned long, float, 3 );
				callCorrectReadWriterMacro( unsigned long, double, 3 );

				/** From long to something else. */
				callCorrectReadWriterMacro( long, unsigned char, 3 );
				callCorrectReadWriterMacro( long, char, 3 );
				callCorrectReadWriterMacro( long, unsigned short, 3 );
				callCorrectReadWriterMacro( long, short, 3 );
				callCorrectReadWriterMacro( long, unsigned int, 3 );
				callCorrectReadWriterMacro( long, int, 3 );
				callCorrectReadWriterMacro( long, unsigned long, 3 );
				callCorrectReadWriterMacro( long, long, 3 );
				callCorrectReadWriterMacro( long, float, 3 );
				callCorrectReadWriterMacro( long, double, 3 );

				/** From float to something else. */
				callCorrectReadWriterMacro( float, unsigned char, 3 );
				callCorrectReadWriterMacro( float, char, 3 );
				callCorrectReadWriterMacro( float, unsigned short, 3 );
				callCorrectReadWriterMacro( float, short, 3 );
				callCorrectReadWriterMacro( float, unsigned int, 3 );
				callCorrectReadWriterMacro( float, int, 3 );
				callCorrectReadWriterMacro( float, unsigned long, 3 );
				callCorrectReadWriterMacro( float, long, 3 );
				callCorrectReadWriterMacro( float, float, 3 );
				callCorrectReadWriterMacro( float, double, 3 );

				/** From double to something else. */
				callCorrectReadWriterMacro( double, unsigned char, 3 );
				callCorrectReadWriterMacro( double, char, 3 );
				callCorrectReadWriterMacro( double, unsigned short, 3 );
				callCorrectReadWriterMacro( double, short, 3 );
				callCorrectReadWriterMacro( double, unsigned int, 3 );
				callCorrectReadWriterMacro( double, int, 3 );
				callCorrectReadWriterMacro( double, unsigned long, 3 );
				callCorrectReadWriterMacro( double, long, 3 );
				callCorrectReadWriterMacro( double, float, 3 );
				callCorrectReadWriterMacro( double, double, 3 );

			} // end support for 3D images
			else
			{
				std::cerr	<< "Dimension equals " << inputDimension << ", which is not supported."	<< std::endl;
				std::cerr	<< "Only 2D and 3D images are supported."	<< std::endl;
				return 1;
			} // end if over inputDimension

		} // end support for SCALAR pixel type
		else
		{
			std::cerr	<< "Pixel type is "	<< pixelType
				<< ", component type is " << inputPixelComponentType
				<< " and number of components equals " <<	numberOfComponents <<	"."	<< std::endl;
			std::cerr	<< "ERROR: This image type is not supported."	<< std::endl;
			return 1;
		}
	}
	else
	{
		/** In this case input is a DICOM series, from which we only support
		 * SCALAR pixel types, with component type:
		 * DICOMImageIO2: (unsigned) char, (unsigned) short, float
		 * GDCMImageIO: (unsigned) char, (unsigned) short, (unsigned) int, double
		 * It is also assumed that the dicom series consist of multiple
		 * 2D images forming a 3D image.
		 */

		if ( strcmp( pixelType.c_str(),	"scalar" ) == 0	&& numberOfComponents	== 1 )
		{
			/** From unsigned char to something else. */
			callCorrectReadDicomWriterMacro( unsigned char, unsigned char );
			callCorrectReadDicomWriterMacro( unsigned char, char );
			callCorrectReadDicomWriterMacro( unsigned char, unsigned short );
			callCorrectReadDicomWriterMacro( unsigned char, short );
			callCorrectReadDicomWriterMacro( unsigned char, unsigned int );
			callCorrectReadDicomWriterMacro( unsigned char, int );
			callCorrectReadDicomWriterMacro( unsigned char, unsigned long );
			callCorrectReadDicomWriterMacro( unsigned char, long );
			callCorrectReadDicomWriterMacro( unsigned char, float );
			callCorrectReadDicomWriterMacro( unsigned char, double );

			/** From char to something else. */
			callCorrectReadDicomWriterMacro( char, unsigned char );
			callCorrectReadDicomWriterMacro( char, char );
			callCorrectReadDicomWriterMacro( char, unsigned short );
			callCorrectReadDicomWriterMacro( char, short );
			callCorrectReadDicomWriterMacro( char, unsigned int );
			callCorrectReadDicomWriterMacro( char, int );
			callCorrectReadDicomWriterMacro( char, unsigned long );
			callCorrectReadDicomWriterMacro( char, long );
			callCorrectReadDicomWriterMacro( char, float );
			callCorrectReadDicomWriterMacro( char, double );

			/** From unsigned short to something else. */
			callCorrectReadDicomWriterMacro( unsigned short, unsigned char );
			callCorrectReadDicomWriterMacro( unsigned short, char );
			callCorrectReadDicomWriterMacro( unsigned short, unsigned short );
			callCorrectReadDicomWriterMacro( unsigned short, short );
			callCorrectReadDicomWriterMacro( unsigned short, unsigned int );
			callCorrectReadDicomWriterMacro( unsigned short, int );
			callCorrectReadDicomWriterMacro( unsigned short, unsigned long );
			callCorrectReadDicomWriterMacro( unsigned short, long );
			callCorrectReadDicomWriterMacro( unsigned short, float );
			callCorrectReadDicomWriterMacro( unsigned short, double );

			/** From short to something else. */
			callCorrectReadDicomWriterMacro( short, unsigned char );
			callCorrectReadDicomWriterMacro( short, char );
			callCorrectReadDicomWriterMacro( short, unsigned short );
			callCorrectReadDicomWriterMacro( short, short );
			callCorrectReadDicomWriterMacro( short, unsigned int );
			callCorrectReadDicomWriterMacro( short, int );
			callCorrectReadDicomWriterMacro( short, unsigned long );
			callCorrectReadDicomWriterMacro( short, long );
			callCorrectReadDicomWriterMacro( short, float );
			callCorrectReadDicomWriterMacro( short, double );

			/** From unsigned int to something else. */
			callCorrectReadDicomWriterMacro( unsigned int, unsigned char );
			callCorrectReadDicomWriterMacro( unsigned int, char );
			callCorrectReadDicomWriterMacro( unsigned int, unsigned short );
			callCorrectReadDicomWriterMacro( unsigned int, short );
			callCorrectReadDicomWriterMacro( unsigned int, unsigned int );
			callCorrectReadDicomWriterMacro( unsigned int, int );
			callCorrectReadDicomWriterMacro( unsigned int, unsigned long );
			callCorrectReadDicomWriterMacro( unsigned int, long );
			callCorrectReadDicomWriterMacro( unsigned int, float );
			callCorrectReadDicomWriterMacro( unsigned int, double );

			/** From int to something else. */
			callCorrectReadDicomWriterMacro( int, unsigned char );
			callCorrectReadDicomWriterMacro( int, char );
			callCorrectReadDicomWriterMacro( int, unsigned short );
			callCorrectReadDicomWriterMacro( int, short );
			callCorrectReadDicomWriterMacro( int, unsigned int );
			callCorrectReadDicomWriterMacro( int, int );
			callCorrectReadDicomWriterMacro( int, unsigned long );
			callCorrectReadDicomWriterMacro( int, long );
			callCorrectReadDicomWriterMacro( int, float );
			callCorrectReadDicomWriterMacro( int, double );

			/** From float to something else. *
			callCorrectReadDicomWriterMacro( float, unsigned char );
			callCorrectReadDicomWriterMacro( float, char );
			callCorrectReadDicomWriterMacro( float, unsigned short );
			callCorrectReadDicomWriterMacro( float, short );
			callCorrectReadDicomWriterMacro( float, unsigned int );
			callCorrectReadDicomWriterMacro( float, int );
			callCorrectReadDicomWriterMacro( float, unsigned long );
			callCorrectReadDicomWriterMacro( float, long );
			callCorrectReadDicomWriterMacro( float, float );
			callCorrectReadDicomWriterMacro( float, double );

			/** From double to something else. */
			callCorrectReadDicomWriterMacro( double, unsigned char );
			callCorrectReadDicomWriterMacro( double, char );
			callCorrectReadDicomWriterMacro( double, unsigned short );
			callCorrectReadDicomWriterMacro( double, short );
			callCorrectReadDicomWriterMacro( double, unsigned int );
			callCorrectReadDicomWriterMacro( double, int );
			callCorrectReadDicomWriterMacro( double, unsigned long );
			callCorrectReadDicomWriterMacro( double, long );
			callCorrectReadDicomWriterMacro( double, float );
			callCorrectReadDicomWriterMacro( double, double );

		} // end support for SCALAR pixel type
		else
		{
			std::cerr	<< "Pixel type is "	<< pixelType
				<< ", component type is " << inputPixelComponentType
				<< " and number of components equals " <<	numberOfComponents <<	"."	<< std::endl;
			std::cerr	<< "ERROR: This image type is not supported."	<< std::endl;
			return 1;
		}

	} // end isDICOM


		/**
		 * ****************** Support for RGB pixel types. **********************************
		 *
		else if ( strcmp( pixelType.c_str(),	"rgb" ) == 0	&& numberOfComponents	== 3 )
		{
			if ( strcmp( iOComponent.c_str(),	"unsigned_char"	)	== 0 )
			{
				typedef itk::RGBPixel< unsigned char >		PixelType;
				typedef	itk::Image<	PixelType, 2 >				ImageType;
				ReadWriteImage<	ImageType, ImageType >(	inputFileName, outputFileName	);
			}
		} // end Support for RGB pixel type */


	/**	End	program. */
	return 0;

}	// end main


/**	The	function that	reads	the	input	dicom image	and	writes the output	image.
 * This	function is	templated	over the image types.	In the main	function
 * we	have to	make sure	to call	the	right	instantiation.
 */
template<	class	InputImageType,	class	OutputImageType	>
void ReadDicomSeriesCastWriteImage( std::string inputDirectoryName,	std::string	outputFileName )
{
	/**	Typedef the correct reader, caster and writer. */
	typedef	typename itk::ImageSeriesReader< InputImageType	>		SeriesReaderType;
	typedef typename itk::RescaleIntensityImageFilter<
		InputImageType, OutputImageType >													RescaleFilterType;
	typedef typename itk::ShiftScaleImageFilter<
		InputImageType, OutputImageType >													ShiftScaleFilterType;
	typedef	typename itk::ImageFileWriter< OutputImageType >		ImageWriterType;

	/** Typedef dicom stuff. */
	typedef itk::GDCMImageIO                        GDCMImageIOType;
	typedef itk::GDCMSeriesFileNames								GDCMNamesGeneratorType;
	typedef std::vector< std::string >							FileNamesContainerType;

	/** Create the dicom ImageIO. */
	typename GDCMImageIOType::Pointer dicomIO = GDCMImageIOType::New();
	
	/** Get a list of the filenames of the 2D input dicom images. */
	GDCMNamesGeneratorType::Pointer nameGenerator = GDCMNamesGeneratorType::New();
  nameGenerator->SetInputDirectory( inputDirectoryName.c_str() );
	FileNamesContainerType fileNames = nameGenerator->GetInputFileNames();

	/** Create and setup the seriesReader. */
	typename SeriesReaderType::Pointer seriesReader = SeriesReaderType::New();
	seriesReader->SetFileNames( fileNames );
	seriesReader->SetImageIO( dicomIO );

	/** Create and setup caster and writer. */
	//typename RescaleFilterType::Pointer caster = RescaleFilterType::New();
	typename ShiftScaleFilterType::Pointer caster = ShiftScaleFilterType::New();
	typename ImageWriterType::Pointer	writer = ImageWriterType::New();
	caster->SetShift( 0.0 );
	caster->SetScale( 1.0 );
	writer->SetFileName( outputFileName.c_str()	);

	/** Connect the pipeline. */
	caster->SetInput(	seriesReader->GetOutput()	);
	writer->SetInput(	caster->GetOutput()	);

	/**	Do the actual	conversion.	*/
	try
	{
		writer->Update();
	}
	catch( itk::ExceptionObject	&	err	)
	{
		std::cerr	<< "ExceptionObject caught !"	<< std::endl;
		std::cerr	<< err <<	std::endl;
	}

	/**	Print	information. */
	PrintInfo( seriesReader, writer	);

}	// end ReadDicomSeriesCastWriteImage


/**	The	function that	reads	the	input	image	and	writes the output	image.
 * This	function is	templated	over the image types.	In the main	function
 * we	have to	make sure	to call	the	right	instantiation.
 */
template<	class	InputImageType,	class	OutputImageType	>
void ReadCastWriteImage( std::string inputFileName,	std::string	outputFileName )
{
	/**	Typedef the correct reader, caster and writer. */
	typedef	typename itk::ImageFileReader< InputImageType	>			ImageReaderType;
	typedef typename itk::RescaleIntensityImageFilter<
		InputImageType, OutputImageType >													RescaleFilterType;
	typedef typename itk::ShiftScaleImageFilter<
		InputImageType, OutputImageType >													ShiftScaleFilterType;
	typedef	typename itk::ImageFileWriter< OutputImageType >		ImageWriterType;
	
	/** Create and setup the reader. */
	typename ImageReaderType::Pointer	reader = ImageReaderType::New();
	reader->SetFileName( inputFileName.c_str() );

	/** Create and setup caster and writer. */
	//typename RescaleFilterType::Pointer caster = RescaleFilterType::New();
	typename ShiftScaleFilterType::Pointer caster = ShiftScaleFilterType::New();
	typename ImageWriterType::Pointer	writer = ImageWriterType::New();
	caster->SetShift( 0.0 );
	caster->SetScale( 1.0 );
	writer->SetFileName( outputFileName.c_str()	);

	/** Connect the pipeline. */
	caster->SetInput(	reader->GetOutput()	);
	writer->SetInput(	caster->GetOutput()	);

	/**	Do the actual	conversion.	*/
	try
	{
		writer->Update();
	}
	catch( itk::ExceptionObject	&	err	)
	{
		std::cerr	<< "ExceptionObject caught !"	<< std::endl;
		std::cerr	<< err <<	std::endl;
	}

	/**	Print	information. */
	PrintInfo( reader, writer	);

}	// end ReadWriteImage


/** Print image information from the reader and the writer. */
template<	class	ReaderType,	class	WriterType >
void PrintInfo(	ReaderType reader, WriterType	writer )
{
	/**	Typedef's. */
	typedef	itk::ImageIOBase												ImageIOBaseType;
	typedef	itk::ImageIORegion											ImageIORegionType;
	typedef	typename ImageIORegionType::SizeType		SizeType;

	/**	Get	IOBase of	the	reader and extract information.	*/
	ImageIOBaseType::Pointer imageIOBaseIn = reader->GetImageIO();
	ImageIORegionType	iORegionIn = imageIOBaseIn->GetIORegion();

	const	char * fileNameIn	=	imageIOBaseIn->GetFileName();
	std::string	pixelTypeIn	=	imageIOBaseIn->GetPixelTypeAsString( imageIOBaseIn->GetPixelType() );
	unsigned int nocIn = imageIOBaseIn->GetNumberOfComponents();
	std::string	componentTypeIn	=	imageIOBaseIn->GetComponentTypeAsString( imageIOBaseIn->GetComponentType() );
	unsigned int dimensionIn = imageIOBaseIn->GetNumberOfDimensions();
	SizeType sizeIn	=	iORegionIn.GetSize();

	/**	Get	IOBase of	the	writer and extract information.	*/
	ImageIOBaseType::Pointer imageIOBaseOut	=	writer->GetImageIO();
	ImageIORegionType	iORegionOut	=	imageIOBaseOut->GetIORegion();

	const	char * fileNameOut = imageIOBaseOut->GetFileName();
	std::string	pixelTypeOut = imageIOBaseOut->GetPixelTypeAsString( imageIOBaseOut->GetPixelType()	);
	unsigned int nocOut	=	imageIOBaseOut->GetNumberOfComponents();
	std::string	componentTypeOut = imageIOBaseOut->GetComponentTypeAsString( imageIOBaseOut->GetComponentType()	);
	unsigned int dimensionOut	=	imageIOBaseOut->GetNumberOfDimensions();
	SizeType sizeOut = iORegionOut.GetSize();

	/**	Print	information. */
	std::cout	<< "Information about the input image \""	<< fileNameIn	<< "\":" <<	std::endl;
	std::cout	<< "\tdimension:\t\t"	<< dimensionIn <<	std::endl;
	std::cout	<< "\tpixel type:\t\t" <<	pixelTypeIn	<< std::endl;
	std::cout	<< "\tnumber of components:\t" <<	nocIn	<< std::endl;
	std::cout	<< "\tcomponent type:\t\t" <<	componentTypeIn	<< std::endl;
	std::cout	<< "\tsize:\t\t\t";
	for	(	unsigned int i = 0;	i	<	dimensionIn; i++ ) std::cout <<	sizeIn[	i	]	<< " ";
	std::cout	<< std::endl;

	/**	Print	information. */
	std::cout	<< std::endl;
	std::cout	<< "Information about the output image \"" <<	fileNameOut	<< "\":" <<	std::endl;
	std::cout	<< "\tdimension:\t\t"	<< dimensionOut	<< std::endl;
	std::cout	<< "\tpixel type:\t\t" <<	pixelTypeOut <<	std::endl;
	std::cout	<< "\tnumber of components:\t" <<	nocOut <<	std::endl;
	std::cout	<< "\tcomponent type:\t\t" <<	componentTypeOut <<	std::endl;
	std::cout	<< "\tsize:\t\t\t";
	for	(	unsigned int i = 0;	i	<	dimensionOut;	i++	)	std::cout	<< sizeOut[	i	]	<< " ";
	std::cout	<< std::endl;

}	// end PrintInfo

-------------- next part --------------
# This project is intended to be built outside the Insight source tree
PROJECT(castconvert)

# Find ITK.
FIND_PACKAGE(ITK)
IF(ITK_FOUND)
  INCLUDE(${ITK_USE_FILE})
ELSE(ITK_FOUND)
  MESSAGE(FATAL_ERROR
          "Cannot build without ITK.  Please set ITK_DIR.")
ENDIF(ITK_FOUND)

ADD_EXECUTABLE(castconvert castconvert.cxx)

INSTALL_TARGETS(/. castconvert)

TARGET_LINK_LIBRARIES(castconvert ITKIO ITKCommon)


More information about the Insight-users mailing list