diff --git a/Testing/Code/IO/CMakeLists.txt b/Testing/Code/IO/CMakeLists.txt index da6ef772325b306fbf6a1f5911752bfc0966fd14..49a9cdf4cf1f89ac0b0348f7e4a58631c4ed5de9 100644 --- a/Testing/Code/IO/CMakeLists.txt +++ b/Testing/Code/IO/CMakeLists.txt @@ -2798,9 +2798,10 @@ ADD_TEST(ioTvTileMapImageIOHelperTest ${IO_TESTS21} # Tests about complex reading -#SET(INPUTFILE_PIXELTYPES_LIST "Int" "Short" "Float" "Double") -SET(INPUTFILE_PIXELTYPES_LIST "Float" "Double") -SET(READING_PIXELTYPES_LIST "Float" "Double") +SET(INPUTFILE_PIXELTYPES_LIST "Int" "Short" "Float" "Double") +#SET(INPUTFILE_PIXELTYPES_LIST "Float" "Double") +#SET(READING_PIXELTYPES_LIST "Float" "Double") +SET(READING_PIXELTYPES_LIST "Int" "Short" "Float" "Double") SET(NBBANDS_LIST "2" "3" "4") FOREACH(INPUTFILE_PIXELTYPE ${INPUTFILE_PIXELTYPES_LIST}) @@ -2820,22 +2821,22 @@ FOREACH(INPUTFILE_PIXELTYPE ${INPUTFILE_PIXELTYPES_LIST}) ADD_TEST(ioTvMonobandComplex${INPUTFILE_PIXELTYPE}ToImageScalar${READING_PIXELTYPE} ${IO_TESTS21} otbMonobandComplexToImageScalar${READING_PIXELTYPE} - ${INPUTDATA}/monobandComplex${INPUTFILE_PIXELTYPE}.hdr) + ${INPUTDATA}/monobandComplex${INPUTFILE_PIXELTYPE}.tif) #hdr) ADD_TEST(ioTvMonobandComplex${INPUTFILE_PIXELTYPE}ToImageComplex${READING_PIXELTYPE} ${IO_TESTS21} otbMonobandComplexToImageComplex${READING_PIXELTYPE} - ${INPUTDATA}/monobandComplex${INPUTFILE_PIXELTYPE}.hdr) + ${INPUTDATA}/monobandComplex${INPUTFILE_PIXELTYPE}.tif) #hdr) ADD_TEST(ioTvMonobandComplex${INPUTFILE_PIXELTYPE}ToVectorImageScalar${READING_PIXELTYPE} ${IO_TESTS21} otbMonobandComplexToVectorImageScalar${READING_PIXELTYPE} - ${INPUTDATA}/monobandComplex${INPUTFILE_PIXELTYPE}.hdr) + ${INPUTDATA}/monobandComplex${INPUTFILE_PIXELTYPE}.tif) #hdr) ADD_TEST(ioTvMonobandComplex${INPUTFILE_PIXELTYPE}ToVectorImageComplex${READING_PIXELTYPE} ${IO_TESTS21} otbMonobandComplexToVectorImageComplex${READING_PIXELTYPE} - ${INPUTDATA}/monobandComplex${INPUTFILE_PIXELTYPE}.hdr) + ${INPUTDATA}/monobandComplex${INPUTFILE_PIXELTYPE}.tif) #hdr) # Weird case : only the first 2 bands used ADD_TEST(ioTvMultibandScalar${INPUTFILE_PIXELTYPE}ToImageComplex${READING_PIXELTYPE} @@ -2856,12 +2857,12 @@ FOREACH(INPUTFILE_PIXELTYPE ${INPUTFILE_PIXELTYPES_LIST}) # ADD_TEST(ioTvMultibandComplex${INPUTFILE_PIXELTYPE}${NBBANDS}BandsToImageScalar${READING_PIXELTYPE} # ${IO_TESTS21} # otbMultibandComplexToImageScalar${READING_PIXELTYPE} - # ${INPUTDATA}/multibandComplex${INPUTFILE_PIXELTYPE}_${NBBANDS}bands.hdr) + # ${INPUTDATA}/multibandComplex${INPUTFILE_PIXELTYPE}_${NBBANDS}bands.tif) #hdr) ADD_TEST(ioTvMultibandComplex${INPUTFILE_PIXELTYPE}${NBBANDS}BandsToVectorImageScalar${READING_PIXELTYPE} ${IO_TESTS21} otbMultibandComplexToVectorImageScalar${READING_PIXELTYPE} - ${INPUTDATA}/multibandComplex${INPUTFILE_PIXELTYPE}_${NBBANDS}bands.hdr) + ${INPUTDATA}/multibandComplex${INPUTFILE_PIXELTYPE}_${NBBANDS}bands.tif) #hdr) # Weird case : need specifications to write the test # [missing impl] @@ -2870,7 +2871,7 @@ FOREACH(INPUTFILE_PIXELTYPE ${INPUTFILE_PIXELTYPES_LIST}) ADD_TEST(ioTvMultibandComplex${INPUTFILE_PIXELTYPE}${NBBANDS}BandsToVectorImageComplex${READING_PIXELTYPE} ${IO_TESTS21} otbMultibandComplexToVectorImageComplex${READING_PIXELTYPE} - ${INPUTDATA}/multibandComplex${INPUTFILE_PIXELTYPE}_${NBBANDS}bands.hdr) + ${INPUTDATA}/multibandComplex${INPUTFILE_PIXELTYPE}_${NBBANDS}bands.tif) #hdr) ENDFOREACH(NBBANDS ${NBBANDS_LIST}) @@ -2887,8 +2888,8 @@ FOREACH(INPUTFILE_PIXELTYPE ${INPUTFILE_PIXELTYPES_LIST}) ADD_TEST(ioTvGDALReadPxlComplex${INPUTFILE_PIXELTYPE} ${IO_TESTS21} otbGDALReadPxlComplex${INPUTFILE_PIXELTYPE} - ${INPUTDATA}/multibandComplex${INPUTFILE_PIXELTYPE}_3bands - 1 5 10 2) + ${INPUTDATA}/multibandComplex${INPUTFILE_PIXELTYPE}_3bands.tif + 1 5 10 2) #old file hdr sans extesions ENDFOREACH(INPUTFILE_PIXELTYPE ${INPUTFILE_PIXELTYPES_LIST}) diff --git a/Testing/Code/IO/otbComplexImageManipulationTest.cxx b/Testing/Code/IO/otbComplexImageManipulationTest.cxx index 59fab5423b27ca8cc88491c640f3b38f7e65ec4f..468360326dc0a6014df94368939d2d7a9c439ed5 100644 --- a/Testing/Code/IO/otbComplexImageManipulationTest.cxx +++ b/Testing/Code/IO/otbComplexImageManipulationTest.cxx @@ -29,13 +29,26 @@ const double Epsilon = 1.E-6; template<class TPixel> bool IsEqual(TPixel output, TPixel expected) { - typedef typename itk::NumericTraits<TPixel>::RealType RealType; + typedef typename itk::NumericTraits<TPixel>::RealType RealType; - RealType outputReal = output; - RealType expectedReal = expected; + RealType outputReal = static_cast<RealType>(output); + RealType expectedReal = static_cast<RealType>(expected); // avoid division by zero - return output == expected || (vcl_abs(expected - output) / vcl_abs(expected) < Epsilon); + return outputReal == expectedReal || (vcl_abs(expectedReal - outputReal) / vcl_abs(expectedReal) < Epsilon); +} + +template<class TPixel> +bool IsEqual(std::complex<TPixel> output, std::complex<TPixel> expected) +{ + typedef typename itk::NumericTraits<std::complex<TPixel> >::RealType RealType; + typedef typename itk::NumericTraits<std::complex<TPixel> >::ScalarRealType ScalarRealType; + + RealType outputReal ( static_cast<ScalarRealType>(output.real()) , static_cast<ScalarRealType>(output.imag()) ); + RealType expectedReal( static_cast<ScalarRealType>(expected.real()), static_cast<ScalarRealType>(expected.imag()) ); + + // avoid division by zero + return outputReal == expectedReal || (vcl_abs(expectedReal - outputReal) / vcl_abs(expectedReal) < Epsilon); } template<class TInternalPixel> @@ -50,7 +63,6 @@ bool IsEqual(itk::VariableLengthVector<TInternalPixel> output, itk::VariableLeng } - template<class TIndex, class TPixel> bool TestCompare(TIndex idx, TPixel output, TPixel expected) { @@ -145,6 +157,16 @@ int otbMonobandScalarToImageComplexDouble(int argc, char * argv[]) return otbMonobandScalarToImageComplexGeneric<double>(argc, argv); } +int otbMonobandScalarToImageComplexInt(int argc, char * argv[]) +{ + return otbMonobandScalarToImageComplexGeneric<int>(argc, argv); +} + +int otbMonobandScalarToImageComplexShort(int argc, char * argv[]) +{ + return otbMonobandScalarToImageComplexGeneric<short>(argc, argv); +} + /*********** * 2. * Read MonobandComplex as Image<double> @@ -193,6 +215,16 @@ int otbMonobandComplexToImageScalarDouble(int argc, char * argv[]) return otbMonobandComplexToImageScalarGeneric<double>(argc, argv); } +int otbMonobandComplexToImageScalarInt(int argc, char * argv[]) +{ + return otbMonobandComplexToImageScalarGeneric<int>(argc, argv); +} + +int otbMonobandComplexToImageScalarShort(int argc, char * argv[]) +{ + return otbMonobandComplexToImageScalarGeneric<short>(argc, argv); +} + /*********** * 3. * Read Monoband Complex as Image<complex> @@ -237,6 +269,16 @@ int otbMonobandComplexToImageComplexDouble(int argc, char * argv[]) return otbMonobandComplexToImageComplexGeneric<double>(argc, argv); } +int otbMonobandComplexToImageComplexInt(int argc, char * argv[]) +{ + return otbMonobandComplexToImageComplexGeneric<int>(argc, argv); +} + +int otbMonobandComplexToImageComplexShort(int argc, char * argv[]) +{ + return otbMonobandComplexToImageComplexGeneric<short>(argc, argv); +} + /*********** * 4. * Read Monoband Complex as VectorImage<double> @@ -286,6 +328,16 @@ int otbMonobandComplexToVectorImageScalarDouble(int argc, char * argv[]) return otbMonobandComplexToVectorImageScalarGeneric<double>(argc, argv); } +int otbMonobandComplexToVectorImageScalarInt(int argc, char * argv[]) +{ + return otbMonobandComplexToVectorImageScalarGeneric<int>(argc, argv); +} + +int otbMonobandComplexToVectorImageScalarShort(int argc, char * argv[]) +{ + return otbMonobandComplexToVectorImageScalarGeneric<short>(argc, argv); +} + /*********** * 5. * Read Monoband Complex as VectorImage<complex> @@ -334,6 +386,15 @@ int otbMonobandComplexToVectorImageComplexDouble(int argc, char * argv[]) return otbMonobandComplexToVectorImageComplexGeneric<double>(argc, argv); } +int otbMonobandComplexToVectorImageComplexInt(int argc, char * argv[]) +{ + return otbMonobandComplexToVectorImageComplexGeneric<int>(argc, argv); +} + +int otbMonobandComplexToVectorImageComplexShort(int argc, char * argv[]) +{ + return otbMonobandComplexToVectorImageComplexGeneric<short>(argc, argv); +} /*********** * 6. @@ -382,6 +443,16 @@ int otbMultibandScalarToImageComplexDouble(int argc, char * argv[]) return otbMultibandScalarToImageComplexGeneric<double>(argc, argv); } +int otbMultibandScalarToImageComplexInt(int argc, char * argv[]) +{ + return otbMultibandScalarToImageComplexGeneric<int>(argc, argv); +} + +int otbMultibandScalarToImageComplexShort(int argc, char * argv[]) +{ + return otbMultibandScalarToImageComplexGeneric<short>(argc, argv); +} + /*********** * 7. @@ -432,6 +503,16 @@ int otbMultibandScalarToVectorImageComplexDouble(int argc, char * argv[]) return otbMultibandScalarToVectorImageComplexGeneric<double>(argc, argv); } +int otbMultibandScalarToVectorImageComplexInt(int argc, char * argv[]) +{ + return otbMultibandScalarToVectorImageComplexGeneric<int>(argc, argv); +} + +int otbMultibandScalarToVectorImageComplexShort(int argc, char * argv[]) +{ + return otbMultibandScalarToVectorImageComplexGeneric<short>(argc, argv); +} + /*********** * 8. @@ -487,6 +568,16 @@ int otbMultibandComplexToVectorImageScalarDouble(int argc, char * argv[]) return otbMultibandComplexToVectorImageScalarGeneric<double>(argc, argv); } +int otbMultibandComplexToVectorImageScalarInt(int argc, char * argv[]) +{ + return otbMultibandComplexToVectorImageScalarGeneric<int>(argc, argv); +} + +int otbMultibandComplexToVectorImageScalarShort(int argc, char * argv[]) +{ + return otbMultibandComplexToVectorImageScalarGeneric<short>(argc, argv); +} + /*********** * 9. * Read Multiband Complex as VectorImage<complex> @@ -541,6 +632,16 @@ int otbMultibandComplexToVectorImageComplexDouble(int argc, char * argv[]) return otbMultibandComplexToVectorImageComplexGeneric<double>(argc, argv); } +int otbMultibandComplexToVectorImageComplexShort(int argc, char * argv[]) +{ + return otbMultibandComplexToVectorImageComplexGeneric<short>(argc, argv); +} + +int otbMultibandComplexToVectorImageComplexInt(int argc, char * argv[]) +{ + return otbMultibandComplexToVectorImageComplexGeneric<int>(argc, argv); +} + /*********** * 10. * Read Monoband Scalar as VectorImage<complex> @@ -589,6 +690,16 @@ int otbMonobandScalarToVectorImageComplexDouble(int argc, char * argv[]) return otbMonobandScalarToVectorImageComplexGeneric<double>(argc, argv); } +int otbMonobandScalarToVectorImageComplexShort(int argc, char * argv[]) +{ + return otbMonobandScalarToVectorImageComplexGeneric<short>(argc, argv); +} + +int otbMonobandScalarToVectorImageComplexInt(int argc, char * argv[]) +{ + return otbMonobandScalarToVectorImageComplexGeneric<int>(argc, argv); +} + /*********** * 11. * Read MultibandComplex as Image<double> diff --git a/Testing/Code/IO/otbIOTests21.cxx b/Testing/Code/IO/otbIOTests21.cxx index 751ea64be1130d55d4ea366b5bab2d86fbfe792d..f3c2f93afc9748954a82dbe30825f5981063a92f 100644 --- a/Testing/Code/IO/otbIOTests21.cxx +++ b/Testing/Code/IO/otbIOTests21.cxx @@ -57,6 +57,36 @@ void RegisterTests() REGISTER_TEST(otbMonobandScalarToVectorImageComplexDouble); REGISTER_TEST(otbMultibandComplexToImageScalarFloat); REGISTER_TEST(otbMultibandComplexToImageScalarDouble); + //new tests + REGISTER_TEST(otbMonobandScalarToImageComplexInt); + REGISTER_TEST(otbMonobandScalarToImageComplexShort); + + REGISTER_TEST(otbMonobandComplexToImageScalarInt); + REGISTER_TEST(otbMonobandComplexToImageScalarShort); + + REGISTER_TEST(otbMonobandComplexToImageComplexInt); + REGISTER_TEST(otbMonobandComplexToImageComplexShort); + + REGISTER_TEST(otbMonobandComplexToVectorImageScalarInt); + REGISTER_TEST(otbMonobandComplexToVectorImageScalarShort); + + REGISTER_TEST(otbMonobandComplexToVectorImageComplexInt); + REGISTER_TEST(otbMonobandComplexToVectorImageComplexShort); + + REGISTER_TEST(otbMultibandScalarToImageComplexInt); + REGISTER_TEST(otbMultibandScalarToImageComplexShort); + + REGISTER_TEST(otbMultibandScalarToVectorImageComplexInt); + REGISTER_TEST(otbMultibandScalarToVectorImageComplexShort); + + REGISTER_TEST(otbMultibandComplexToVectorImageScalarInt); + REGISTER_TEST(otbMultibandComplexToVectorImageScalarShort); + + REGISTER_TEST(otbMultibandComplexToVectorImageComplexInt); + REGISTER_TEST(otbMultibandComplexToVectorImageComplexShort); + + REGISTER_TEST(otbMonobandScalarToVectorImageComplexInt); + REGISTER_TEST(otbMonobandScalarToVectorImageComplexShort); // Complex tests with GDAL only REGISTER_TEST(otbGDALReadPxlComplexDouble); REGISTER_TEST(otbGDALReadPxlComplexFloat); diff --git a/Utilities/ITK/Code/Common/itkNumericTraits.cxx b/Utilities/ITK/Code/Common/itkNumericTraits.cxx index 8e78a906b148786681a495af99ff7ca6886a4214..41d3b52a1a4ad60d2ee9ce9fa41e47432153150b 100644 --- a/Utilities/ITK/Code/Common/itkNumericTraits.cxx +++ b/Utilities/ITK/Code/Common/itkNumericTraits.cxx @@ -58,6 +58,12 @@ const double NumericTraits<double>::One = 1.0; const long double NumericTraits<long double>::Zero = 0.0; const long double NumericTraits<long double>::One = 1.0; +const std::complex<short> NumericTraits< std::complex<short> >::Zero = std::complex<short>(0,0); +const std::complex<short> NumericTraits< std::complex<short> >::One = std::complex<short>(1,0); + +const std::complex<int> NumericTraits< std::complex<int> >::Zero = std::complex<int>(0,0); +const std::complex<int> NumericTraits< std::complex<int> >::One = std::complex<int>(1,0); + const std::complex<float> NumericTraits< std::complex<float> >::Zero = std::complex<float>(0.0f,0.0f); const std::complex<float> NumericTraits< std::complex<float> >::One = std::complex<float>(1.0f,0.0f); diff --git a/Utilities/ITK/Code/Common/itkNumericTraits.h b/Utilities/ITK/Code/Common/itkNumericTraits.h index 530607baddca3a01feeaa8cb9586927746aff2ed..24954e9632ea2b53a3a621c46b04299a8395d480 100644 --- a/Utilities/ITK/Code/Common/itkNumericTraits.h +++ b/Utilities/ITK/Code/Common/itkNumericTraits.h @@ -534,6 +534,92 @@ public: }; +/** \class NumericTraits< std::complex<short> > + * \brief Define traits for type std::complex<short>. + * \ingroup DataRepresentation + */ +template <> +class NumericTraits< std::complex<short> > { +public: + typedef std::complex<short> TheType; + typedef short ValueType; + typedef TheType PrintType; + typedef double AbsType; + typedef TheType AccumulateType; + typedef std::complex<double> RealType; + typedef double ScalarRealType; + typedef std::complex<float> FloatType; + + static const TheType ITKCommon_EXPORT Zero; + static const TheType ITKCommon_EXPORT One; + + static TheType min() { return TheType(vcl_numeric_limits<ValueType>::min(), + vcl_numeric_limits<ValueType>::min());} + static TheType max() {return TheType(vcl_numeric_limits<ValueType>::max(), + vcl_numeric_limits<ValueType>::max()); } + static TheType min( TheType ) { return TheType(vcl_numeric_limits<ValueType>::min(), + vcl_numeric_limits<ValueType>::min()); } + static TheType max( TheType ) { return TheType(vcl_numeric_limits<ValueType>::max(), + vcl_numeric_limits<ValueType>::max()); } + static TheType NonpositiveMin() { + return TheType(NumericTraits<float>::NonpositiveMin(),NumericTraits<float>::NonpositiveMin()); } + static bool IsPositive(TheType val) { return val.real() > 0.0; } + static bool IsNonpositive(TheType val) { return val.real() <= 0.0; } + static bool IsNegative(TheType val) { return val.real() < 0.0; } + static bool IsNonnegative(TheType val) {return val.real() >= 0.0; } + static TheType ZeroValue() { return Zero; } + static TheType OneValue() { return One; } + static TheType Clamp(TheType val,TheType minVal, TheType maxVal) + { + return TheType(NumericTraits<ValueType>::Clamp(val.real(),minVal.real(),maxVal.real()), + NumericTraits<ValueType>::Clamp(val.imag(),minVal.imag(),maxVal.imag())); + } + +}; + +/** \class NumericTraits< std::complex<int> > + * \brief Define traits for type std::complex<int>. + * \ingroup DataRepresentation + */ +template <> +class NumericTraits< std::complex<int> > { +public: + typedef std::complex<int> TheType; + typedef int ValueType; + typedef TheType PrintType; + typedef double AbsType; // or int ? + typedef TheType AccumulateType; + typedef std::complex<double> RealType; // or std::complex<int> + typedef double ScalarRealType; // or int + typedef std::complex<float> FloatType; + + static const TheType ITKCommon_EXPORT Zero; + static const TheType ITKCommon_EXPORT One; + + static TheType min() { return TheType(vcl_numeric_limits<ValueType>::min(), + vcl_numeric_limits<ValueType>::min());} + static TheType max() {return TheType(vcl_numeric_limits<ValueType>::max(), + vcl_numeric_limits<ValueType>::max()); } + static TheType min( TheType ) { return TheType(vcl_numeric_limits<ValueType>::min(), + vcl_numeric_limits<ValueType>::min()); } + static TheType max( TheType ) { return TheType(vcl_numeric_limits<ValueType>::max(), + vcl_numeric_limits<ValueType>::max()); } + static TheType NonpositiveMin() { + return TheType(NumericTraits<float>::NonpositiveMin(),NumericTraits<float>::NonpositiveMin()); } + static bool IsPositive(TheType val) { return val.real() > 0.0; } + static bool IsNonpositive(TheType val) { return val.real() <= 0.0; } + static bool IsNegative(TheType val) { return val.real() < 0.0; } + static bool IsNonnegative(TheType val) {return val.real() >= 0.0; } + static TheType ZeroValue() { return Zero; } + static TheType OneValue() { return One; } + static TheType Clamp(TheType val,TheType minVal, TheType maxVal) + { + return TheType(NumericTraits<ValueType>::Clamp(val.real(),minVal.real(),maxVal.real()), + NumericTraits<ValueType>::Clamp(val.imag(),minVal.imag(),maxVal.imag())); + } + +}; + /** \class NumericTraits< std::complex<float> > * \brief Define traits for type std::complex<float>. * \ingroup DataRepresentation diff --git a/Utilities/ITK/Code/IO/itkDefaultConvertPixelTraits.h b/Utilities/ITK/Code/IO/itkDefaultConvertPixelTraits.h index 6f7709a132fbed0b9cdb57d205093ae923cc4ba7..81210f1940f7ce33f456e4ffd98e25e2e57bda0f 100644 --- a/Utilities/ITK/Code/IO/itkDefaultConvertPixelTraits.h +++ b/Utilities/ITK/Code/IO/itkDefaultConvertPixelTraits.h @@ -310,6 +310,7 @@ ITK_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(float); ITK_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(double); ITK_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(signed int); ITK_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(unsigned int); +ITK_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(short int); ITK_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(signed char); ITK_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(unsigned char); ITK_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(signed long);