diff --git a/Code/MultiScale/otbProfileToProfileDerivativeFilter.h b/Code/MultiScale/otbProfileToProfileDerivativeFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..147bfd030bc05ac975baa1ab42aa3c86eb714bb3 --- /dev/null +++ b/Code/MultiScale/otbProfileToProfileDerivativeFilter.h @@ -0,0 +1,106 @@ +/*========================================================================= + +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 _otbProfileToProfileDerivativeFilter_h +#define _otbProfileToProfileDerivativeFilter_h + +#include "otbImageListToImageListFilter.h" +#include "itkSubtractImageFilter.h" +#include "itkAbsImageFilter.h" + +namespace otb +{ +/** \class ProfileToProfileDerivativeFilter + * \brief This filter computes the derivative of a given profile. + * + * For the profile \f$ \Pi_{\phi}(f)= \{\phi_{n}(f), n \in \{n_{1},\ldots,n_{N}\}\}\f$, the + * profile derivative is defined by: + * + * \f[ + * \Delta\Pi_{\phi}(f)= \{\Delta\phi_{n}(f), n \in \{n_{1},\ldots,n_{N}\}\} + * \f] + * + * with \f$ \Delta\phi_{n}(f) = \mid \Pi_{\phi_{n2}}(f)-\Pi_{\phi_{n1}}(f) \mid \f$ + * + * \ingroup Streamed + */ +template <class TInputImage, class TOutputImage> +class ITK_EXPORT ProfileToProfileDerivativeFilter + : public ImageListToImageListFilter<TInputImage,TOutputImage> +{ + public: + /** Standard typedefs */ + typedef ProfileToProfileDerivativeFilter Self; + typedef ImageListToImageListFilter<TInputImage,TOutputImage> Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Type macro */ + itkNewMacro(Self); + + /** Creation through object factory macro */ + itkTypeMacro(ProfileToProfileDerivativeFilter, ImageListToImageListFilter); + + /** Template parameters typedefs */ + typedef TInputImage InputImageType; + typedef typename InputImageType::Pointer InputImagePointerType; + typedef typename Superclass::InputImageListType InputImageListType; + typedef typename InputImageListType::Pointer InputImageListPointerType; + typedef typename InputImageListType::ImageType InputImageType; + typedef TOutputImage OutputImageType; + typedef typename Superclass::OutputImageListType OutputImageListType; + typedef typename OutputImageListType::Pointer OutputImageListPointerType; + typedef typename OutputImageListType::ImageType OutputImageType; + + /** typedefs of the filters used for the derivative */ + typedef itk::SubtractImageFilter<InputImageType,InputImageType,InputImageType> SubtractFilterType; + typedef itk::AbsImageFilter<InputImageType,InputImageType> AbsFilterType; + typedef typename SubtractFilterType::Pointer SubtractFilterPointerType; + typedef typename AbsFilterType::Pointer AbsFilterPointerType; + + /** Generate output information for the ImageList and for each image + in the list. */ + virtual void GenerateOutputInformation(void); + + /** Generate input requested region for each image in the list. */ + virtual void GenerateInputRequestedRegion(void); + +protected: + /** Main computation method */ + virtual void GenerateData(void); + /** Constructor */ + ProfileToProfileDerivativeFilter(); + /** Destructor */ + virtual ~ProfileToProfileDerivativeFilter() {}; + /**PrintSelf method */ + virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; + +private: + ProfileToProfileDerivativeFilter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + /** Subtract filter for the dervivative */ + SubtractFilterPointerType m_SubtractFilter; + /** Abs filter for the derivative */ + AbsFilterPointerType m_AbsFilter; +}; +}// End namespace otb +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbProfileToProfileDerivativeFilter.txx" +#endif + +#endif diff --git a/Code/MultiScale/otbProfileToProfileDerivativeFilter.txx b/Code/MultiScale/otbProfileToProfileDerivativeFilter.txx new file mode 100644 index 0000000000000000000000000000000000000000..bc3b171241a54d27af308733c513b23f5ca550b5 --- /dev/null +++ b/Code/MultiScale/otbProfileToProfileDerivativeFilter.txx @@ -0,0 +1,140 @@ +/*========================================================================= + +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 _otbImageListToImageListApplyFilter_txx +#define _otbImageListToImageListApplyFilter_txx + +#include "otbProfileToProfileDerivativeFilter.h" + +namespace otb +{ +/** + * Constructor + */ +template <class TInputImageList, class TOutputImageList> +ProfileToProfileDerivativeFilter<TInputImageList,TOutputImageList> +::ProfileToProfileDerivativeFilter() +{ + m_SubtractFilter = SubtractFilterType::New(); + m_AbsFilter = AbsFilterType::New(); +} +/** Generate output information for the ImageList and for each image + in the List. */ +template <class TInputImageList, class TOutputImageList> +void +ProfileToProfileDerivativeFilter<TInputImageList,TOutputImageList> +::GenerateOutputInformation() +{ + // Retrieving input/output pointers + InputImageListPointerType inputPtr = this->GetInput(); + OutputImageListPointerType outputPtr = this->GetOutput(); + if(outputPtr) + { + if(outputPtr->Size()!=inputPtr->Size()-1) + { + // in this case, clear the list + outputPtr->Clear(); + typename InputImageListType::ConstIterator inputListIt = inputPtr->Begin(); + while(inputListIt!=inputPtr->End()) + { + outputPtr->PushBack(OutputImageType::New()); + ++inputListIt; + } + } + + // For each input image + typename InputImageListType::ConstIterator inputListIt = inputPtr->Begin(); + typename OutputImageListType::Iterator outputListIt = outputPtr->Begin(); + + while(inputListIt!=inputPtr->End()&&outputListIt!=outputPtr->End()) + { + // Create the output image and set its information + outputListIt.Get()->CopyInformation(inputListIt.Get()); + outputListIt.Get()->SetLargestPossibleRegion(inputListIt.Get()->GetLargestPossibleRegion()); + ++inputListIt; + ++outputListIt; + } + } +} +/** Generate input requested region for each image in the List. */ +template <class TInputImageList, class TOutputImageList> +void +ProfileToProfileDerivativeFilter<TInputImageList,TOutputImageList> +::GenerateInputRequestedRegion() +{ + // Retrieving input/output pointers + InputImageListPointerType inputPtr = this->GetInput(); + OutputImageListPointerType outputPtr = this->GetOutput(); + + // For each input image and corresponding output image + typename InputImageListType::ConstIterator inputListIt = inputPtr->Begin(); + typename OutputImageListType::Iterator outputListIt = outputPtr->Begin(); + + // Use the filter to generate input requested region + while(inputListIt!=inputPtr->End()&&outputListIt!=outputPtr->End()) + { + inputListIt.Get() ->SetRequestedRegion(outputListIt.Get()->GetRequestedRegion()); + ++inputListIt; + ++outputListIt; + } +} +/** Main computation method */ +template <class TInputImageList, class TOutputImageList> +void +ProfileToProfileDerivativeFilter<TInputImageList,TOutputImageList> +::GenerateData() +{ + m_AbsFilter->SetInput(m_SubtractFilter->GetOutput()); + + // Retrieving input/output pointers + InputImageListPointerType inputPtr = this->GetInput(); + OutputImageListPointerType outputPtr = this->GetOutput(); + + // For each input image and corresponding output image + typename InputImageListType::ConstIterator inputListIt = inputPtr->Begin(); + typename OutputImageListType::Iterator outputListIt = outputPtr->Begin(); + unsigned int counter = 0; + + InputImagePointerType lastImage = inputListIt.Get(); + ++inputListIt; + + while(inputListIt!=inputPtr->End()&&outputListIt!=outputPtr->End()) + { + m_SubtractFilter->SetInput1(inputListIt.Get()); + m_SubtractFilter->SetInput2(lastImage); + m_AbsFilter->GetOutput()->SetRequestedRegion(outputListIt.Get()->GetRequestedRegion()); + m_AbsFilter->Update(); + outputPtr->SetNthElement(counter,static_cast<OutputImageType *>(m_AbsFilter->GetOutput())); + outputListIt.Get()->DisconnectPipeline(); + lastImage=inputListIt.Get(); + ++inputListIt; + ++outputListIt; + ++counter; + } +} +/** + * PrintSelf Method + */ +template <class TInputImageList, class TOutputImageList> +void +ProfileToProfileDerivativeFilter<TInputImageList,TOutputImageList> +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} +} // End namespace otb +#endif diff --git a/Testing/Code/MultiScale/CMakeLists.txt b/Testing/Code/MultiScale/CMakeLists.txt index 8dba9d0aa54a4a4c6bfffad8d3c32fa5057debde..0fb263e58d56ce39f7f926152c3bd3bef896ebee 100644 --- a/Testing/Code/MultiScale/CMakeLists.txt +++ b/Testing/Code/MultiScale/CMakeLists.txt @@ -15,6 +15,7 @@ SET(EPSILON 0.00000001) SET(MULTISCALE_TESTS1 ${CXX_TEST_PATH}/otbMultiScaleTests1) SET(MULTISCALE_TESTS2 ${CXX_TEST_PATH}/otbMultiScaleTests2) +SET(MULTISCALE_TESTS3 ${CXX_TEST_PATH}/otbMultiScaleTests3) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbMULTISCALE_TESTS1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -263,6 +264,30 @@ ADD_TEST(msTvMorphologicalClosingProfileFilter ${MULTISCALE_TESTS2} 1 ) +# ------- otb::ProfileToProfileDerivativeFilter ---------- + +ADD_TEST(msTuProfileToProfileDerivativeFilterNew ${MULTISCALE_TESTS3} + otbProfileToProfileDerivativeFilterNew) + +ADD_TEST(msTvProfileToProfileDerivativeFilter ${MULTISCALE_TESTS3} + --compare-n-images ${TOL} 4 + ${BASELINE}/msProfileToProfileDerivativeFilterOutput1.tif + ${TEMP}/msProfileToProfileDerivativeFilterOutput1.tif + ${BASELINE}/msProfileToProfileDerivativeFilterOutput2.tif + ${TEMP}/msProfileToProfileDerivativeFilterOutput2.tif + ${BASELINE}/msProfileToProfileDerivativeFilterOutput3.tif + ${TEMP}/msProfileToProfileDerivativeFilterOutput3.tif + ${BASELINE}/msProfileToProfileDerivativeFilterOutput4.tif + ${TEMP}/msProfileToProfileDerivativeFilterOutput4.tif + otbProfileToProfileDerivativeFilter + ${INPUTDATA}/ROI_IKO_PAN_LesHalles.tif + ${TEMP}/msProfileToProfileDerivativeFilterOutput + tif + 5 + 1 + 1 +) + # ------- Fichiers sources CXX ----------------------------------- SET(BasicMultiScale_SRCS1 otbMorphologicalPyramidResamplerNew.cxx @@ -290,7 +315,10 @@ otbMorphologicalOpeningProfileFilter.cxx otbMorphologicalClosingProfileFilterNew.cxx otbMorphologicalClosingProfileFilter.cxx ) - +SET(BasicMultiScale_SRCS3 +otbProfileToProfileDerivativeFilterNew.cxx +otbProfileToProfileDerivativeFilter.cxx +) INCLUDE_DIRECTORIES("${OTBTesting_BINARY_DIR}") @@ -298,5 +326,7 @@ ADD_EXECUTABLE(otbMultiScaleTests1 otbMultiScaleTests1.cxx ${BasicMultiScale_SRC TARGET_LINK_LIBRARIES(otbMultiScaleTests1 OTBIO OTBMultiScale gdal ITKIO ITKAlgorithms ITKStatistics ITKCommon) ADD_EXECUTABLE(otbMultiScaleTests2 otbMultiScaleTests2.cxx ${BasicMultiScale_SRCS2}) TARGET_LINK_LIBRARIES(otbMultiScaleTests2 OTBIO OTBMultiScale gdal ITKIO ITKAlgorithms ITKStatistics ITKCommon) +ADD_EXECUTABLE(otbMultiScaleTests3 otbMultiScaleTests3.cxx ${BasicMultiScale_SRCS3}) +TARGET_LINK_LIBRARIES(otbMultiScaleTests3 OTBIO OTBMultiScale gdal ITKIO ITKAlgorithms ITKStatistics ITKCommon) ENDIF( NOT OTB_DISABLE_CXX_TESTING ) diff --git a/Testing/Code/MultiScale/otbMultiScaleTests3.cxx b/Testing/Code/MultiScale/otbMultiScaleTests3.cxx new file mode 100644 index 0000000000000000000000000000000000000000..70055b0a295b5601b05cef228e8e2d88b1a51023 --- /dev/null +++ b/Testing/Code/MultiScale/otbMultiScaleTests3.cxx @@ -0,0 +1,31 @@ +/*========================================================================= + + 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. + +=========================================================================*/ + +// this file defines the otbMultiScaleTest for the test driver +// and all it expects is that you have a function called RegisterTests +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif +#include <iostream> +#include "otbTestMain.h" + +void RegisterTests() +{ +REGISTER_TEST(otbProfileToProfileDerivativeFilterNew); +REGISTER_TEST(otbProfileToProfileDerivativeFilter); +} diff --git a/Testing/Code/MultiScale/otbProfileToProfileDerivativeFilter.cxx b/Testing/Code/MultiScale/otbProfileToProfileDerivativeFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3bd027dc6fa1c358931b9b87a8dc2bac139de37d --- /dev/null +++ b/Testing/Code/MultiScale/otbProfileToProfileDerivativeFilter.cxx @@ -0,0 +1,83 @@ +/*========================================================================= + +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. + +=========================================================================*/ +#include "otbMorphologicalOpeningProfileFilter.h" +#include "otbProfileToProfileDerivativeFilter.h" +#include "itkBinaryBallStructuringElement.h" +#include "otbImageFileReader.h" +#include "otbStreamingImageFileWriter.h" +#include "otbImage.h" + +#include "itkMacro.h" + +int otbProfileToProfileDerivativeFilter(int argc, char * argv[]) +{ + const char * inputFilename = argv[1]; + const char * outputFilenamePrefix = argv[2]; + const char * outputFilenameSuffix = argv[3]; + const unsigned int profileSize = atoi(argv[4]); + const unsigned int initialValue = atoi(argv[5]); + const unsigned int step = atoi(argv[5]); + + + const unsigned int Dimension = 2; + typedef double InputPixelType; + typedef double OutputPixelType; + + typedef otb::Image<InputPixelType,Dimension> InputImageType; + typedef otb::Image<OutputPixelType,Dimension> OutputImageType; + + typedef otb::ImageFileReader<InputImageType> ReaderType; + typedef otb::StreamingImageFileWriter<OutputImageType> WriterType; + + typedef itk::BinaryBallStructuringElement<InputPixelType,Dimension> StructuringElementType; + typedef otb::MorphologicalOpeningProfileFilter<InputImageType,InputImageType,StructuringElementType> + OpeningProfileFilterType; + typedef otb::ProfileToProfileDerivativeFilter<InputImageType,OutputImageType> DerivativeFilterType; + + // Reading input image + ReaderType::Pointer reader = ReaderType::New(); + reader->SetFileName(inputFilename); + + // Instantiation + OpeningProfileFilterType::Pointer profileFilter = OpeningProfileFilterType::New(); + profileFilter->SetInput(reader->GetOutput()); + profileFilter->SetProfileSize(profileSize); + profileFilter->SetInitialValue(initialValue); + profileFilter->SetStep(step); + + DerivativeFilterType::Pointer derivativeFilter = DerivativeFilterType::New(); + derivativeFilter->SetInput(profileFilter->GetOutput()); + derivativeFilter->Update(); + + WriterType::Pointer writer; + + // std::stringstream oss; + itk::OStringStream oss; + // Writing the results images + for(unsigned int i = 1;i<profileSize;++i) + { + writer = WriterType::New(); + oss<<outputFilenamePrefix<<i<<"."<<outputFilenameSuffix; + writer->SetInput(derivativeFilter->GetOutput()->GetNthElement(i-1)); + writer->SetFileName(oss.str().c_str()); + writer->Update(); + oss.str(""); + } + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/MultiScale/otbProfileToProfileDerivativeFilterNew.cxx b/Testing/Code/MultiScale/otbProfileToProfileDerivativeFilterNew.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4c6f5f6b6057513e2527b38cd34d097da70f341b --- /dev/null +++ b/Testing/Code/MultiScale/otbProfileToProfileDerivativeFilterNew.cxx @@ -0,0 +1,36 @@ +/*========================================================================= + +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. + +=========================================================================*/ +#include "otbProfileToProfileDerivativeFilter.h" +#include "otbImage.h" + +#include "itkMacro.h" + +int otbProfileToProfileDerivativeFilterNew(int argc, char * argv[]) +{ + const unsigned int Dimension = 2; + typedef double InputPixelType; + typedef double OutputPixelType; + + typedef otb::Image<InputPixelType,Dimension> InputImageType; + typedef otb::Image<OutputPixelType,Dimension> OutputImageType; + typedef otb::ProfileToProfileDerivativeFilter<InputImageType,OutputImageType> DerivativeFilterType; + + DerivativeFilterType::Pointer derivativeFilter = DerivativeFilterType::New(); + + return EXIT_SUCCESS; +}