diff --git a/Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h b/Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h index 44260ab8183fb267e4d0ed67362daa3731ea9294..790b397a31950bff9aede8659ef10885c2859b70 100644 --- a/Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h +++ b/Code/Learning/otbCzihoSOMLearningBehaviorFunctor.h @@ -68,7 +68,7 @@ namespace Functor { void SetIterationThreshold ( const itk::Size<VDimension> & sizeInit, unsigned int iterMax ) { double V0 = static_cast<double>( sizeInit[0] ); - for ( int i = 1; i < VDimension; i++ ) + for (unsigned int i = 1; i < VDimension; i++ ) { if ( V0 < static_cast<double>( sizeInit[i] ) ) V0 = static_cast<double>( sizeInit[i] ); diff --git a/Examples/Learning/SOMClassifierExample.cxx b/Examples/Learning/SOMClassifierExample.cxx index 9283d7d452e219d4a64b88e3e91ab50228f9d6a2..5234423fd5e9412eb6224811de44b3ab98f7efdb 100644 --- a/Examples/Learning/SOMClassifierExample.cxx +++ b/Examples/Learning/SOMClassifierExample.cxx @@ -21,12 +21,13 @@ #endif #include <fstream> +#include "otbImage.h" #include "otbVectorImage.h" #include "otbSOMMap.h" #include "otbImageFileReader.h" #include "otbImageFileWriter.h" #include "itkImageRegionIterator.h" -#include "itkImageToListAdaptor.h" +#include "itkListSample.h" // Software Guide : BeginCommandLineArgs // INPUTS: {ROI_QB_MUL_1.png}, {ROI_QB_MUL_SOM.png} @@ -72,7 +73,7 @@ int main(int argc, char* argv[] ) typedef unsigned char LabelPixelType; const unsigned int Dimension = 2; - typedef itk::RGBPixel<InputPixelType> PixelType; + typedef itk::VariableLengthVector<InputPixelType> PixelType; // Software Guide : BeginLatex // @@ -91,7 +92,7 @@ int main(int argc, char* argv[] ) // Software Guide : EndCodeSnippet - typedef otb::Image<PixelType,Dimension> InputImageType; + typedef otb::VectorImage<InputPixelType,Dimension> InputImageType; typedef otb::ImageFileReader< InputImageType > ReaderType; // Software Guide : BeginLatex @@ -111,7 +112,7 @@ int main(int argc, char* argv[] ) // Software Guide : BeginCodeSnippet - typedef itk::Statistics::ImageToListAdaptor< InputImageType > SampleType; + typedef itk::Statistics::ListSample< PixelType> SampleType; typedef otb::SOMClassifier<SampleType,SOMMapType,LabelPixelType> ClassifierType; @@ -159,7 +160,16 @@ int main(int argc, char* argv[] ) // Software Guide : BeginCodeSnippet SampleType::Pointer sample = SampleType::New(); - sample->SetImage(reader->GetOutput()); + + itk::ImageRegionIterator<InputImageType> it(reader->GetOutput(),reader->GetOutput()->GetLargestPossibleRegion()); + + it.GoToBegin(); + + while(!it.IsAtEnd()) + { + sample->PushBack(it.Get()); + ++it; + } // Software Guide : EndCodeSnippet // diff --git a/Examples/Learning/SOMExample.cxx b/Examples/Learning/SOMExample.cxx index a2753335c27ab7e5fbfd4b26a53f3c6d9454d854..fbabb8e4153051b82878b6ec4cc8fac1ef2b95ee 100644 --- a/Examples/Learning/SOMExample.cxx +++ b/Examples/Learning/SOMExample.cxx @@ -9,6 +9,8 @@ Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. See OTBCopyright.txt for details. + Copyright (c) Institut Telecom ; Telecom Bretagne. All rights reserved. + See GETCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR @@ -50,12 +52,15 @@ #include "itkExceptionObject.h" #include "otbImage.h" -#include "itkRGBPixel.h" +#include "otbVectorImage.h" +#include "itkVariableLengthVector.h" + #include "itkVectorExpandImageFilter.h" #include "itkVectorNearestNeighborInterpolateImageFunction.h" #include "itkExpandImageFilter.h" #include "itkNearestNeighborInterpolateImageFunction.h" +#include "otbPerBandVectorImageFilter.h" // Software Guide : BeginLatex // Since the \doxygen{otb}{SOM} class uses a distance, we will need to @@ -71,30 +76,22 @@ // Software Guide : EndCodeSnippet #include "otbImageFileReader.h" #include "otbImageFileWriter.h" -#include "itkImageToListAdaptor.h" +#include "itkListSample.h" int main(int argc, char* argv[]) { - if(argc!=12) - { - std::cout << "Usage: " << argv[0] << "inputImage outputMap activationMap"; - std::cout << "sizeX sizeY neighborX neighborY iterations "; - std::cout << "beta0 betaEnd initValue" << std::endl; - return 1; - } - - - char * inputFileName = argv[1]; - char * outputFileName = argv[2]; - char * actMapFileName = argv[3]; - unsigned int sizeX = atoi(argv[4]); - unsigned int sizeY = atoi(argv[5]); - unsigned int neighInitX = atoi(argv[6]); - unsigned int neighInitY= atoi(argv[7]); - unsigned int nbIterations= atoi(argv[8]); - double betaInit = atof(argv[9]); - double betaEnd= atof(argv[10]); - float initValue = atof(argv[11]); +try { + const char * inputFileName = argv[1]; + const char * outputFileName = argv[2]; + const char * actMapFileName = argv[3]; + unsigned int sizeX = atoi( argv[4] ); + unsigned int sizeY = atoi( argv[5] ); + unsigned int neighInitX = atoi( argv[6] ); + unsigned int neighInitY= atoi( argv[7] ); + unsigned int nbIterations = atoi( argv[8] ); + double betaInit = atof( argv[9] ); + double betaEnd= atof( argv[10] ); + double initValue = atof( argv[11] ); // Software Guide : BeginLatex // @@ -107,10 +104,10 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet - const unsigned int Dimension = 2; - typedef unsigned char ComponentType; - typedef itk::RGBPixel<ComponentType> PixelType; + typedef double PixelType; + typedef otb::VectorImage< PixelType, Dimension > ImageType; + typedef ImageType::PixelType VectorType; // Software Guide : EndCodeSnippet // Software Guide : BeginLatex @@ -123,7 +120,7 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet - typedef itk::Statistics::EuclideanDistance<PixelType> DistanceType; + typedef itk::Statistics::EuclideanDistance< VectorType > DistanceType; // Software Guide : EndCodeSnippet // @@ -139,8 +136,7 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet - - typedef otb::SOMMap<PixelType,DistanceType,Dimension> MapType; + typedef otb::SOMMap< VectorType, DistanceType, Dimension > MapType; // Software Guide : EndCodeSnippet // @@ -155,8 +151,6 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet - - typedef otb::Image<PixelType,Dimension> ImageType; typedef otb::ImageFileReader<ImageType> ReaderType; // Software Guide : EndCodeSnippet @@ -171,37 +165,38 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet - typedef itk::Statistics::ImageToListAdaptor<ImageType> ListAdaptorType; - + typedef itk::Statistics::ListSample< VectorType > SampleListType; + // Software Guide : EndCodeSnippet // // Software Guide : BeginLatex // // We can now define the type for the SOM, which is templated over the -// input sample list and the type of the map to be produced. +// input sample list and the type of the map to be produced and the two +// functors that hold the training behavior. // // Software Guide : EndLatex // Software Guide : BeginCodeSnippet - typedef otb::SOM<ListAdaptorType,MapType> SOMType; + typedef otb::Functor::CzihoSOMLearningBehaviorFunctor + LearningBehaviorFunctorType; + typedef otb::Functor::CzihoSOMNeighborhoodBehaviorFunctor + NeighborhoodBehaviorFunctorType; + typedef otb::SOM< SampleListType, MapType, + LearningBehaviorFunctorType, NeighborhoodBehaviorFunctorType > + SOMType; // Software Guide : EndCodeSnippet // // Software Guide : BeginLatex // -// Since the map is itself an image, we can write it to disk with an -// \doxygen{otb}{ImageFileWriter}. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - - typedef otb::ImageFileWriter<MapType> WriterType; - -// Software Guide : EndCodeSnippet -// -// Software Guide : BeginLatex +// As an alternative to standart \code{SOMType}, one can decide to use +// an \doxygen{otb}{PeriodicSOM}, which behaves like \doxygen{otb}{SOM} but +// is to be considered to as a torrus instead of a simple map. Hence, the +// neighborhood behavior of the winning neuron does not depend on its location +// on the map... +// \doxygen{otb}{PeriodicSOM} is defined in otbPeriodicSOM.h. // // We can now start building the pipeline. The first step is to // instantiate the reader and pass its output to the adaptor. @@ -210,13 +205,25 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet - ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(inputFileName); reader->Update(); - ListAdaptorType::Pointer adaptor = ListAdaptorType::New(); - adaptor->SetImage(reader->GetOutput()); + SampleListType::Pointer sampleList = SampleListType::New(); + sampleList->SetMeasurementVectorSize( reader->GetOutput()->GetVectorLength() ); + + itk::ImageRegionIterator< ImageType > imgIter ( reader->GetOutput(), + reader->GetOutput()->GetBufferedRegion() ); + imgIter.GoToBegin(); + + itk::ImageRegionIterator< ImageType > imgIterEnd ( reader->GetOutput(), + reader->GetOutput()->GetBufferedRegion() ); + imgIterEnd.GoToEnd(); + + do { + sampleList->PushBack( imgIter.Get() ); + ++imgIter; + } while ( imgIter != imgIterEnd ); // Software Guide : EndCodeSnippet // @@ -229,7 +236,7 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet SOMType::Pointer som = SOMType::New(); - som->SetListSample(adaptor); + som->SetListSample( sampleList ); // Software Guide : EndCodeSnippet // @@ -277,11 +284,28 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet - som->SetNumberOfIterations(nbIterations); som->SetBetaInit(betaInit); som->SetBetaEnd(betaEnd); - som->SetMaxWeight(static_cast<ComponentType>(initValue)); + som->SetMaxWeight(static_cast<PixelType>(initValue)); + +// Software Guide : EndCodeSnippet +// +// Software Guide : BeginLatex +// +// Now comes the intialisation of the functors. +// +// Software Guide : EndLatex + +// Software Guide : BeginCodeSnippet + + LearningBehaviorFunctorType learningFunctor; + learningFunctor.SetIterationThreshold( radius, nbIterations ); + som->SetBetaFunctor( learningFunctor ); + + NeighborhoodBehaviorFunctorType neighborFunctor; + som->SetNeighborhoodSizeFunctor( neighborFunctor ); + // Software Guide : EndCodeSnippet // // Software Guide : BeginLatex @@ -289,39 +313,35 @@ int main(int argc, char* argv[]) // Finally, we set up the las part of the pipeline where the plug the // output of the SOM into the writer. The learning procedure is // triggered by calling the \code{Update()} method on the writer. +// Since the map is itself an image, we can write it to disk with an +// \doxygen{otb}{ImageFileWriter}. // // Software Guide : EndLatex -// Software Guide : BeginCodeSnippet - +// Software Guide : BeginCodeSnippet + typedef otb::ImageFileWriter< ImageType > WriterType; WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outputFileName); - writer->SetInput(som->GetOutput()); - writer->Update(); // Software Guide : EndCodeSnippet //Just for visualization purposes, we zoom the image. - typedef itk::VectorExpandImageFilter< MapType, MapType > ExpandType; - typedef itk::VectorNearestNeighborInterpolateImageFunction< MapType, + typedef otb::Image<PixelType,2> SingleImageType; + typedef itk::ExpandImageFilter< SingleImageType, SingleImageType > ExpandType; + typedef otb::PerBandVectorImageFilter<MapType,MapType,ExpandType> VectorExpandType; + typedef itk::NearestNeighborInterpolateImageFunction< SingleImageType, double > InterpolatorType; InterpolatorType::Pointer interpolator = InterpolatorType::New(); - ExpandType::Pointer expand = ExpandType::New(); + VectorExpandType::Pointer expand = VectorExpandType::New(); expand->SetInput(som->GetOutput()); - expand->SetExpandFactors( 40 ); - expand->SetInterpolator( interpolator ); - PixelType pix; - pix[0]= 255; - pix[1]= 255; - pix[2]= 255; - expand->SetEdgePaddingValue(pix); + expand->GetFilter()->SetExpandFactors( 40 ); + expand->GetFilter()->SetInterpolator( interpolator ); + expand->GetFilter()->SetEdgePaddingValue(255); writer->SetInput(expand->GetOutput()); writer->Update(); - - // Software Guide : BeginLatex // Figure \ref{fig:SOMMAP} shows the result of the SOM learning. Since // we have performed a learning on RGB pixel values, the produced SOM @@ -374,7 +394,7 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet - typedef otb::SOMActivationBuilder<ListAdaptorType,MapType, + typedef otb::SOMActivationBuilder< SampleListType, MapType, OutputImageType> SOMActivationBuilderType; // Software Guide : EndCodeSnippet @@ -390,7 +410,7 @@ int main(int argc, char* argv[]) SOMActivationBuilderType::Pointer somAct = SOMActivationBuilderType::New(); somAct->SetInput(som->GetOutput()); - somAct->SetListSample(adaptor); + somAct->SetListSample( sampleList ); // Software Guide : EndCodeSnippet // Software Guide : BeginLatex @@ -402,10 +422,11 @@ int main(int argc, char* argv[]) // Software Guide : BeginCodeSnippet - ActivationWriterType::Pointer actWriter = ActivationWriterType::New(); - actWriter->SetFileName(actMapFileName); - actWriter->SetInput(somAct->GetOutput()); - actWriter->Update(); + if ( actMapFileName != NULL ) + { + ActivationWriterType::Pointer actWriter = ActivationWriterType::New(); + actWriter->SetFileName(actMapFileName); + // Software Guide : EndCodeSnippet // Software Guide : BeginLatex @@ -414,20 +435,24 @@ int main(int argc, char* argv[]) // // Software Guide : EndLatex - //Just for visualization purposes, we zoom the image. - typedef itk::ExpandImageFilter< OutputImageType, OutputImageType > ExpandType2; - typedef itk::NearestNeighborInterpolateImageFunction< OutputImageType, double > InterpolatorType2; + //Just for visualization purposes, we zoom the image. + typedef itk::ExpandImageFilter< OutputImageType, OutputImageType > ExpandType2; + typedef itk::NearestNeighborInterpolateImageFunction< OutputImageType,double > InterpolatorType2; - InterpolatorType2::Pointer interpolator2 = InterpolatorType2::New(); - ExpandType2::Pointer expand2 = ExpandType2::New(); - expand2->SetInput(somAct->GetOutput()); - expand2->SetExpandFactors( 20 ); - expand2->SetInterpolator( interpolator2 ); - expand2->SetEdgePaddingValue(255); - actWriter->SetInput(expand2->GetOutput()); - actWriter->Update(); + InterpolatorType2::Pointer interpolator2 = InterpolatorType2::New(); + ExpandType2::Pointer expand2 = ExpandType2::New(); + expand2->SetInput(somAct->GetOutput()); + expand2->SetExpandFactors( 20 ); + expand2->SetInterpolator( interpolator2 ); + expand2->SetEdgePaddingValue(255); + actWriter->SetInput(expand2->GetOutput()); + actWriter->Update(); + } - return EXIT_SUCCESS; + } catch ( ... ) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } diff --git a/Testing/Fa/CMakeLists.txt b/Testing/Fa/CMakeLists.txt index d726410a717b26842215d4bc6b21fa23860a392b..7f010bd8465574be1c30af4040f3c8cd143c1472 100755 --- a/Testing/Fa/CMakeLists.txt +++ b/Testing/Fa/CMakeLists.txt @@ -170,11 +170,9 @@ ADD_TEST(FA-00060-le_Map_Activation ${CXX_TEST_PATH}/MapActivation 0.1 128 1 - ${TEMP}/FA-00013-le-som.hd - ${TEMP}/FA-00013-le-som-zoom.mhd + ${TEMP}/FA-00013-le-som.hdr ${TEMP}/FA-00013-le-actMap.png - ${TEMP}/FA-00013-le-actMap-zoom.png - ${TEMP}/FA-00013-le-som.mhd + ${TEMP}/FA-00013-le-som.hdr ) # ------- Fin des FAs traitees ----------------------------------- diff --git a/Testing/Fa/MapActivation.cxx b/Testing/Fa/MapActivation.cxx index 9e288c5cbc07238f00a08fa78430a61811504287..32e00c3c9918b825beb7fb84a96f16df092ffa63 100755 --- a/Testing/Fa/MapActivation.cxx +++ b/Testing/Fa/MapActivation.cxx @@ -52,14 +52,12 @@ int main(int argc, char* argv[] ) { - if (argc < 14) + if (argc < 12) { - std::cout << "Usage : " << argv[0] << " inputTabImage size radius NumberOfIterations BetaInit BetaEnd MaxWeight MinWeight som som-zoom actMap actMap-zoom som" << std::endl ; + std::cout << "Usage : " << argv[0] << " inputTabImage size radius NumberOfIterations BetaInit BetaEnd MaxWeight MinWeight som actMap som" << std::endl ; return EXIT_FAILURE; } - - const int nbparam= 9; typedef otb::Image<double, 2 > ListImageType; @@ -67,14 +65,13 @@ int main(int argc, char* argv[] ) TabReaderType::Pointer Tabreader = TabReaderType::New(); Tabreader->SetFileName(argv[1]); Tabreader->Update(); - ListImageType::Pointer tabreadImage = ListImageType::New(); - tabreadImage = Tabreader->GetOutput(); + ListImageType::Pointer tabreadImage = Tabreader->GetOutput(); typedef itk::ImageRegionIterator< ListImageType > IteratorType; IteratorType It1( tabreadImage, tabreadImage->GetLargestPossibleRegion() ); - const int nblines=591; // (const int)(tabreadImage->GetLargestPossibleRegion().GetSize()[1]); + const int nblines= (const int)(tabreadImage->GetLargestPossibleRegion().GetSize()[1]); - const int nbcolonnes=9;//tabreadImage->GetLargestPossibleRegion().GetSize()[0]; + const int nbcolonnes= (const int)tabreadImage->GetLargestPossibleRegion().GetSize()[0]; double vectTab[nblines][nbcolonnes]; std::cout<<"lignes = "<<nblines<<" colonnes = "<<nbcolonnes<<std::endl; @@ -83,15 +80,14 @@ int main(int argc, char* argv[] ) vectTab[It1.GetIndex()[1]][It1.GetIndex()[0]]=It1.Get(); } - typedef itk::Vector< double, nbparam > MeasurementVectorType ; - //typedef itk::VariableLengthVector< double > MeasurementVectorType ; + typedef itk::VariableLengthVector< double > MeasurementVectorType ; typedef itk::Statistics::ListSample< MeasurementVectorType > SampleType ; SampleType::Pointer liste = SampleType::New() ; - MeasurementVectorType tab; - for(int j=0;j<nblines;j++) { + MeasurementVectorType tab; + tab.SetSize(nbcolonnes); for(int i=0;i<nbcolonnes;i++) { tab[i] = vectTab[j][i]; @@ -131,29 +127,6 @@ int main(int argc, char* argv[] ) somwriter->SetInput(som->GetOutput()); somwriter->Update(); - - //Just for visualization purposes, we zoom the image. - typedef itk::VectorExpandImageFilter< MapType, MapType > ExpandType; - typedef itk::VectorNearestNeighborInterpolateImageFunction< MapType, double > InterpolatorType; - - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - ExpandType::Pointer expand = ExpandType::New(); - expand->SetInput(som->GetOutput()); - expand->SetExpandFactors( 40 ); - expand->SetInterpolator( interpolator ); - MeasurementVectorType pix; - for(int j=0;j<nbcolonnes;j++) - { - pix[j]= 255; - } - - - expand->SetEdgePaddingValue(pix); - somwriter->SetInput(expand->GetOutput()); - somwriter->SetFileName(argv[10]/*"som-zoom.mhd"*/); - somwriter->Update(); - - typedef unsigned char OutputPixelType; typedef otb::Image<OutputPixelType,2> OutputImageType; @@ -164,31 +137,17 @@ int main(int argc, char* argv[] ) somAct->SetListSample(liste); ActivationWriterType::Pointer actWriter = ActivationWriterType::New(); - actWriter->SetFileName(argv[11]/*"actMap.png"*/); + actWriter->SetFileName(argv[10]/*"actMap.png"*/); actWriter->SetInput(somAct->GetOutput()); actWriter->Update(); - //Just for visualization purposes, we zoom the image. - typedef itk::ExpandImageFilter< OutputImageType, OutputImageType > ExpandType2; - typedef itk::NearestNeighborInterpolateImageFunction< OutputImageType,double > InterpolatorType2; - - InterpolatorType2::Pointer interpolator2 = InterpolatorType2::New(); - ExpandType2::Pointer expand2 = ExpandType2::New(); - expand2->SetInput(somAct->GetOutput()); - expand2->SetExpandFactors( 40 ); - expand2->SetInterpolator( interpolator2 ); - expand2->SetEdgePaddingValue(255); - actWriter->SetInput(expand2->GetOutput()); - actWriter->SetFileName(argv[12]/*"actMap-zoom.png"*/); - actWriter->Update(); - - + //Classifier : typedef otb::ImageFileReader<MapType> SOMReaderType; typedef otb::SOMClassifier<SampleType,MapType,unsigned char> ClassifierType; SOMReaderType::Pointer somreader = SOMReaderType::New(); - somreader->SetFileName(argv[13]/*"som.mhd"*/); + somreader->SetFileName(argv[11]/*"som.mhd"*/); somreader->Update(); ClassifierType::Pointer classifier = ClassifierType::New() ;