diff --git a/Code/FeatureExtraction/otbImageFunctionAdapter.h b/Code/FeatureExtraction/otbImageFunctionAdapter.h index 862ae9a644cc3409aadaada845ff0d0d81b9adc9..e66a57bda16d77b24d45b036b0ae6f954c7c5aa6 100644 --- a/Code/FeatureExtraction/otbImageFunctionAdapter.h +++ b/Code/FeatureExtraction/otbImageFunctionAdapter.h @@ -68,7 +68,7 @@ class ITK_EXPORT ImageFunctionAdapterBase : typedef typename Superclass::OutputType OutputType; typedef typename OutputType::ValueType OutputValueType; - // Template Partial Specialazation Specific typedef // + // Template Partial Specialization Specific typedef // typedef TInternalImageFunctionType InternalImageFunctionType; typedef typename InternalImageFunctionType::Pointer InternalImageFunctionPointerType; @@ -196,7 +196,7 @@ public: typedef typename Superclass::IndexType IndexType; typedef typename Superclass::ContinuousIndexType ContinuousIndexType; typedef typename Superclass::OutputType OutputType; - // Template Partial Specialazation Specific typedef // + // Template Partial Specialization Specific typedef // typedef typename Superclass::InternalImageFunctionType InternalImageFunctionType; // Evalulate the function at specified index // @@ -241,7 +241,7 @@ public: typedef typename Superclass::IndexType IndexType; typedef typename Superclass::ContinuousIndexType ContinuousIndexType; typedef typename Superclass::OutputType OutputType; - // Template Partial Specialazation Specific typedef // + // Template Partial Specialization Specific typedef // typedef typename Superclass::InternalImageFunctionType InternalImageFunctionType; // Evalulate the function at specified index // @@ -286,7 +286,7 @@ public: typedef typename Superclass::IndexType IndexType; typedef typename Superclass::ContinuousIndexType ContinuousIndexType; typedef typename Superclass::OutputType OutputType; - // Template Partial Specialazation Specific typedef // + // Template Partial Specialization Specific typedef // typedef typename Superclass::InternalImageFunctionType InternalImageFunctionType; // Evalulate the function at specified index // @@ -331,7 +331,7 @@ public: typedef typename Superclass::IndexType IndexType; typedef typename Superclass::ContinuousIndexType ContinuousIndexType; typedef typename Superclass::OutputType OutputType; - // Template Partial Specialazation Specific typedef // + // Template Partial Specialization Specific typedef // typedef typename Superclass::InternalImageFunctionType InternalImageFunctionType; // Evalulate the function at specified index // @@ -376,7 +376,7 @@ public: typedef typename Superclass::IndexType IndexType; typedef typename Superclass::ContinuousIndexType ContinuousIndexType; typedef typename Superclass::OutputType OutputType; - // Template Partial Specialazation Specific typedef // + // Template Partial Specialization Specific typedef // typedef typename Superclass::InternalImageFunctionType InternalImageFunctionType; // Evalulate the function at specified index // @@ -421,7 +421,7 @@ public: typedef typename Superclass::IndexType IndexType; typedef typename Superclass::ContinuousIndexType ContinuousIndexType; typedef typename Superclass::OutputType OutputType; - // Template Partial Specialazation Specific typedef // + // Template Partial Specialization Specific typedef // typedef typename Superclass::InternalImageFunctionType InternalImageFunctionType; // Evalulate the function at specified index // @@ -467,7 +467,7 @@ public: typedef typename Superclass::IndexType IndexType; typedef typename Superclass::ContinuousIndexType ContinuousIndexType; typedef typename Superclass::OutputType OutputType; - // Template Partial Specialazation Specific typedef + // Template Partial Specialization Specific typedef typedef typename Superclass::InternalImageFunctionType InternalImageFunctionType; // Evalulate the function at specified index // diff --git a/Code/IO/otbGDALImageIO.cxx b/Code/IO/otbGDALImageIO.cxx index 62f31d56e764796e961478764bbcf45cfd67cffb..9fb774a81f2f172a2d1fc776d3b0b3fc7905ccbf 100644 --- a/Code/IO/otbGDALImageIO.cxx +++ b/Code/IO/otbGDALImageIO.cxx @@ -185,6 +185,7 @@ GDALImageIO::GDALImageIO() m_FlagWriteImageInformation = true; m_CanStreamWrite = false; + m_IsComplex = false; } GDALImageIO::~GDALImageIO() @@ -241,7 +242,7 @@ void GDALImageIO::Read(void* buffer) std::streamoff cpt(0); GDALDataset* dataset = m_Dataset->GetDataSet(); - if (GDALDataTypeIsComplex(m_PxType)) + if (GDALDataTypeIsComplex(m_PxType) && !m_IsComplex) { lCrGdal = dataset->GetRasterBand(1)->RasterIO(GF_Read, lFirstColumn, @@ -341,7 +342,7 @@ void GDALImageIO::ReadImageInformation() void GDALImageIO::InternalReadImageInformation() { GDALDataset* dataset = m_Dataset->GetDataSet(); - otbMsgDevMacro(<< " GCPCount (original): " << m_poDataset->GetGCPCount()); +// otbMsgDevMacro(<< " GCPCount (original): " << m_Dataset->GetGCPCount()); // Get image dimensions if ( dataset->GetRasterXSize() == 0 || dataset->GetRasterYSize() == 0 ) @@ -422,7 +423,7 @@ void GDALImageIO::InternalReadImageInformation() { SetComponentType(INT); } - else if ((m_PxType == GDT_Float32) || (m_PxType == GDT_CFloat32)) + else if (m_PxType == GDT_Float32) { SetComponentType(FLOAT); } @@ -430,6 +431,10 @@ void GDALImageIO::InternalReadImageInformation() { SetComponentType(DOUBLE); } + else if (m_PxType == GDT_CFloat32) + { + SetComponentType(CFLOAT); + } else { itkExceptionMacro(<< "Pixel type unknown"); @@ -438,34 +443,47 @@ void GDALImageIO::InternalReadImageInformation() if (this->GetComponentType() == CHAR) { m_NbOctetPixel = 1; + m_IsComplex = false; } else if (this->GetComponentType() == UCHAR) { m_NbOctetPixel = 1; + m_IsComplex = false; } else if (this->GetComponentType() == USHORT) { m_NbOctetPixel = 2; + m_IsComplex = false; } else if (this->GetComponentType() == SHORT) { m_NbOctetPixel = 2; + m_IsComplex = false; } else if (this->GetComponentType() == INT) { m_NbOctetPixel = 4; + m_IsComplex = false; } else if (this->GetComponentType() == UINT) { m_NbOctetPixel = 4; + m_IsComplex = false; } else if (this->GetComponentType() == FLOAT) { m_NbOctetPixel = 4; + m_IsComplex = false; } else if (this->GetComponentType() == DOUBLE) { m_NbOctetPixel = 8; + m_IsComplex = false; + } + else if (this->GetComponentType() == CFLOAT) + { + m_NbOctetPixel = sizeof(std::complex<float>); + m_IsComplex = true; } else { @@ -475,8 +493,9 @@ void GDALImageIO::InternalReadImageInformation() /******************************************************************/ // Pixel Type always set to Scalar for GDAL ? maybe also to vector ? - // Modif Patrick: LIRE LES IMAGES COMPLEXES - if (GDALDataTypeIsComplex(m_PxType)) + //Once all sorts of gdal complex image are handle, this won't be + //necessary any more + if (GDALDataTypeIsComplex(m_PxType) && (m_PxType != GDT_CFloat32)) { m_NbOctetPixel = m_NbOctetPixel * 2; this->SetNumberOfComponents(2); diff --git a/Code/IO/otbGDALImageIO.h b/Code/IO/otbGDALImageIO.h index ceff6ea357b403d7d51105efdeea91a3ce5dc561..8b90c414343dd48714c4b94a37eb8adfca577458 100644 --- a/Code/IO/otbGDALImageIO.h +++ b/Code/IO/otbGDALImageIO.h @@ -156,6 +156,7 @@ private: bool m_FlagWriteImageInformation; bool m_CanStreamWrite; + bool m_IsComplex; }; } // end namespace otb diff --git a/Testing/Code/IO/CMakeLists.txt b/Testing/Code/IO/CMakeLists.txt index 51191f4627c5871e95e5be235be758e45d9179af..bfbaabe03257d86e63d2dc78ff578155ce708e3b 100644 --- a/Testing/Code/IO/CMakeLists.txt +++ b/Testing/Code/IO/CMakeLists.txt @@ -1124,10 +1124,10 @@ ENDIF(OTB_DATA_USE_LARGEINPUT) ADD_TEST(ioTuVectorImageComplexNew ${IO_TESTS9} otbVectorImageComplexNew) -#ADD_TEST(ioTuVectorImageComplexTest ${IO_TESTS9} -# otbVectorImageComplexTest -#dual pol image -#) +ADD_TEST(ioTuVectorImageComplexTest ${IO_TESTS9} + otbVectorImageComplexTest + ${INPUTDATA}/multibandComplex.hdr +) # --- otb::VectorImageReadWriteTest --- ADD_TEST(ioTvVectorImageFileReaderWriterTest ${IO_TESTS9} diff --git a/Testing/Code/IO/otbVectorImageTest.cxx b/Testing/Code/IO/otbVectorImageTest.cxx index c5b0821987173c27eafddd8beb0d3122ff446462..5b16aa76dcc2987fcefa1ab85a64ba7e1367a03f 100644 --- a/Testing/Code/IO/otbVectorImageTest.cxx +++ b/Testing/Code/IO/otbVectorImageTest.cxx @@ -146,11 +146,13 @@ int otbVectorImageComplexTest(int argc, char* argv[]) reader->SetFileName(argv[1]); reader->UpdateOutputInformation(); std::cout << reader->GetOutput()->GetNumberOfComponentsPerPixel() << std::endl; - + itk::ImageIOBase::Pointer io = reader->GetImageIO(); + std::cout << io << std::endl; reader->Update(); ImageType::IndexType index; index[0]=0; index[1]=0; + std::cout << reader->GetOutput()->GetPixel(index) << std::endl; return EXIT_SUCCESS; diff --git a/Utilities/ITK/Code/IO/itkConvertPixelBuffer.h b/Utilities/ITK/Code/IO/itkConvertPixelBuffer.h index 4079f400489ad40e057e6c48e0d788cfdf59bd7d..30cf712f84e8b76a285a54c3ac31680db16a278d 100644 --- a/Utilities/ITK/Code/IO/itkConvertPixelBuffer.h +++ b/Utilities/ITK/Code/IO/itkConvertPixelBuffer.h @@ -51,6 +51,13 @@ public: static void ConvertVectorImage(InputPixelType* inputData, int inputNumberOfComponents, OutputPixelType* outputData , size_t size); + static void ConvertComplexVectorImageToVectorImage(std::complex<InputPixelType>* inputData, + int inputNumberOfComponents, + OutputPixelType* outputData , size_t size); + static void ConvertComplexToGray(std::complex<InputPixelType>* inputData, + int inputNumberOfComponents, + OutputPixelType* outputData , size_t size); + protected: /** Convert to Gray output. */ /** Input values are cast to output values. */ diff --git a/Utilities/ITK/Code/IO/itkConvertPixelBuffer.txx b/Utilities/ITK/Code/IO/itkConvertPixelBuffer.txx index f36a1bfdc1c5bf170fa509a04810f034ffa89454..58142ed6965f33d0af07848e6f5660112adc5862 100644 --- a/Utilities/ITK/Code/IO/itkConvertPixelBuffer.txx +++ b/Utilities/ITK/Code/IO/itkConvertPixelBuffer.txx @@ -595,6 +595,27 @@ ConvertPixelBuffer<InputPixelType, OutputPixelType, OutputConvertTraits> } } +template < typename InputPixelType, + typename OutputPixelType, + class OutputConvertTraits + > +void +ConvertPixelBuffer<InputPixelType, OutputPixelType, OutputConvertTraits> +::ConvertComplexToGray(std::complex<InputPixelType>* inputData, + int inputNumberOfComponents, + OutputPixelType* outputData , size_t size) +{ + std::complex<InputPixelType>* endInput = inputData + size; + while(inputData != endInput) + { + OutputConvertTraits::SetNthComponent(0, *outputData, + static_cast<OutputComponentType> + (std::norm(*inputData))); + inputData++; + outputData++; + } +} + template < typename InputPixelType, typename OutputPixelType, @@ -697,6 +718,41 @@ ConvertPixelBuffer<InputPixelType, OutputPixelType, OutputConvertTraits> } } +/* To be able to convert transparently*/ + +template<typename InputType, typename OutputType> +OutputType +SpecialCast(const std::complex<InputType>& in, const OutputType& dummy) +{ + return static_cast < OutputType >( in.real() ); +} + +template<typename InputType, typename OutputType> +std::complex<OutputType> +SpecialCast(const std::complex<InputType>& in, const std::complex<OutputType>& dummy) +{ + return static_cast < std::complex<OutputType> >( in ); +} + +template < typename InputPixelType, + typename OutputPixelType, + class OutputConvertTraits > +void +ConvertPixelBuffer<InputPixelType, OutputPixelType, OutputConvertTraits> +::ConvertComplexVectorImageToVectorImage(std::complex<InputPixelType>* inputData, + int inputNumberOfComponents, + OutputPixelType* outputData , size_t size) +{ + size_t length = size* (size_t)inputNumberOfComponents; + OutputPixelType dummy; + for( size_t i=0; i< length; i++ ) + { + OutputConvertTraits::SetNthComponent( 0, *outputData, + SpecialCast(*inputData, dummy)); + ++outputData; + ++inputData; + } +} }// end namespace itk diff --git a/Utilities/ITK/Code/IO/itkDefaultConvertPixelTraits.h b/Utilities/ITK/Code/IO/itkDefaultConvertPixelTraits.h index 3807aad5e23153d7ad3eba49169973ec5dcd593b..1636f637b0afd737ffdde312c45ff42514998bf9 100644 --- a/Utilities/ITK/Code/IO/itkDefaultConvertPixelTraits.h +++ b/Utilities/ITK/Code/IO/itkDefaultConvertPixelTraits.h @@ -54,6 +54,8 @@ public: /** Set the nth component of the pixel. */ static void SetNthComponent(int c, PixelType& pixel, const ComponentType& v) { pixel.SetNthComponent(c, v); } + static void SetNthComponent(int c, PixelType & pixel, const PixelType& v) + { pixel = v; } /** Return a single scalar value from this pixel. */ static ComponentType GetScalarValue(const PixelType& pixel) @@ -115,6 +117,10 @@ public: \ { \ pixel[i] = v; \ } \ + static void SetNthComponent(int i, TargetType & pixel, const TargetType& v) \ + { \ + pixel = v; \ + } \ static ComponentType GetScalarValue(const TargetType& pixel) \ { \ return pixel[0]; \ @@ -148,6 +154,10 @@ public: \ { \ pixel[i] = v; \ } \ + static void SetNthComponent(int i, TargetType & pixel, const TargetType& v) \ + { \ + pixel = v; \ + } \ static ComponentType GetScalarValue(const TargetType& pixel) \ { \ return pixel[0]; \ @@ -213,6 +223,10 @@ public: \ const unsigned int col = i % cols; \ pixel[row][col] = v; \ } \ + static void SetNthComponent(int i, TargetType & pixel, const TargetType& v) \ + { \ + pixel = v; \ + } \ static ComponentType GetScalarValue(const TargetType& pixel) \ { \ return pixel[0][0]; \ @@ -282,6 +296,10 @@ public: \ pixel = TargetType( pixel.real(), v ); \ } \ } \ + static void SetNthComponent(int i, TargetType & pixel, const TargetType& v) \ + { \ + pixel = v; \ + } \ static ComponentType GetScalarValue(const TargetType& pixel) \ { \ return std::norm(pixel); \ diff --git a/Utilities/ITK/Code/IO/itkImageFileReader.txx b/Utilities/ITK/Code/IO/itkImageFileReader.txx index 9099fe63e8d242d2bc7a6df823068c7360f51f07..d349482f5fcb70652923a53325b776a28f14e0ae 100644 --- a/Utilities/ITK/Code/IO/itkImageFileReader.txx +++ b/Utilities/ITK/Code/IO/itkImageFileReader.txx @@ -529,6 +529,37 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> numberOfPixels); \ } \ } +#define ITK_CONVERT_CBUFFER_IF_BLOCK(type) \ + else if( m_ImageIO->GetComponentTypeInfo() == typeid(type) ) \ + { \ + if( strcmp( this->GetOutput()->GetNameOfClass(), "VectorImage" ) == 0 ) \ + { \ + ConvertPixelBuffer< \ + type::value_type, \ + OutputImagePixelType, \ + ConvertPixelTraits \ + > \ + ::ConvertComplexVectorImageToVectorImage( \ + static_cast<type*>(inputData), \ + m_ImageIO->GetNumberOfComponents(), \ + outputData, \ + numberOfPixels); \ + } \ + else \ + { \ + ConvertPixelBuffer< \ + type::value_type, \ + OutputImagePixelType, \ + ConvertPixelTraits \ + > \ + ::ConvertComplexToGray( \ + static_cast<type*>(inputData), \ + m_ImageIO->GetNumberOfComponents(), \ + outputData, \ + numberOfPixels); \ + } \ + } + if(0) { } @@ -542,6 +573,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> ITK_CONVERT_BUFFER_IF_BLOCK( long) ITK_CONVERT_BUFFER_IF_BLOCK(float) ITK_CONVERT_BUFFER_IF_BLOCK( double) + ITK_CONVERT_CBUFFER_IF_BLOCK(std::complex<float>) else { ImageFileReaderException e(__FILE__, __LINE__); @@ -567,6 +599,7 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> return; } #undef ITK_CONVERT_BUFFER_IF_BLOCK +#undef ITK_CONVERT_CBUFFER_IF_BLOCK } diff --git a/Utilities/ITK/Code/IO/itkImageIOBase.cxx b/Utilities/ITK/Code/IO/itkImageIOBase.cxx index 1fc2c4a446f9d1a43d4d2e64921b5afa4670aa2e..e26bb93c2178952dab93fe5490ec45d2a3acf7cb 100644 --- a/Utilities/ITK/Code/IO/itkImageIOBase.cxx +++ b/Utilities/ITK/Code/IO/itkImageIOBase.cxx @@ -204,6 +204,8 @@ const std::type_info& ImageIOBase::GetComponentTypeInfo() const return typeid(float); case DOUBLE: return typeid(double); + case CFLOAT: + return typeid(std::complex<float>); case UNKNOWNCOMPONENTTYPE: default: itkExceptionMacro ("Unknown component type: " << m_ComponentType); @@ -441,7 +443,8 @@ bool ImageIOBase::SetPixelTypeInfo(const std::type_info& ptype) !itkSetPixelType(this,ptype,ImageIOBase::LONG,(long)(0)) && !itkSetPixelType(this,ptype,ImageIOBase::ULONG,(unsigned long)(0)) && !itkSetPixelType(this,ptype,ImageIOBase::FLOAT,(float)(0)) && - !itkSetPixelType(this,ptype,ImageIOBase::DOUBLE,(double)(0)) ) + !itkSetPixelType(this,ptype,ImageIOBase::DOUBLE,(double)(0)) && + !itkSetPixelType(this,ptype,ImageIOBase::CFLOAT,(std::complex<float>)(0)) ) { if ( ptype == typeid(Offset<2>) ) { @@ -647,6 +650,8 @@ unsigned int ImageIOBase::GetComponentSize() const return sizeof(float); case DOUBLE: return sizeof(double); + case CFLOAT: + return sizeof(std::complex<float>); case UNKNOWNCOMPONENTTYPE: default: itkExceptionMacro ("Unknown component type: " << m_ComponentType); @@ -712,6 +717,8 @@ std::string ImageIOBase::GetComponentTypeAsString(IOComponentType t) const return (s = "float"); case DOUBLE: return (s = "double"); + case CFLOAT: + return (s = "complex_float"); case UNKNOWNCOMPONENTTYPE: default: return (s = "unknown"); @@ -852,6 +859,14 @@ void ImageIOBase::WriteBufferAsASCII(std::ostream& os, const void *buffer, } break; + case CFLOAT: + { + typedef const std::complex<float> * Type; + Type buf = reinterpret_cast<Type>(buffer); + WriteBuffer(os, buf, numComp); + } + break; + default: break; } @@ -948,6 +963,13 @@ void ImageIOBase::ReadBufferAsASCII(std::istream& is, void *buffer, } break; + case CFLOAT: + { + std::complex<float> *buf = reinterpret_cast<std::complex<float>*>(buffer); + ReadBuffer(is, buf, numComp); + } + break; + default: break; } diff --git a/Utilities/ITK/Code/IO/itkImageIOBase.h b/Utilities/ITK/Code/IO/itkImageIOBase.h index 854f826e9268739e6ea68940f75beb402c61c059..8d2a190aafd42f53019fca5f6232421692db0928 100644 --- a/Utilities/ITK/Code/IO/itkImageIOBase.h +++ b/Utilities/ITK/Code/IO/itkImageIOBase.h @@ -92,7 +92,7 @@ public: * SCALAR pixel type or elements of a compound pixel. */ typedef enum {UNKNOWNCOMPONENTTYPE,UCHAR,CHAR,USHORT,SHORT,UINT,INT, - ULONG,LONG, FLOAT,DOUBLE} IOComponentType; + ULONG,LONG, FLOAT,DOUBLE, CFLOAT} IOComponentType; /** Set/Get the number of independent variables (dimensions) in the * image being read or written. Note this is not necessarily what