diff --git a/Testing/Code/FeatureExtraction/otbImageFunctionAdaptor.cxx b/Testing/Code/FeatureExtraction/otbImageFunctionAdaptor.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d5d3d6e55144f4859ed44f35eeb7d8f6074c062f --- /dev/null +++ b/Testing/Code/FeatureExtraction/otbImageFunctionAdaptor.cxx @@ -0,0 +1,306 @@ +/*========================================================================= + + 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 "otbImageFileReader.h" +#include "otbStreamingMinMaxImageFilter.h" + +#include "otbImageFunctionAdaptor.h" + +#include "otbFourierMellinDescriptorsImageFunction.h" +#include "otbRealMomentsImageFunction.h" +#include "otbComplexMomentsImageFunction.h" +#include "otbFlusserMomentsImageFunction.h" +#include "otbHuMomentsImageFunction.h" +#include "otbRadiometricMomentsImageFunction.h" +#include "otbLocalHistogramImageFunction.h" + + +int otbImageFunctionAdaptorNew(int argc, char * argv[]) +{ + typedef double InputPixelType; + const unsigned int Dimension = 2; + + typedef otb::Image<InputPixelType, Dimension> InputImageType; + + typedef otb::FourierMellinDescriptorsImageFunction<InputImageType> FMDFunctionType; + typedef otb::RealMomentsImageFunction<InputImageType> RMFunctionType; + typedef otb::ComplexMomentsImageFunction<InputImageType> CMFunctionType; + typedef otb::FlusserMomentsImageFunction<InputImageType> FMFunctionType; + typedef otb::HuMomentsImageFunction<InputImageType> HMFunctionType; + typedef otb::RadiometricMomentsImageFunction<InputImageType> RaMFunctionType; + typedef otb::LocalHistogramImageFunction<InputImageType> LHFunctionType; + + typedef otb::ImageFunctionAdaptor<FMDFunctionType> FMDImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<RMFunctionType> RMImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<CMFunctionType> CMImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<FMFunctionType> FMImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<HMFunctionType> HMImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<RaMFunctionType> RaMImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<LHFunctionType> LHImageFunctionAdaptorType; + + // Instantiating objects + FMDImageFunctionAdaptorType::Pointer FMDadaptedFunction = FMDImageFunctionAdaptorType::New(); + std::cout << FMDadaptedFunction << std::endl; + RMImageFunctionAdaptorType::Pointer RMadaptedFunction = RMImageFunctionAdaptorType::New(); + std::cout << RMadaptedFunction << std::endl; + CMImageFunctionAdaptorType::Pointer CMadaptedFunction = CMImageFunctionAdaptorType::New(); + std::cout << CMadaptedFunction << std::endl; + FMImageFunctionAdaptorType::Pointer FMadaptedFunction = FMImageFunctionAdaptorType::New(); + std::cout << FMadaptedFunction << std::endl; + HMImageFunctionAdaptorType::Pointer HMadaptedFunction = HMImageFunctionAdaptorType::New(); + std::cout << HMadaptedFunction << std::endl; + RaMImageFunctionAdaptorType::Pointer RaMadaptedFunction = RaMImageFunctionAdaptorType::New(); + std::cout << RaMadaptedFunction << std::endl; + //LHImageFunctionAdaptorType::Pointer LHadaptedFunction = LHImageFunctionAdaptorType::New(); + //std::cout << LHadaptedFunction << std::endl; + + return EXIT_SUCCESS; +} + +int otbImageFunctionAdaptor(int argc, char * argv[]) +{ + const char * inputFilename = argv[1]; + + typedef double InputPixelType; + const unsigned int Dimension = 2; + unsigned int rsltIdx = 0; + + typedef otb::Image<InputPixelType, Dimension> InputImageType; + typedef otb::ImageFileReader<InputImageType> ReaderType; + typedef otb::StreamingMinMaxImageFilter<InputImageType> MinMaxFilterType; + + typedef otb::FourierMellinDescriptorsImageFunction<InputImageType> FMDFunctionType; + typedef otb::RealMomentsImageFunction<InputImageType> RMFunctionType; + typedef otb::ComplexMomentsImageFunction<InputImageType> CMFunctionType; + typedef otb::FlusserMomentsImageFunction<InputImageType> FMFunctionType; + typedef otb::HuMomentsImageFunction<InputImageType> HMFunctionType; + typedef otb::RadiometricMomentsImageFunction<InputImageType> RaMFunctionType; + typedef otb::LocalHistogramImageFunction<InputImageType> LHFunctionType; + + typedef otb::ImageFunctionAdaptor<FMDFunctionType> FMDImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<RMFunctionType> RMImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<CMFunctionType> CMImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<FMFunctionType> FMImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<HMFunctionType> HMImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<RaMFunctionType> RaMImageFunctionAdaptorType; + typedef otb::ImageFunctionAdaptor<LHFunctionType> LHImageFunctionAdaptorType; + + // Instantiating objects + ReaderType::Pointer reader = ReaderType::New(); + MinMaxFilterType::Pointer filter = MinMaxFilterType::New(); + + FMDFunctionType::Pointer FMDFunction = FMDFunctionType::New(); + RMFunctionType::Pointer RMFunction = RMFunctionType::New(); + CMFunctionType::Pointer CMFunction = CMFunctionType::New(); + FMFunctionType::Pointer FMFunction = FMFunctionType::New(); + HMFunctionType::Pointer HMFunction = HMFunctionType::New(); + RaMFunctionType::Pointer RaMFunction = RaMFunctionType::New(); + LHFunctionType::Pointer LHFunction = LHFunctionType::New(); + + FMDImageFunctionAdaptorType::Pointer FMDadaptedFunction = FMDImageFunctionAdaptorType::New(); + RMImageFunctionAdaptorType::Pointer RMadaptedFunction = RMImageFunctionAdaptorType::New(); + CMImageFunctionAdaptorType::Pointer CMadaptedFunction = CMImageFunctionAdaptorType::New(); + FMImageFunctionAdaptorType::Pointer FMadaptedFunction = FMImageFunctionAdaptorType::New(); + HMImageFunctionAdaptorType::Pointer HMadaptedFunction = HMImageFunctionAdaptorType::New(); + RaMImageFunctionAdaptorType::Pointer RaMadaptedFunction = RaMImageFunctionAdaptorType::New(); + LHImageFunctionAdaptorType::Pointer LHadaptedFunction = LHImageFunctionAdaptorType::New(); + + reader->SetFileName(inputFilename); + filter->SetInput(reader->GetOutput()); + filter->Update(); + + InputImageType::IndexType index; + index[0] = 100; + index[1] = 100; + + // Content testing + double error = 0.0; + + FMDFunction->SetInputImage(reader->GetOutput()); + FMDFunction->SetNeighborhoodRadius(5); + FMDFunction->SetPmax(5); + FMDFunction->SetQmax(5); + FMDFunctionType::OutputType resultFMD = FMDFunction->EvaluateAtIndex(index); + + FMDadaptedFunction->SetInputImage(reader->GetOutput()); + FMDadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5); + FMDadaptedFunction->GetInternalImageFunction()->SetPmax(5); + FMDadaptedFunction->GetInternalImageFunction()->SetQmax(5); + FMDImageFunctionAdaptorType::OutputType resultAdaptedFMD = FMDadaptedFunction->EvaluateAtIndex(index); + + rsltIdx = 0; + for (unsigned int i=0; i<=5; i++) + { + for (unsigned int j=0; j<=5; j++) + { + error += vcl_pow(vcl_abs(resultAdaptedFMD[rsltIdx] - resultFMD.at(i).at(j)), 2); + + std::cout << "resultAdaptedFMD : " << resultAdaptedFMD[rsltIdx] + << "\t - resultFMD : " << resultFMD.at(i).at(j) << std::endl; + rsltIdx ++; + } + } + + RMFunction->SetInputImage(reader->GetOutput()); + RMFunction->SetNeighborhoodRadius(5); + RMFunction->SetPmax(5); + RMFunction->SetQmax(5); + RMFunctionType::OutputType resultRM = RMFunction->EvaluateAtIndex(index); + + RMadaptedFunction->SetInputImage(reader->GetOutput()); + RMadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5); + RMadaptedFunction->GetInternalImageFunction()->SetPmax(5); + RMadaptedFunction->GetInternalImageFunction()->SetQmax(5); + RMImageFunctionAdaptorType::OutputType resultAdaptedRM = RMadaptedFunction->EvaluateAtIndex(index); + + rsltIdx = 0; + for (unsigned int i=0; i<=5; i++) + { + for (unsigned int j=0; j<=5; j++) + { + error += vcl_pow(vcl_abs(resultAdaptedRM[rsltIdx] - resultRM.at(i).at(j)), 2); + + std::cout << "resultAdaptedRM : " << resultAdaptedRM[rsltIdx] + << "\t - resultRM : " << resultRM.at(i).at(j) << std::endl; + rsltIdx ++; + } + } + + CMFunction->SetInputImage(reader->GetOutput()); + CMFunction->SetNeighborhoodRadius(5); + CMFunction->SetPmax(5); + CMFunction->SetQmax(5); + CMFunctionType::OutputType resultCM = CMFunction->EvaluateAtIndex(index); + + CMadaptedFunction->SetInputImage(reader->GetOutput()); + CMadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5); + CMadaptedFunction->GetInternalImageFunction()->SetPmax(5); + CMadaptedFunction->GetInternalImageFunction()->SetQmax(5); + CMImageFunctionAdaptorType::OutputType resultAdaptedCM = CMadaptedFunction->EvaluateAtIndex(index); + + rsltIdx = 0; + for (unsigned int i=0; i<=5; i++) + { + for (unsigned int j=0; j<=5; j++) + { + error += vcl_pow(vcl_abs(resultAdaptedCM[rsltIdx] - resultCM.at(i).at(j).real()), 2); + std::cout << "resultAdaptedCM : (" << resultAdaptedCM[rsltIdx] + << "," << resultAdaptedCM[rsltIdx+1] << ")" + << "\t - resultCM : " << resultCM.at(i).at(j) << std::endl; + rsltIdx ++; + error += vcl_pow(vcl_abs(resultAdaptedCM[rsltIdx] - resultCM.at(i).at(j).imag()), 2); + rsltIdx ++; + } + } + + FMFunction->SetInputImage(reader->GetOutput()); + FMFunction->SetNeighborhoodRadius(5); + FMFunctionType::OutputType resultFM = FMFunction->EvaluateAtIndex(index); + + FMadaptedFunction->SetInputImage(reader->GetOutput()); + FMadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5); + FMImageFunctionAdaptorType::OutputType resultAdaptedFM = FMadaptedFunction->EvaluateAtIndex(index); + + rsltIdx = 0; + for (unsigned int i=0; i<11; i++) + { + error += vcl_pow(vcl_abs(resultAdaptedFM[rsltIdx] - resultFM[i]), 2); + + std::cout << "resultAdaptedFM : " << resultAdaptedFM[rsltIdx] + << "\t - resultFM : " << resultFM[i] << std::endl; + rsltIdx ++; + } + + HMFunction->SetInputImage(reader->GetOutput()); + HMFunction->SetNeighborhoodRadius(5); + HMFunctionType::OutputType resultHM = HMFunction->EvaluateAtIndex(index); + + HMadaptedFunction->SetInputImage(reader->GetOutput()); + HMadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5); + HMImageFunctionAdaptorType::OutputType resultAdaptedHM = HMadaptedFunction->EvaluateAtIndex(index); + + rsltIdx = 0; + for (unsigned int i=0; i<7; i++) + { + error += vcl_pow(vcl_abs(resultAdaptedHM[rsltIdx] - resultHM[i]), 2); + + std::cout << "resultAdaptedHM : " << resultAdaptedHM[rsltIdx] + << "\t - resultHM : " << resultHM[i] << std::endl; + rsltIdx ++; + } + + RaMFunction->SetInputImage(reader->GetOutput()); + RaMFunction->SetNeighborhoodRadius(5); + RaMFunctionType::OutputType resultRaM = RaMFunction->EvaluateAtIndex(index); + + RaMadaptedFunction->SetInputImage(reader->GetOutput()); + RaMadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5); + RaMImageFunctionAdaptorType::OutputType resultAdaptedRaM = RaMadaptedFunction->EvaluateAtIndex(index); + + rsltIdx = 0; + for (unsigned int i=0; i<4; i++) + { + error += vcl_pow(vcl_abs(resultAdaptedRaM[rsltIdx] - resultRaM[i]), 2); + + std::cout << "resultAdaptedRaM : " << resultAdaptedRaM[rsltIdx] + << "\t - resultRaM : " << resultRaM[i] << std::endl; + rsltIdx ++; + } + + LHFunction->SetInputImage(reader->GetOutput()); + LHFunction->SetNeighborhoodRadius(5); + LHFunction->SetNumberOfHistogramBins(64); + LHFunction->SetHistogramMin(filter->GetMinimum()); + LHFunction->SetHistogramMax(filter->GetMaximum()); + LHFunctionType::OutputType resultLH = LHFunction->EvaluateAtIndex(index); + + LHadaptedFunction->SetInputImage(reader->GetOutput()); + LHadaptedFunction->GetInternalImageFunction()->SetNeighborhoodRadius(5); + LHadaptedFunction->GetInternalImageFunction()->SetNumberOfHistogramBins(64); + LHadaptedFunction->GetInternalImageFunction()->SetHistogramMin(filter->GetMinimum()); + LHadaptedFunction->GetInternalImageFunction()->SetHistogramMax(filter->GetMaximum()); + LHImageFunctionAdaptorType::OutputType resultAdaptedLH = LHadaptedFunction->EvaluateAtIndex(index); + + rsltIdx = 0; + for (unsigned int i=0; i<64; i++) + { + error += vcl_pow(vcl_abs( resultAdaptedLH[rsltIdx] - resultLH->GetFrequency(i)), 2); + + std::cout << "resultAdaptedLH : " << resultAdaptedLH[rsltIdx] + << "\t - resultLH : " << resultLH->GetFrequency(i) << std::endl; + rsltIdx ++; + } + + error = vcl_sqrt(error); + std::cout << std::endl << "Error : " << error << std::endl + << std::endl; + + if (error > 1E-3) + { + itkGenericExceptionMacro( << "Error = " << error + << " > 1E-9 -> TEST FAILLED" << std::endl ); + } + + return EXIT_SUCCESS; +} +