[Insight-users] castconvert program

Luis Ibanez luis.ibanez at kitware.com
Thu Sep 8 20:08:27 EDT 2005


Hi Marius,

Thanks a lot for contributing your code.

This will make a nice submission for the Insight Journal,
and will be quite useful to ITK users.

Could you please write a page or two on your rationale
and post it to the current issue of the Insight Journal ?

http://www.insightsoftwareconsortium.org/InsightJournal/

In this way, it will get tested and discussed among the
ITK community before it is introduced in the toolkit,
or in InsightApplications.



We plan to make the Insight Journal the entry gate for
new classes and algorithms into the Insight Toolkit.



Note that the Insight Journal is not the typical vanity-
based technical journal were people try to publish just
to add lines in their Resumes and brag about how many
papers they have published.

The Insight Journal enforces the fundamental practices of
the scientific method, which comes down to:

              Enforce reproducibility

In other words:

             "If we cannot replicate it...
              it doesn't exist"      :-)



Please let us know if you have any questions regarding
how to submit your contribution to the Insight Journal.



Just to further encourage you:

   Never underestimate how much time ITK users spend in
   dealing with file formats and type conversions.




    Regards,


       Luis



----------------------
Marius Staring wrote:
> 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
> 
> 
> ------------------------------------------------------------------------
> 
> /**
>  * 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
> 
> 
> 
> ------------------------------------------------------------------------
> 
> # 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)
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users



More information about the Insight-users mailing list