From 98a43139c2c9d67e51ef31965d44e639399a3d2e Mon Sep 17 00:00:00 2001 From: Emmanuel Christophe <emmanuel.christophe@orfeo-toolbox.org> Date: Wed, 15 Sep 2010 16:04:14 +0800 Subject: [PATCH] ENH: add convenient class to form intensity images from complex data --- .../otbComplexToIntensityImageFilter.h | 107 +++++++++++++ Testing/Code/BasicFilters/CMakeLists.txt | 4 + .../BasicFilters/otbBasicFiltersTests13.cxx | 1 + .../otbComplexToIntensityFilterTest.cxx | 150 ++++++++++++++++++ 4 files changed, 262 insertions(+) create mode 100644 Code/BasicFilters/otbComplexToIntensityImageFilter.h create mode 100644 Testing/Code/BasicFilters/otbComplexToIntensityFilterTest.cxx diff --git a/Code/BasicFilters/otbComplexToIntensityImageFilter.h b/Code/BasicFilters/otbComplexToIntensityImageFilter.h new file mode 100644 index 0000000000..2a0d4af5f8 --- /dev/null +++ b/Code/BasicFilters/otbComplexToIntensityImageFilter.h @@ -0,0 +1,107 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef __otbComplexToIntensityImageFilter_h +#define __otbComplexToIntensityImageFilter_h + +#include "itkUnaryFunctorImageFilter.h" +#include "vnl/vnl_math.h" + +namespace otb +{ + +/** \class ComplexToIntensityImageFilter + * \brief Computes pixel-wise the intensity of a complex image. + * + * \sa ComplexToPhaseImageFilter ComplexToModulusImageFilter + * \ingroup IntensityImageFilters Multithreaded + */ + +namespace Function { + +template< class TInput, class TOutput> +class ComplexToIntensity +{ +public: + ComplexToIntensity() {} + ~ComplexToIntensity() {} + bool operator!=( const ComplexToIntensity & ) const + { + return false; + } + bool operator==( const ComplexToIntensity & other ) const + { + return !(*this != other); + } + inline TOutput operator()( const TInput & A ) const + { + return (TOutput)( A.real()*A.real() + A.imag()*A.imag() ); + } +}; +} + +template <class TInputImage, class TOutputImage> +class ITK_EXPORT ComplexToIntensityImageFilter : + public +itk::UnaryFunctorImageFilter<TInputImage,TOutputImage, + Function::ComplexToIntensity< + typename TInputImage::PixelType, + typename TOutputImage::PixelType> > +{ +public: + /** Standard class typedefs. */ + typedef ComplexToIntensityImageFilter Self; + typedef itk::UnaryFunctorImageFilter< + TInputImage,TOutputImage, + Function::ComplexToIntensity< typename TInputImage::PixelType, + typename TOutputImage::PixelType> > + Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Runtime information support. */ + itkTypeMacro(ComplexToIntensityImageFilter, + UnaryFunctorImageFilter); + + typedef typename TInputImage::PixelType InputPixelType; + typedef typename TOutputImage::PixelType OutputPixelType; + typedef typename itk::NumericTraits< InputPixelType >::ValueType InputPixelValueType; + +#ifdef ITK_USE_CONCEPT_CHECKING + /** Begin concept checking */ + itkConceptMacro(InputConvertibleToOutputCheck, + (itk::Concept::Convertible<InputPixelValueType, OutputPixelType>)); + /** End concept checking */ +#endif + + +protected: + ComplexToIntensityImageFilter() {} + virtual ~ComplexToIntensityImageFilter() {} + +private: + ComplexToIntensityImageFilter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + +}; + +} // end namespace otb + +#endif diff --git a/Testing/Code/BasicFilters/CMakeLists.txt b/Testing/Code/BasicFilters/CMakeLists.txt index c77b69dd19..e0c95e81d5 100644 --- a/Testing/Code/BasicFilters/CMakeLists.txt +++ b/Testing/Code/BasicFilters/CMakeLists.txt @@ -1678,6 +1678,9 @@ ADD_TEST(bfTuBandMathImageFilter ${BASICFILTERS_TESTS13} ADD_TEST(bfTvBandMathImageFilter ${BASICFILTERS_TESTS13} otbBandMathImageFilter) +ADD_TEST(bfTvComplexToIntensityFilterTest ${BASICFILTERS_TESTS13} + otbComplexToIntensityFilterTest) + # A enrichir SET(BasicFilters_SRCS1 @@ -1922,6 +1925,7 @@ otbImageAndVectorImageOperationFilterTest.cxx SET(BasicFilters_SRCS13 otbBasicFiltersTests13.cxx otbBandMathImageFilter.cxx +otbComplexToIntensityFilterTest.cxx ) diff --git a/Testing/Code/BasicFilters/otbBasicFiltersTests13.cxx b/Testing/Code/BasicFilters/otbBasicFiltersTests13.cxx index 2d5eab2544..9974b1467b 100644 --- a/Testing/Code/BasicFilters/otbBasicFiltersTests13.cxx +++ b/Testing/Code/BasicFilters/otbBasicFiltersTests13.cxx @@ -28,4 +28,5 @@ void RegisterTests() { REGISTER_TEST(otbBandMathImageFilterNew); REGISTER_TEST(otbBandMathImageFilter); + REGISTER_TEST(otbComplexToIntensityFilterTest); } diff --git a/Testing/Code/BasicFilters/otbComplexToIntensityFilterTest.cxx b/Testing/Code/BasicFilters/otbComplexToIntensityFilterTest.cxx new file mode 100644 index 0000000000..aeae0a45f1 --- /dev/null +++ b/Testing/Code/BasicFilters/otbComplexToIntensityFilterTest.cxx @@ -0,0 +1,150 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + + + +#include "otbImage.h" +#include "otbComplexToIntensityImageFilter.h" +#include "itkImageRegionIteratorWithIndex.h" +#include "itkSubtractImageFilter.h" + + +int otbComplexToIntensityFilterTest(int, char* [] ) +{ + + // Define the dimension of the images + const unsigned int ImageDimension = 2; + + // Declare the types of the images + typedef std::complex<float> InputPixelType; + + typedef otb::Image<InputPixelType, ImageDimension> InputImageType; + typedef otb::Image<float, ImageDimension> OutputImageType; + + + + // Declare Iterator types apropriated for each image + typedef itk::ImageRegionIteratorWithIndex< + InputImageType> InputIteratorType; + + typedef itk::ImageRegionIteratorWithIndex< + OutputImageType> OutputIteratorType; + + + + // Declare the type of the index to access images + typedef itk::Index<ImageDimension> IndexType; + + // Declare the type of the size + typedef itk::Size<ImageDimension> SizeType; + + // Declare the type of the Region + typedef itk::ImageRegion<ImageDimension> RegionType; + + // Create two images + InputImageType::Pointer inputImage = InputImageType::New(); + + // Define their size, and start index + SizeType size; + size[0] = 2; + size[1] = 2; + + IndexType start; + start[0] = 0; + start[1] = 0; + + RegionType region; + region.SetIndex( start ); + region.SetSize( size ); + + // Initialize Image A + inputImage->SetLargestPossibleRegion( region ); + inputImage->SetBufferedRegion( region ); + inputImage->SetRequestedRegion( region ); + inputImage->Allocate(); + // Create one iterator for the Input Image (this is a light object) + InputIteratorType it( inputImage, inputImage->GetBufferedRegion() ); + + // Initialize the content of Image A + InputPixelType value( 13, 25); + std::cout << "Content of the Input " << std::endl; + it.GoToBegin(); + while( !it.IsAtEnd() ) + { + it.Set( value ); + std::cout << it.Get() << std::endl; + ++it; + } + + // Declare the type for the ComplexToIntensity filter + typedef otb::ComplexToIntensityImageFilter< InputImageType, + OutputImageType > FilterType; + + + // Create an ADD Filter + FilterType::Pointer filter = FilterType::New(); + + + // Connect the input images + filter->SetInput( inputImage ); + + // Get the Smart Pointer to the Filter Output + OutputImageType::Pointer outputImage = filter->GetOutput(); + + + // Execute the filter + filter->Update(); + + // Create an iterator for going through the image output + OutputIteratorType ot(outputImage, outputImage->GetRequestedRegion()); + + // Check the content of the result image + std::cout << "Verification of the output " << std::endl; + const OutputImageType::PixelType epsilon = 1e-6; + ot.GoToBegin(); + it.GoToBegin(); + while( !ot.IsAtEnd() ) + { + const InputImageType::PixelType input = it.Get(); + const OutputImageType::PixelType output = ot.Get(); + + double intensityd = input.real()*input.real() + input.imag()*input.imag(); + + const OutputImageType::PixelType intensity = + static_cast<OutputImageType::PixelType>( intensityd ); + + std::cout << output << " = "; + std::cout << intensity << std::endl; + + if( vcl_fabs( intensity - output ) > epsilon ) + { + std::cerr << "Error in itkComplexToIntensityImageFilterTest " << std::endl; + std::cerr << " intensity( " << input << ") = " << intensity << std::endl; + std::cerr << " differs from " << output; + std::cerr << " by more than " << epsilon << std::endl; + return EXIT_FAILURE; + } + ++ot; + ++it; + } + + return EXIT_SUCCESS; +} -- GitLab