diff --git a/Examples/antsApplyTransforms.cxx b/Examples/antsApplyTransforms.cxx index e10e8a345..03072399c 100644 --- a/Examples/antsApplyTransforms.cxx +++ b/Examples/antsApplyTransforms.cxx @@ -9,6 +9,7 @@ #include "itkResampleImageFilter.h" #include "itkVectorImage.h" #include "itkVectorIndexSelectionCastImageFilter.h" +#include "itkCastImageFilter.h" #include "itkAffineTransform.h" #include "itkCompositeTransform.h" @@ -138,7 +139,7 @@ bool isDiagonalElement(std::vector diagElements, unsigned int ind) return false; } -template +template int antsApplyTransforms( itk::ants::CommandLineParser::Pointer & parser, unsigned int inputImageType = 0 ) { typedef T RealType; @@ -158,6 +159,13 @@ int antsApplyTransforms( itk::ants::CommandLineParser::Pointer & parser, unsigne typedef itk::VectorImage MultiChannelImageType; typedef itk::Image TensorImageType; + typedef OT OutputPixelType; + typedef itk::Image OutputImageType; + typedef itk::Image OutputTimeSeriesImageType; + typedef itk::VectorImage OutputMultiChannelImageType; + typedef itk::Vector OutputVectorType; + typedef itk::Image OutputDisplacementFieldType; + typedef typename ants::RegistrationHelper RegistrationHelperType; typedef typename RegistrationHelperType::AffineTransformType AffineTransformType; typedef typename RegistrationHelperType::CompositeTransformType CompositeTransformType; @@ -606,11 +614,18 @@ int antsApplyTransforms( itk::ants::CommandLineParser::Pointer & parser, unsigne } It.Set( vector ); } - typedef itk::ImageFileWriter WriterType; + + typedef itk::CastImageFilter CastFitlerType; + typename CastFitlerType::Pointer caster = CastFitlerType::New(); + caster->SetInput( outputVectorImage ); + caster->Update(); + + typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); - writer->SetInput( outputVectorImage ); + writer->SetInput( caster->GetOutput() ); writer->SetFileName( ( outputFileName ).c_str() ); writer->Update(); + } else if( inputImageType == 2 ) { @@ -707,19 +722,35 @@ int antsApplyTransforms( itk::ants::CommandLineParser::Pointer & parser, unsigne } if( inputImageType == 3 ) { - WriteImage( outputTimeSeriesImage, ( outputFileName ).c_str() ); + typedef itk::CastImageFilter CastFitlerType; + typename CastFitlerType::Pointer caster = CastFitlerType::New(); + caster->SetInput( outputTimeSeriesImage ); + caster->Update(); + + WriteImage( caster->GetOutput(), ( outputFileName ).c_str() ); } else // inputImageType == 4 { multiChannelImage = ConvertTimeSeriesImageToMultiChannelImage( outputTimeSeriesImage ); - WriteImage( multiChannelImage, ( outputFileName ).c_str() ); + + typedef itk::CastImageFilter CastFitlerType; + typename CastFitlerType::Pointer caster = CastFitlerType::New(); + caster->SetInput( multiChannelImage ); + caster->Update(); + + WriteImage( caster->GetOutput(), ( outputFileName ).c_str() ); } } else { try { - WriteImage( outputImages[0], ( outputFileName ).c_str() ); + typedef itk::CastImageFilter CastFitlerType; + typename CastFitlerType::Pointer caster = CastFitlerType::New(); + caster->SetInput( outputImages[0] ); + caster->Update(); + + WriteImage( caster->GetOutput(), ( outputFileName ).c_str() ); } catch( itk::ExceptionObject & err ) { @@ -849,6 +880,31 @@ static void antsApplyTransformsInitializeCommandLineOptions( itk::ants::CommandL parser->AddOption( option ); } + { + std::string description = + std::string( "Output image data type. " ) + + std::string( "This is a direct typecast; output values are not rescaled. " ) + + std::string( "Default is to use the internal data type (float or double). " ) + + std::string( "uchar is unsigned char; others are signed. " ) + + std::string( "WARNING: Outputs will be incorrect (overflowed/reinterpreted) " ) + + std::string( "if values exceed the range allowed by your choice. " ) + + std::string( "Note that some pixel types are not supported by some image " ) + + std::string( "formats. e.g. int is not supported by jpg. " ); + + OptionType::Pointer option = OptionType::New(); + option->SetLongName( "output-data-type" ); + option->SetShortName( 'u' ); + option->SetUsageOption( 0, "char" ); + option->SetUsageOption( 1, "uchar" ); + option->SetUsageOption( 2, "short" ); + option->SetUsageOption( 3, "int" ); + option->SetUsageOption( 4, "float" ); + option->SetUsageOption( 5, "double" ); + option->SetUsageOption( 6, "default" ); + option->SetDescription( description ); + parser->AddOption( option ); + } + { std::string description = std::string( "Several transform options are supported including all " ) @@ -1118,6 +1174,14 @@ int antsApplyTransforms( std::vector args, std::ostream * /*out_str } } + std::string outputDataType( "default" ); + typename itk::ants::CommandLineParser::OptionType::Pointer outputDataTypeOption = parser->GetOption( "output-data-type" ); + if( outputDataTypeOption && outputDataTypeOption->GetNumberOfFunctions() ) + { + outputDataType = outputDataTypeOption->GetFunction( 0 )->GetName(); + ConvertToLowerCase( outputDataType ); + } + switch( dimension ) { case 2: @@ -1134,11 +1198,37 @@ int antsApplyTransforms( std::vector args, std::ostream * /*out_str { if( useDoublePrecision ) { - return antsApplyTransforms( parser, imageType ); + if( !std::strcmp( outputDataType.c_str(), "char" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "uchar" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "short" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "int" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "float" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "double" ) ) + return antsApplyTransforms( parser, imageType ); + else + return antsApplyTransforms( parser, imageType ); } else { - return antsApplyTransforms( parser, imageType ); + if( !std::strcmp( outputDataType.c_str(), "char" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "uchar" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "short" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "int" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "float" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "double" ) ) + return antsApplyTransforms( parser, imageType ); + else + return antsApplyTransforms( parser, imageType ); } } } @@ -1147,11 +1237,37 @@ int antsApplyTransforms( std::vector args, std::ostream * /*out_str { if( useDoublePrecision ) { - return antsApplyTransforms( parser, imageType ); + if( !std::strcmp( outputDataType.c_str(), "char" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "uchar" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "short" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "int" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "float" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "double" ) ) + return antsApplyTransforms( parser, imageType ); + else + return antsApplyTransforms( parser, imageType ); } else { - return antsApplyTransforms( parser, imageType ); + if( !std::strcmp( outputDataType.c_str(), "char" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "uchar" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "short" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "int" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "float" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "double" ) ) + return antsApplyTransforms( parser, imageType ); + else + return antsApplyTransforms( parser, imageType ); } } break; @@ -1175,11 +1291,37 @@ int antsApplyTransforms( std::vector args, std::ostream * /*out_str { if( useDoublePrecision ) { - return antsApplyTransforms( parser, imageType ); + if( !std::strcmp( outputDataType.c_str(), "char" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "uchar" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "short" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "int" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "float" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "double" ) ) + return antsApplyTransforms( parser, imageType ); + else + return antsApplyTransforms( parser, imageType ); } else { - return antsApplyTransforms( parser, imageType ); + if( !std::strcmp( outputDataType.c_str(), "char" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "uchar" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "short" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "int" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "float" ) ) + return antsApplyTransforms( parser, imageType ); + else if( !std::strcmp( outputDataType.c_str(), "double" ) ) + return antsApplyTransforms( parser, imageType ); + else + return antsApplyTransforms( parser, imageType ); } } }