diff --git a/Applications/CMakeLists.txt b/Applications/CMakeLists.txt index 08943e56832459f3009056435cb7c4bcd13ad59c..fe8811222b9b203ebd9ee5a55c55e1a69a71d80d 100644 --- a/Applications/CMakeLists.txt +++ b/Applications/CMakeLists.txt @@ -13,7 +13,6 @@ add_subdirectory(DisparityMap) add_subdirectory(FeatureExtraction) add_subdirectory(Hyperspectral) add_subdirectory(Projections) -add_subdirectory(RadiometricIndices) add_subdirectory(Radiometry) add_subdirectory(Rasterization) add_subdirectory(Segmentation) diff --git a/Applications/FeatureExtraction/CMakeLists.txt b/Applications/FeatureExtraction/CMakeLists.txt index cf76c74617fa9cf4b63df2d17486c1351e2abc68..f679c1dc29e4645eac116cc432660eb1ef9d847a 100644 --- a/Applications/FeatureExtraction/CMakeLists.txt +++ b/Applications/FeatureExtraction/CMakeLists.txt @@ -2,6 +2,10 @@ OTB_CREATE_APPLICATION(NAME LineSegmentDetection SOURCES otbLineSegmentDetection.cxx LINK_LIBRARIES OTBIO;OTBCommon;OTBBasicFilters) + +OTB_CREATE_APPLICATION(NAME RadiometricIndices + SOURCES otbRadiometricIndices.cxx + LINK_LIBRARIES OTBIO;OTBRadiometry) OTB_CREATE_APPLICATION(NAME HaralickTextureExtraction SOURCES otbHaralickTextureExtraction.cxx @@ -10,7 +14,3 @@ OTB_CREATE_APPLICATION(NAME HaralickTextureExtraction OTB_CREATE_APPLICATION(NAME SFSTextureExtraction SOURCES otbSFSTextureExtraction.cxx LINK_LIBRARIES OTBIO;OTBCommon;OTBBasicFilters) - -#OTB_CREATE_APPLICATION(NAME ComputeImageFeatures -# SOURCES otbComputeImageFeatures.cxx -# LINK_LIBRARIES OTBIO;OTBCommon;OTBBasicFilters) diff --git a/Applications/FeatureExtraction/otbComputeImageFeatures.cxx b/Applications/FeatureExtraction/otbComputeImageFeatures.cxx deleted file mode 100644 index 13e1c821018c1b5ac0ef5b374f0d66a030b236e7..0000000000000000000000000000000000000000 --- a/Applications/FeatureExtraction/otbComputeImageFeatures.cxx +++ /dev/null @@ -1,501 +0,0 @@ -/*========================================================================= - - 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 "otbWrapperApplication.h" -#include "otbWrapperApplicationFactory.h" - -/* -// otb basic -#include "otbImage.h" -#include "otbVectorImage.h" -#include "otbImageFileReader.h" -#include "otbStreamingImageFileWriter.h" -#include "otbChangeLabelImageFilter.h" -#include "otbStandardWriterWatcher.h" - -// itk -#include "itkVariableLengthVector.h" - - -// Statistic XML Reader -#include "otbStatisticsXMLFileReader.h" - -// Shift Scale Vector Image Filter -#include "otbShiftScaleVectorImageFilter.h" - -// Classification filter -#include "otbSVMImageClassificationFilter.h" - -#include "itkTimeProbe.h" -#include "otbStandardFilterWatcher.h" -*/ - - -#include "otbImageFileReader.h" -#include "otbStreamingImageFileWriter.h" -#include "otbImageFileWriter.h" -#include "otbStandardWriterWatcher.h" - -#include "otbVectorImage.h" -#include "otbImage.h" - -#include "otbImageList.h" -#include "otbVectorImageToImageListFilter.h" -#include "otbVectorImageToAmplitudeImageFilter.h" -#include "otbMultiChannelExtractROI.h" - -#include "otbStreamingShrinkImageFilter.h" -#include "itkListSample.h" -#include "otbListSampleToHistogramListGenerator.h" -#include "itkImageRegionConstIterator.h" -#include "otbVectorRescaleIntensityImageFilter.h" -#include "otbLocalHistogramImageFunction.h" -#include "otbFlusserMomentsImageFunction.h" -#include "otbHaralickTexturesImageFunction.h" -#include "otbFourierMellinDescriptorsImageFunction.h" -#include "otbHistogramOfOrientedGradientCovariantImageFunction.h" - -#include "itkGradientImageFilter.h" -#include "itkMeanImageFilter.h" - -#include "otbVariableLengthVectorConverter.h" -#include "itkTimeProbe.h" - -#include "itkNumericTraits.h" - -namespace otb -{ - namespace Wrapper - { - - class ComputeImageFeatures : public Application - { - public: - /** Standard class typedefs. */ - typedef ComputeImageFeatures Self; - typedef Application Superclass; - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; - - typedef FloatVectorImageType::InternalPixelType PixelType; - typedef otb::VectorImage<PixelType> InputImageType; - typedef otb::VectorImage<double, 2> OutImageType; - - typedef otb::Image<PixelType> SingleInputImageType; - typedef otb::VectorImage<unsigned char> OutputImageType; - typedef otb::ImageFileReader<InputImageType> InputImageReaderType; - typedef otb::ImageFileReader<OutputImageType> OutputImageReaderType; - typedef otb::StreamingImageFileWriter<OutputImageType> OutputWriterType; - typedef otb::ImageList<SingleInputImageType> ImageListType; - typedef otb::VectorImageToImageListFilter<InputImageType, ImageListType> VI2ILFilterType; - typedef otb::VectorImageToAmplitudeImageFilter<InputImageType,SingleInputImageType> AmplitudeFilterType; - typedef otb::VectorRescaleIntensityImageFilter<InputImageType,OutputImageType> RescaleFilterType; - typedef otb::StreamingShrinkImageFilter<InputImageType, InputImageType> ShrinkFilterType; - typedef itk::Statistics::ListSample<InputImageType::PixelType> ListSampleType; - typedef itk::Statistics::DenseFrequencyContainer DFContainerType; - typedef otb::ListSampleToHistogramListGenerator<ListSampleType, InputImageType::InternalPixelType, DFContainerType> HistogramsGeneratorType; - typedef otb::MultiChannelExtractROI<unsigned char, unsigned char> UCharExtractFilterType; - typedef otb::MultiChannelExtractROI<PixelType, PixelType> UShortExtractFilterType; - - // Features - typedef otb::LocalHistogramImageFunction<SingleInputImageType,double> HistogramFunctionType; - typedef otb::VariableLengthVectorConverter<HistogramFunctionType::OutputType, double> HistogramConverterType; - - typedef otb::FlusserMomentsImageFunction<SingleInputImageType> FlusserMomentsFunctionType; - typedef otb::VariableLengthVectorConverter<FlusserMomentsFunctionType::OutputType, double> FlusserMomentsConverterType; - - typedef otb::HaralickTexturesImageFunction<SingleInputImageType> HaralickTexturesFunctionType; - typedef otb::VariableLengthVectorConverter<HaralickTexturesFunctionType::OutputType,double> HaralickConverterType; - - typedef otb::FourierMellinDescriptorsImageFunction<SingleInputImageType> FourierMellinFunctionType; - typedef otb::VariableLengthVectorConverter<FourierMellinFunctionType::OutputType,double> FourierMellinConverterType; - - typedef itk::GradientImageFilter<SingleInputImageType> GradientFilterType; - typedef GradientFilterType::OutputImageType GradientImageType; - - typedef otb::HistogramOfOrientedGradientCovariantImageFunction<GradientImageType> HOGFunctionType; - typedef otb::VariableLengthVectorConverter<HOGFunctionType::OutputType,double> HOGConverterType; - - /** Standard macro */ - itkNewMacro(Self); - - itkTypeMacro(ComputeImageFeatures, otb::Application); - - private: - - void DoInit() - { - SetName("ComputeImageFeatures"); - SetDescription("..."); - - AddParameter(ParameterType_InputImage, "in", "Input Image"); - SetParameterDescription("in", "The input image to compute the features on."); - - AddParameter(ParameterType_Int, "tilesize", "Tile Size"); - SetParameterDescription("tilesize", "Width of the window over which the features are computed."); - SetDefaultParameterInt("tilesize", 20); - - AddParameter(ParameterType_Int, "tilestep", "Tile Step"); - SetParameterDescription("tilestep", "Step distance between neighboring windows (windows may overlap)"); - SetDefaultParameterInt("tilestep", 1); - - // Add the feature parameters in a group - AddParameter(ParameterType_Group, "features", "Features computed"); - SetParameterDescription("features","This group of parameters allows to define features computed in the input image."); - - AddParameter(ParameterType_Empty,"outputs.hog","Compute histogram of oriented gradient by default"); - SetParameterDescription("outputs.hog", "hog"); - EnableParameter("outputs.hog"); - - AddParameter(ParameterType_Empty,"outputs.flusser","Compute flusser moments by default"); - SetParameterDescription("outputs.flusser", "flusser"); - EnableParameter("outputs.flusser"); - - AddParameter(ParameterType_OutputImage, "out", "Output Image"); - SetParameterDescription("out", "Output image containing the feature vectors."); - SetParameterOutputImagePixelType("out", ImagePixelType_double); - } - - void DoUpdateParameters() - { - // Nothing to do here : all parameters are independent - } - - void DoExecute() - { - const unsigned int numParameters = 232; - - itk::VariableLengthVector<double> features(numParameters); - - float intensityMin = 0; // [!] change - float intensityMax = 1000; // [!] change - - unsigned int tilesize = GetParameterInt("tilesize"); - unsigned int tilestep = GetParameterInt("tilestep"); - - // First, instantiate a reader - InputImageReaderType::Pointer inreader = InputImageReaderType::New(); - inreader->SetFileName(GetParameterString("in").c_str()); - inreader->UpdateOutputInformation(); - - // Retrieve nb of bands - unsigned int nbComp = inreader->GetOutput()->GetNumberOfComponentsPerPixel(); - - // Shrink image to estimate histogram - ShrinkFilterType::Pointer shrinkFilter = ShrinkFilterType::New(); - - // Shrink factor is computed so as to load a quicklook of 1000 - // pixels square at most - InputImageType::SizeType imageSize = inreader->GetOutput()->GetLargestPossibleRegion().GetSize(); - unsigned int shrinkFactor = 1; //std::max(imageSize[0], imageSize[1])/1000; // [!] - std::cout<<"Shrink factor: "<<shrinkFactor<<std::endl; - shrinkFilter->SetShrinkFactor(shrinkFactor); - shrinkFilter->SetInput(inreader->GetOutput()); - - otb::StandardWriterWatcher shrinkWatcher(shrinkFilter->GetStreamer(), shrinkFilter->GetFilter(),"Estimating image histogram for rescaling"); - shrinkFilter->GetStreamer()->SetAutomaticTiledStreaming(256); - shrinkFilter->Update(); - - AmplitudeFilterType::Pointer shrinkAmplitudeFilter = AmplitudeFilterType::New(); - shrinkAmplitudeFilter->SetInput(shrinkFilter->GetOutput()); - shrinkAmplitudeFilter->Update(); - - ListSampleType::Pointer listSample = ListSampleType::New(); - - itk::ImageRegionConstIterator<InputImageType> it(shrinkFilter->GetOutput(), shrinkFilter->GetOutput()->GetLargestPossibleRegion()); - itk::ImageRegionConstIterator<SingleInputImageType> ait(shrinkAmplitudeFilter->GetOutput(), shrinkAmplitudeFilter->GetOutput()->GetLargestPossibleRegion()); - - // Now we generate the list of samples - for(it.GoToBegin(),ait.GoToBegin(); !it.IsAtEnd() && !ait.IsAtEnd(); ++it,++ait) - { - InputImageType::PixelType sample(nbComp+1); - - for(unsigned int i = 0; i < nbComp; ++i) - { - sample[i] = it.Get()[i]; - } - sample[nbComp] = ait.Get(); - listSample->PushBack(sample); - } - - // And then the histogram - HistogramsGeneratorType::Pointer histogramsGenerator = HistogramsGeneratorType::New(); - histogramsGenerator->SetListSample(listSample); - histogramsGenerator->SetNumberOfBins(255); - histogramsGenerator->NoDataFlagOn(); - histogramsGenerator->Update(); - - // And extract the 2% lower and upper quantile - InputImageType::PixelType inputMin(nbComp), inputMax(nbComp); - OutputImageType::PixelType outputMin(nbComp),outputMax(nbComp); - outputMin.Fill(0); - outputMax.Fill(255); - - - for(unsigned int i = 0; i < nbComp; ++i) - { - inputMin[i] = intensityMin; // histogramsGenerator->GetOutput()->GetNthElement(i)->Quantile(0, 0.02); - inputMax[i] = intensityMax; //histogramsGenerator->GetOutput()->GetNthElement(i)->Quantile(0, 0.98); - } - - std::cout<<"Values below "<<inputMin<<" are set to 0"<<std::endl; - std::cout<<"Values above "<<inputMax<<" are set to 255"<<std::endl; - - // Now, generate the 8 bits RGB scaled view - RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); - rescaler->SetInput(inreader->GetOutput()); - rescaler->SetInputMinimum(inputMin); - rescaler->SetInputMaximum(inputMax); - rescaler->SetOutputMinimum(outputMin); - rescaler->SetOutputMaximum(outputMax); - rescaler->AutomaticInputMinMaxComputationOff(); - - UCharExtractFilterType::Pointer extractFilter = UCharExtractFilterType::New(); - extractFilter->SetInput(rescaler->GetOutput()); - extractFilter->SetChannel(3); - extractFilter->SetChannel(2); - extractFilter->SetChannel(1); - - // Region for patches extraction - InputImageType::RegionType region; - region.SetSize(0,tilesize); - region.SetSize(1,tilesize); - InputImageType::IndexType index; - - unsigned int count = 0; - - // unsigned int nbPatches = inreader->GetOutput()->GetLargestPossibleRegion().GetNumberOfPixels()/(tilesize*tilesize); [!] - unsigned int nbPatches = inreader->GetOutput()->GetLargestPossibleRegion().GetNumberOfPixels()/(tilestep*tilestep); - - unsigned int radius = tilesize/2 - 1 + tilesize%2; - - unsigned int resX = 0, resY = 0; - for(index[1]=0; index[1] < static_cast<unsigned int>(imageSize[1]-tilesize-1); index[1]+=tilestep) - { - resY++; - } - - for(index[0]=0; index[0]<static_cast<unsigned int>(imageSize[0]-tilesize-1); index[0]+=tilestep) - { - resX++; - } - - std::cout << "res = (" << resX << ", " << resY << ")" << std::endl; - - - OutImageType::Pointer outImage = OutImageType::New(); - - - OutImageType::IndexType start; - start[0] = 0; // first index on X - start[1] = 0; // first index on Y - - OutImageType::SizeType size; - size[0] = resX; // size along X - size[1] = resY; // size along Y - - - OutImageType::RegionType outRegion; - - outRegion.SetSize(size); - outRegion.SetIndex(start); - - outImage->SetRegions(outRegion); - - outImage->SetNumberOfComponentsPerPixel(numParameters); - outImage->Allocate(); - - OutImageType::PixelType pixel; - - pixel.Reserve(numParameters); - - - OutputImageType::IndexType outIndex; - outIndex[0] = 0; - outIndex[1] = 0; - - itk::TimeProbe chrono; - - for(index[1]=0; static_cast<unsigned int>(index[1]<imageSize[1]-tilesize-1); index[1]+=tilestep) - { - unsigned int remtimeOutput; - for(index[0]=0; static_cast<unsigned int>(index[0]<imageSize[0]-tilesize-1); index[0]+=tilestep) - { - - unsigned int globalIndex = 0; - - - chrono.Start(); - - region.SetIndex(index); - - double meanTime = chrono.GetMeanTime(); - unsigned int remainingTime = static_cast<unsigned int>(meanTime*(nbPatches-count)); - - remtimeOutput = remainingTime; - - int dx,dy; - - int reds=0,yellows=0,greens=0,cyans=0,blues=0,magentas=0,grays=0; - - typedef itk::ExtractImageFilter<InputImageType,InputImageType> ExtractFilterType; - ExtractFilterType::Pointer extractFilter1 = ExtractFilterType::New(); - extractFilter1->SetInput(inreader->GetOutput()); - extractFilter1->SetExtractionRegion(region); - extractFilter1->Update(); - - typedef itk::ImageRegionConstIterator< InputImageType > ConstIteratorType; - ConstIteratorType inputIt(extractFilter1->GetOutput(), extractFilter1->GetOutput()->GetLargestPossibleRegion()); - - for (inputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt) - { - InputImageType::PixelType value = inputIt.Get(); - inreader->Update(); - - int margin = 3; // amount by which (e.g.) the red channel value must supercede the others to be counted as "red" - - if (value[0] - margin > value[1] && value[0] > value[2]) - reds++; - else if (value[0] + margin < value[1] && value[0] < value[2]) - cyans++; - else if (value[1] - margin > value[0] && value[1] > value[2]) - greens++; - else if (value[1] + margin < value[0] && value[1] < value[2]) - magentas++; - else if (value[2] - margin > value[0] && value[2] > value[1]) - blues++; - else if (value[2] + margin < value[0] && value[2] < value[1]) - yellows++; - else - grays++; - } - - features[globalIndex++] = reds; - features[globalIndex++] = cyans; - features[globalIndex++] = greens; - features[globalIndex++] = magentas; - features[globalIndex++] = blues; - features[globalIndex++] = yellows; - features[globalIndex++] = grays; - - UCharExtractFilterType::Pointer extractFilter = UCharExtractFilterType::New(); - extractFilter->SetInput(rescaler->GetOutput()); - extractFilter->SetChannel(3); - extractFilter->SetChannel(2); - extractFilter->SetChannel(1); - extractFilter->SetExtractionRegion(region); - - UShortExtractFilterType::Pointer ushortExtractFilter = UShortExtractFilterType::New(); - ushortExtractFilter->SetInput(inreader->GetOutput()); - ushortExtractFilter->SetExtractionRegion(region); - ushortExtractFilter->Update(); - - VI2ILFilterType::Pointer vi2ilFilter = VI2ILFilterType::New(); - vi2ilFilter->SetInput(ushortExtractFilter->GetOutput()); - vi2ilFilter->Update(); - - AmplitudeFilterType::Pointer amplitudeFilter = AmplitudeFilterType::New(); - amplitudeFilter->SetInput(ushortExtractFilter->GetOutput()); - amplitudeFilter->Update(); - - InputImageType::IndexType centerIndex = index; - centerIndex[0]+=tilesize/2; - centerIndex[1]+=tilesize/2; - - InputImageType::PointType point; - inreader->GetOutput()->TransformIndexToPhysicalPoint(centerIndex,point); - - // Computing histograms for each channel - for(unsigned int comp = 0; comp<nbComp; ++comp) - { - HistogramFunctionType::Pointer histogramFunction = HistogramFunctionType::New(); - histogramFunction->SetHistogramMin(intensityMin); //histogramsGenerator->GetOutput()->GetNthElement(comp)->Quantile(0, 0.02)); - histogramFunction->SetHistogramMax(intensityMax); //histogramsGenerator->GetOutput()->GetNthElement(comp)->Quantile(0, 0.98)); - histogramFunction->SetNumberOfHistogramBins(25); - histogramFunction->GaussianSmoothingOn(); - histogramFunction->SetInputImage(vi2ilFilter->GetOutput()->GetNthElement(comp)); // [!] replaced "0" by "comp". better? - histogramFunction->SetNeighborhoodRadius(radius); - - HistogramConverterType::Pointer histogramConverter = HistogramConverterType::New(); - } - - // Compute flusser moments on amplitude - FlusserMomentsFunctionType::Pointer flusserMomentsFunction = FlusserMomentsFunctionType::New(); - flusserMomentsFunction->SetNeighborhoodRadius(radius); - flusserMomentsFunction->SetInputImage(amplitudeFilter->GetOutput()); - - FlusserMomentsConverterType::Pointer flusserMomentsConverter = FlusserMomentsConverterType::New(); - - // Compute Haralick textures on amplitude - HaralickTexturesFunctionType::Pointer haralickFunction = HaralickTexturesFunctionType::New(); - HaralickTexturesFunctionType::OffsetType offset; - offset.Fill(2); - // Last histogam is the amplitude one - haralickFunction->SetInputImageMaximum(histogramsGenerator->GetOutput()->GetNthElement(nbComp)->Quantile(0, 1.0)); - haralickFunction->SetInputImageMinimum(histogramsGenerator->GetOutput()->GetNthElement(nbComp)->Quantile(0, - 0.0)); - haralickFunction->SetNeighborhoodRadius(radius); - haralickFunction->SetNumberOfBinsPerAxis(25); - haralickFunction->SetOffset(offset); - haralickFunction->SetInputImage(amplitudeFilter->GetOutput()); - - HaralickConverterType::Pointer haralickConverter = HaralickConverterType::New(); - - // Compute Fourier-Mellin descriptors on amplitude - FourierMellinFunctionType::Pointer fourierMellinFunction = FourierMellinFunctionType::New(); - fourierMellinFunction->SetNeighborhoodRadius(radius); - fourierMellinFunction->SetInputImage(amplitudeFilter->GetOutput()); - - FourierMellinConverterType::Pointer fourierMellinConverter = FourierMellinConverterType::New(); - - // HOG: COMMENT FROM HERE - - // Compute Histogram of oriented gradients on gradient of - // amplitude image - GradientFilterType::Pointer gradientFilter = GradientFilterType::New(); - gradientFilter->SetInput(amplitudeFilter->GetOutput()); - gradientFilter->Update(); - - HOGFunctionType::Pointer hogFunction = HOGFunctionType::New(); - hogFunction->SetNeighborhoodRadius(radius); - hogFunction->SetInputImage(gradientFilter->GetOutput()); - - HOGConverterType::Pointer hogConverter = HOGConverterType::New(); - - // HOG: COMMENT TO HERE - - ++ count; - - outImage->SetPixel(outIndex, features); - //std::cout << outImage->GetPixel(outIndex) << std::endl; - globalIndex = 0; - chrono.Stop(); - outIndex[0]++; - } - outIndex[0] = 0; - outIndex[1]++; - std::cout<<"Remaining Time: "<<(remtimeOutput/60)<<" minutes "<<(remtimeOutput%60)<<" seconds"<<std::endl; - } - - SetParameterOutputImage("out", dynamic_cast<OutImageType*>(&(*outImage))); - } - }; - } -} - -OTB_APPLICATION_EXPORT(otb::Wrapper::ComputeImageFeatures) diff --git a/Applications/FeatureExtraction/otbHaralickTextureExtraction.cxx b/Applications/FeatureExtraction/otbHaralickTextureExtraction.cxx index 44f856c3d0cd5df1c7638231feaa0518fd7646ec..9d6148fe6e6922a7236bfd598fbb0a7790ec4c28 100644 --- a/Applications/FeatureExtraction/otbHaralickTextureExtraction.cxx +++ b/Applications/FeatureExtraction/otbHaralickTextureExtraction.cxx @@ -162,11 +162,11 @@ void DoExecute() { FloatVectorImageType::Pointer inImage = GetParameterImage("in"); inImage->UpdateOutputInformation(); + int nBComp = inImage->GetNumberOfComponentsPerPixel(); - if( GetParameterInt("channel") > inImage->GetNumberOfComponentsPerPixel() ) + if( GetParameterInt("channel") > nBComp ) { - otbAppLogCRITICAL("Selected band is not available..."); - return; + itkExceptionMacro(<< "The specified channel index is invalid."); } const std::string texType = GetParameterString("texture"); diff --git a/Applications/RadiometricIndices/otbRadiometricIndices.cxx b/Applications/FeatureExtraction/otbRadiometricIndices.cxx similarity index 99% rename from Applications/RadiometricIndices/otbRadiometricIndices.cxx rename to Applications/FeatureExtraction/otbRadiometricIndices.cxx index c86f021b91d527f7d97c1323c32acca0a516b6f2..008b4536920ca70759cacfa487086cc8790b4a34 100644 --- a/Applications/RadiometricIndices/otbRadiometricIndices.cxx +++ b/Applications/FeatureExtraction/otbRadiometricIndices.cxx @@ -483,7 +483,7 @@ private: void DoExecute() { - unsigned int nbChan = GetParameterImage("in")->GetNumberOfComponentsPerPixel(); + int nbChan = GetParameterImage("in")->GetNumberOfComponentsPerPixel(); if ( (this->GetParameterInt("channels.blue") <= nbChan) && (this->GetParameterInt("channels.green") <= nbChan) @@ -568,7 +568,7 @@ private: if( m_ImageList->Size() == 0 ) { - otbAppLogCRITICAL("No indices selected..."); + itkExceptionMacro(<< "No indices selected..."); } m_Concatener->SetInput( m_ImageList ); @@ -578,7 +578,7 @@ private: } else { - otbAppLogINFO("Wrong Band Number..."); + itkExceptionMacro(<< "At least one needed channel has an invalid index"); } } diff --git a/Applications/FeatureExtraction/otbSFSTextureExtraction.cxx b/Applications/FeatureExtraction/otbSFSTextureExtraction.cxx index 7f6aec1f5fab6dd105173aa53c0d7c1ee5b4243e..f987119dfc2fb1333a5b759ae80cecf1bbbd22ad 100644 --- a/Applications/FeatureExtraction/otbSFSTextureExtraction.cxx +++ b/Applications/FeatureExtraction/otbSFSTextureExtraction.cxx @@ -125,11 +125,12 @@ void DoExecute() { FloatVectorImageType::Pointer inImage = GetParameterImage("in"); inImage->UpdateOutputInformation(); + int nBComp = inImage->GetNumberOfComponentsPerPixel(); - if( GetParameterInt("channel") > inImage->GetNumberOfComponentsPerPixel() ) + + if( GetParameterInt("channel") > nBComp ) { - otbAppLogCRITICAL("Selected band is not available..."); - return; + itkExceptionMacro(<< "The specified channel index is invalid."); } m_ExtractorFilter = ExtractorFilterType::New(); diff --git a/Applications/RadiometricIndices/CMakeLists.txt b/Applications/RadiometricIndices/CMakeLists.txt deleted file mode 100644 index 5240857e665302b83f42847b4465c955a04f66e4..0000000000000000000000000000000000000000 --- a/Applications/RadiometricIndices/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ - -OTB_CREATE_APPLICATION(NAME RadiometricVegetationIndices - SOURCES otbRadiometricVegetationIndices.cxx - LINK_LIBRARIES OTBIO;OTBRadiometry) - -OTB_CREATE_APPLICATION(NAME RadiometricWaterIndices - SOURCES otbRadiometricWaterIndices.cxx - LINK_LIBRARIES OTBIO;OTBRadiometry) - -OTB_CREATE_APPLICATION(NAME RadiometricIndices - SOURCES otbRadiometricIndices.cxx - LINK_LIBRARIES OTBIO;OTBRadiometry) \ No newline at end of file diff --git a/Applications/RadiometricIndices/otbRadiometricVegetationIndices.cxx b/Applications/RadiometricIndices/otbRadiometricVegetationIndices.cxx deleted file mode 100644 index 405d6443ff38c65c4a6d51048d67e074f9bf071f..0000000000000000000000000000000000000000 --- a/Applications/RadiometricIndices/otbRadiometricVegetationIndices.cxx +++ /dev/null @@ -1,239 +0,0 @@ -/*========================================================================= - - 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 "otbWrapperApplication.h" -#include "otbWrapperApplicationFactory.h" - -#include "otbMultiChannelRAndNIRIndexImageFilter.h" -#include "otbVegetationIndicesFunctor.h" - -#include "otbImageList.h" -#include "otbImageListToVectorImageFilter.h" - -#include "otbWrapperNumericalParameter.h" - -namespace otb -{ -namespace Wrapper -{ - -class RadiometricVegetationIndices: public Application -{ -public: - /** Standard class typedefs. */ - typedef RadiometricVegetationIndices Self; - typedef Application Superclass; - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; - - /** Standard macro */ - itkNewMacro(Self); - - itkTypeMacro(RadiometricVegetationIndices, otb::Wrapper::Application); - - /** Output containers typedef */ - typedef ObjectList<itk::ProcessObject> FilterListType; - typedef ImageList<FloatImageType> ImageListType; - typedef ImageListToVectorImageFilter<ImageListType, FloatVectorImageType> ImageListToVectorImageFilterType; - - /** Radiometric indices functors typedef */ - typedef Functor::NDVI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> NDVIFunctor; - typedef Functor::TNDVI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> TNDVIFunctor; - typedef Functor::RVI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> RVIFunctor; - typedef Functor::SAVI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> SAVIFunctor; - typedef Functor::TSAVI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> TSAVIFunctor; - typedef Functor::MSAVI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> MSAVIFunctor; - typedef Functor::MSAVI2<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> MSAVI2Functor; - typedef Functor::GEMI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> GEMIFunctor; - typedef Functor::IPVI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> IPVIFunctor; - typedef Functor::LAIFromNDVILogarithmic<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> LAIFromNDVILogFunctor; - typedef Functor::LAIFromReflectancesLinear<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> LAIFromReflLinearFunctor; - typedef Functor::LAIFromNDVIFormosat2Functor<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> LAIFromNDVIFormoFunctor; - - /** Radiometric indices filters typedef */ - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, NDVIFunctor> NDVIFilter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, TNDVIFunctor> TNDVIFilter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, RVIFunctor> RVIFilter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, SAVIFunctor> SAVIFilter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, TSAVIFunctor> TSAVIFilter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, MSAVIFunctor> MSAVIFilter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, MSAVI2Functor> MSAVI2Filter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, GEMIFunctor> GEMIFilter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, IPVIFunctor> IPVIFilter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, LAIFromNDVILogFunctor> LAIFromNDVILogFilter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, LAIFromReflLinearFunctor> LAIFromReflLinearFilter; - typedef MultiChannelRAndNIRIndexImageFilter<FloatVectorImageType, FloatImageType, LAIFromNDVIFormoFunctor> LAIFromNDVIFormoFilter; - -private: - void DoInit() - { - SetName("RadiometricVegetationIndices"); - SetDescription("Compute radiometric indices based on Red and NIR channels."); - - // Documentation - SetDocName("Radiometric Vegetation"); - SetDocLongDescription("This application computes radiometric indices that uses red and NIR channels of the input image. The output image is a multi channel one which each channel is one of the selected index. The channel order is the one of the selected indices."); - SetDocLimitations("None"); - SetDocAuthors("OTB-Team"); - SetDocSeeAlso("otbVegetationIndices class"); - - AddDocTag("Vegetation Indices"); - AddDocTag(Tags::FeatureExtraction); - - AddParameter(ParameterType_InputImage, "in", "Input Image"); - SetParameterDescription("in", "Input image, with at least red and NIR channels"); - - AddParameter(ParameterType_OutputImage, "out", "Output Image"); - SetParameterDescription("out", "Radiometric indices output image"); - - AddRAMParameter(); - - AddParameter(ParameterType_Group, "channels", "Channels selection"); - SetParameterDescription("channels", "Channels selection"); - AddParameter(ParameterType_Int, "channels.red", "Red Channel"); - SetParameterDescription("channels.red", "Red channel index"); - SetDefaultParameterInt("channels.red", 3); - AddParameter(ParameterType_Int, "channels.nir", "NIR Channel"); - SetParameterDescription("channels.nir", "NIR channel index"); - SetDefaultParameterInt("channels.nir", 4); - - AddParameter(ParameterType_Group, "index", "Indices selection"); - SetParameterDescription("index", "List of available radiometric indices"); - AddParameter(ParameterType_Empty, "index.ndvi", "NDVI"); - MandatoryOff("index.ndvi"); - SetParameterDescription("index.ndvi", "Normalized Difference Vegetation Index"); - - AddParameter(ParameterType_Empty, "index.tndvi", "TNDVI"); - MandatoryOff("index.tndvi"); - SetParameterDescription("index.tndvi", " Transformed Normalized Difference Vegetation Index"); - - AddParameter(ParameterType_Empty, "index.rvi", "RVI"); - MandatoryOff("index.rvi"); - SetParameterDescription("index.rvi", "Ratio Vegetation Index"); - - AddParameter(ParameterType_Empty, "index.savi", "SAVI"); - MandatoryOff("index.savi"); - SetParameterDescription("index.savi", "Soil Adjusted Vegetation Index"); - - AddParameter(ParameterType_Empty, "index.tsavi", "TSAVI"); - MandatoryOff("index.tsavi"); - SetParameterDescription("index.tsavi", "Transformed Soil Adjusted Vegetation Index"); - - AddParameter(ParameterType_Empty, "index.msavi", "MSAVI"); - MandatoryOff("index.msavi"); - SetParameterDescription("index.msavi", "Modified Soil Adjusted Vegetation Index"); - - AddParameter(ParameterType_Empty, "index.msavi2", "MSAVI2"); - MandatoryOff("index.msavi2"); - SetParameterDescription("index.msavi2", "Modified Soil Adjusted Vegetation Index 2"); - - AddParameter(ParameterType_Empty, "index.gemi", "GEMI"); - MandatoryOff("index.gemi"); - SetParameterDescription("index.gemi", "Global Environment Monitoring Index"); - - AddParameter(ParameterType_Empty, "index.ipvi", "IPVI"); - MandatoryOff("index.ipvi"); - SetParameterDescription("index.ipvi", "Infrared Percentage Vegetation Index"); - - AddParameter(ParameterType_Empty, "index.laindvilog", "LAIFromNDVILog"); - MandatoryOff("index.laindvilog"); - SetParameterDescription("index.laindvilog", "Leaf Area Index from NDVI using a logarithmic relationship"); - - AddParameter(ParameterType_Empty, "index.lairefl", "LAIFromReflLinear"); - MandatoryOff("index.lairefl"); - SetParameterDescription("index.lairefl", "Leaf Area Index from reflectance using a linear relationship"); - - AddParameter(ParameterType_Empty, "index.laindviformo", "LAIFromNDVIFormo"); - MandatoryOff("index.laindviformo"); - SetParameterDescription("index.laindviformo", "Leaf Area Index from reflectance using using formula a*(exp(nir-red)/((red+nir)*b)-exp(c*b)), with a = 0.1519 b = 3.9443 c = 0.13. This formula is only valid for Formosat 2 reflectance TOCa linear relationship."); - - // Doc example parameter settings - SetDocExampleParameterValue("in", "qb_RoadExtract.tif"); - SetDocExampleParameterValue("index.ndvi", "true"); - SetDocExampleParameterValue("index.rvi", "true"); - SetDocExampleParameterValue("index.ipvi", "true"); - SetDocExampleParameterValue("out", "RadiometricVegetationIndicesImages.tif"); - } - - void DoUpdateParameters() - { - if ( HasValue("in") ) - { - // Put the limit of the channel indices - SetMinimumParameterIntValue("channels.red", 1); - SetMaximumParameterIntValue("channels.red", GetParameterImage("in")->GetNumberOfComponentsPerPixel()); - SetMinimumParameterIntValue("channels.nir", 1); - SetMaximumParameterIntValue("channels.nir", GetParameterImage("in")->GetNumberOfComponentsPerPixel()); - } - } - -#define otbRadiometricVegetationIndicesMacro( key, type ) \ - if( this->IsParameterEnabled(key) ) \ - { \ - type##Filter::Pointer l_##type##Filter = type##Filter::New(); \ - l_##type##Filter->SetRedIndex(redChannel); \ - l_##type##Filter->SetNIRIndex(nirChannel); \ - l_##type##Filter->SetInput(inImage); \ - m_FilterList->PushBack( l_##type##Filter ); \ - m_ImageList->PushBack( l_##type##Filter->GetOutput() ); \ - otbAppLogINFO(key << " indice added."); \ - } - - void DoExecute() - { - m_FilterList = FilterListType::New(); - m_ImageList = ImageListType::New(); - m_Concatener = ImageListToVectorImageFilterType::New(); - - unsigned int redChannel = this->GetParameterInt("channels.red"); - unsigned int nirChannel = this->GetParameterInt("channels.nir"); - FloatVectorImageType* inImage = GetParameterImage("in"); - - otbRadiometricVegetationIndicesMacro("index.ndvi", NDVI); - otbRadiometricVegetationIndicesMacro("index.tndvi", TNDVI); - otbRadiometricVegetationIndicesMacro("index.rvi", RVI); - otbRadiometricVegetationIndicesMacro("index.savi", SAVI); - otbRadiometricVegetationIndicesMacro("index.tsavi", TSAVI); - otbRadiometricVegetationIndicesMacro("index.msavi", MSAVI); - otbRadiometricVegetationIndicesMacro("index.msavi2", MSAVI2); - otbRadiometricVegetationIndicesMacro("index.gemi", GEMI); - otbRadiometricVegetationIndicesMacro("index.ipvi", IPVI); - otbRadiometricVegetationIndicesMacro("index.laindvilog", LAIFromNDVILog); - otbRadiometricVegetationIndicesMacro("index.lairefl", LAIFromReflLinear); - otbRadiometricVegetationIndicesMacro("index.laindviformo", LAIFromNDVIFormo); - - if( m_ImageList->Size() == 0 ) - { - otbAppLogCRITICAL("No indices selected..."); - return; - } - - m_Concatener->SetInput( m_ImageList ); - m_Concatener->UpdateOutputInformation(); - SetParameterOutputImage("out", m_Concatener->GetOutput()); - } - - FilterListType::Pointer m_FilterList; - ImageListType::Pointer m_ImageList; - ImageListToVectorImageFilterType::Pointer m_Concatener; - -}; - -} -} - -OTB_APPLICATION_EXPORT(otb::Wrapper::RadiometricVegetationIndices) diff --git a/Applications/RadiometricIndices/otbRadiometricWaterIndices.cxx b/Applications/RadiometricIndices/otbRadiometricWaterIndices.cxx deleted file mode 100644 index eb2db33932225f2e9791e8ca89af837f663bd734..0000000000000000000000000000000000000000 --- a/Applications/RadiometricIndices/otbRadiometricWaterIndices.cxx +++ /dev/null @@ -1,231 +0,0 @@ -/*========================================================================= - - 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 "otbWrapperApplication.h" -#include "otbWrapperApplicationFactory.h" - -#include "otbMultiChannelRAndNIRIndexImageFilter.h" -#include "otbMultiChannelGAndRIndexImageFilter.h" -#include "otbMultiChannelRAndGAndNIRIndexImageFilter.h" -#include "otbMultiChannelRAndBAndNIRIndexImageFilter.h" -#include "otbMultiChannelRAndGAndNIRIndexImageFilter.h" -#include "otbWaterIndicesFunctor.h" - -#include "otbImageList.h" -#include "otbImageListToVectorImageFilter.h" - -#include "otbWrapperNumericalParameter.h" - -namespace otb -{ -namespace Wrapper -{ - -class RadiometricWaterIndices: public Application -{ -public: - /** Standard class typedefs. */ - typedef RadiometricWaterIndices Self; - typedef Application Superclass; - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; - - /** Standard macro */ - itkNewMacro(Self); - - itkTypeMacro(RadiometricWaterIndices, otb::Wrapper::Application); - - /** Output containers typedef */ - typedef ObjectList<itk::ProcessObject> FilterListType; - typedef ImageList<FloatImageType> ImageListType; - typedef ImageListToVectorImageFilter<ImageListType, FloatVectorImageType> ImageListToVectorImageFilterType; - - /** Radiometric indices functors typedef */ - typedef Functor::SRWI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> SRWIFunctorType; - typedef Functor::NDWI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> NDWIFunctorType; - typedef Functor::NDWI2<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> NDWI2FunctorType; - typedef Functor::MNDWI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> MNDWIFunctorType; - typedef Functor::NDPI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> NDPIFunctorType; - typedef Functor::NDTI<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> NDTIFunctorType; - //typedef Functor::WaterSqrtSpectralAngleFunctor<FloatVectorImageType::InternalPixelType, FloatVectorImageType::InternalPixelType, FloatImageType::PixelType> WaterSqrtSpectralAngleFunctor; - - typedef itk::UnaryFunctorImageFilter<FloatVectorImageType, FloatImageType, SRWIFunctorType> SRWIFilterType; - typedef itk::UnaryFunctorImageFilter<FloatVectorImageType, FloatImageType, NDWIFunctorType> NDWIFilterType; - typedef itk::UnaryFunctorImageFilter<FloatVectorImageType, FloatImageType, NDWI2FunctorType> NDWI2FilterType; - typedef itk::UnaryFunctorImageFilter<FloatVectorImageType, FloatImageType, MNDWIFunctorType> MNDWIFilterType; - typedef itk::UnaryFunctorImageFilter<FloatVectorImageType, FloatImageType, NDPIFunctorType> NDPIFilterType; - typedef itk::UnaryFunctorImageFilter<FloatVectorImageType, FloatImageType, NDTIFunctorType> NDTIFilterType; - -private: - void DoInit() - { - SetName("RadiometricWaterIndices"); - SetDescription("Compute radiometric water indices."); - - // Documentation - SetDocName("Radiometric Water"); - SetDocLongDescription("This application computes radiometric water indices using input image channels of the input image. The output image is a multi channel one which each channel is one of the selected index. The channel order is (if selected): NDWI, NDWI2, MNDWI, NDPI, NDTI, SRWI."); - SetDocLimitations("None"); - SetDocAuthors("OTB-Team"); - SetDocSeeAlso("otbWaterndices class"); - - AddDocTag("Water Indices"); - AddDocTag(Tags::FeatureExtraction); - - AddParameter(ParameterType_InputImage, "in", "Input Image"); - SetParameterDescription("in", "Input image"); - - AddParameter(ParameterType_OutputImage, "out", "Output Image"); - SetParameterDescription("out", "Radiometric indices output image"); - - AddRAMParameter(); - - AddParameter(ParameterType_Group, "channels", "Channels selection"); - SetParameterDescription("channels", "Channels selection"); - - AddParameter(ParameterType_Int, "channels.blue", "Blue Channel"); - SetParameterDescription("channels.blue", "Blue channel index"); - SetDefaultParameterInt("channels.blue", 1); - AddParameter(ParameterType_Int, "channels.green", "Green Channel"); - SetParameterDescription("channels.green", "Green channel index"); - SetDefaultParameterInt("channels.green", 2); - AddParameter(ParameterType_Int, "channels.red", "Red Channel"); - SetParameterDescription("channels.red", "Red channel index"); - SetDefaultParameterInt("channels.red", 3); - AddParameter(ParameterType_Int, "channels.nir", "NIR Channel"); - SetParameterDescription("channels.nir", "NIR channel index"); - SetDefaultParameterInt("channels.nir", 4); - AddParameter(ParameterType_Int, "channels.mir", "Mir Channel"); - SetParameterDescription("channels.mir", "Mir channel index"); - SetDefaultParameterInt("channels.mir", 4); - AddParameter(ParameterType_Int, "channels.rho860", "Rho860 Channel"); - SetParameterDescription("channels.rho860", "860nm band channel index"); - SetDefaultParameterInt("channels.rho860", 2); - AddParameter(ParameterType_Int, "channels.rho1240", "Rho1240 Channel"); - SetParameterDescription("channels.rho1240", "1240nm band channel index"); - SetDefaultParameterInt("channels.rho1240", 5); - - AddParameter(ParameterType_Group, "index", "Indices selection"); - - AddParameter(ParameterType_Empty, "index.ndwi", "NDWI"); - MandatoryOff("index.ndwi"); - SetParameterDescription("index.ndwi", " Normalized Difference Water Index"); - - AddParameter(ParameterType_Empty, "index.ndwi2", "NDWI2"); - MandatoryOff("index.ndwi2"); - SetParameterDescription("index.ndwi2", " Normalized Difference Water Index 2"); - - AddParameter(ParameterType_Empty, "index.mndwi", "MNDWI"); - MandatoryOff("index.mndwi"); - SetParameterDescription("index.mndwi", "Modified Normalized Difference Water Index"); - - AddParameter(ParameterType_Empty, "index.ndpi", "NDPI"); - MandatoryOff("index.ndpi"); - SetParameterDescription("index.ndpi", "Normalized Difference Pond Index"); - - AddParameter(ParameterType_Empty, "index.ndti", "NDTI"); - MandatoryOff("index.ndti"); - SetParameterDescription("index.ndti", "Normalized Difference Turbidity Index"); - - AddParameter(ParameterType_Empty, "index.srwi", "SRWI"); - MandatoryOff("index.srwi"); - SetParameterDescription("index.srwi", "List of available radiometric indices, using Modis 860 and 1240 nm bands"); - - // Doc example parameter settings - SetDocExampleParameterValue("in", "qb_RoadExtract.tif"); - /*SetDocExampleParameterValue("index.ndvi", "true"); - SetDocExampleParameterValue("index.rvi", "true"); - SetDocExampleParameterValue("index.ipvi", "true"); */ - SetDocExampleParameterValue("out", "RadiometricWaterIndicesImages.tif"); - } - - void DoUpdateParameters() - { - if ( HasValue("in") ) - { - // Put the limit of the channel indices - SetMinimumParameterIntValue("channels.blue", 1); - SetMaximumParameterIntValue("channels.blue", GetParameterImage("in")->GetNumberOfComponentsPerPixel()); - SetMinimumParameterIntValue("channels.green", 1); - SetMaximumParameterIntValue("channels.green", GetParameterImage("in")->GetNumberOfComponentsPerPixel()); - SetMinimumParameterIntValue("channels.red", 1); - SetMaximumParameterIntValue("channels.red", GetParameterImage("in")->GetNumberOfComponentsPerPixel()); - SetMinimumParameterIntValue("channels.nir", 1); - SetMaximumParameterIntValue("channels.nir", GetParameterImage("in")->GetNumberOfComponentsPerPixel()); - SetMinimumParameterIntValue("channels.mir", 1); - SetMaximumParameterIntValue("channels.mir", GetParameterImage("in")->GetNumberOfComponentsPerPixel()); - SetMinimumParameterIntValue("channels.rho860", 1); - SetMaximumParameterIntValue("channels.rho860", GetParameterImage("in")->GetNumberOfComponentsPerPixel()); - SetMinimumParameterIntValue("channels.rho1240", 1); - SetMaximumParameterIntValue("channels.rho1240", GetParameterImage("in")->GetNumberOfComponentsPerPixel()); - } - } - -#define otbRadiometricWaterIndicesMacro( key, type, chan1, chan2 ) \ - if( this->IsParameterEnabled(key) ) \ - { \ - type##FilterType::Pointer l_##type##Filter = type##FilterType::New(); \ - std::ostringstream oss; \ - oss<<"channels."<<chan1; \ - l_##type##Filter->GetFunctor().SetIndex1(this->GetParameterInt(oss.str())); \ - oss.str(""); \ - oss<<"channels."<<chan2; \ - l_##type##Filter->GetFunctor().SetIndex2(this->GetParameterInt(oss.str())); \ - l_##type##Filter->SetInput(inImage); \ - m_FilterList->PushBack( l_##type##Filter ); \ - m_ImageList->PushBack( l_##type##Filter->GetOutput() ); \ - otbAppLogINFO(key << " indice added."); \ - } - - void DoExecute() - { - m_FilterList = FilterListType::New(); - m_ImageList = ImageListType::New(); - m_Concatener = ImageListToVectorImageFilterType::New(); - - unsigned int redChannel = this->GetParameterInt("channels.red"); - unsigned int nirChannel = this->GetParameterInt("channels.nir"); - FloatVectorImageType* inImage = GetParameterImage("in"); - - otbRadiometricWaterIndicesMacro("index.ndwi", NDWI, "nir", "mir"); - otbRadiometricWaterIndicesMacro("index.ndwi2", NDWI2, "green", "nir"); - otbRadiometricWaterIndicesMacro("index.mndwi", MNDWI, "green", "mir"); - otbRadiometricWaterIndicesMacro("index.ndpi", NDPI, "mir", "green"); - otbRadiometricWaterIndicesMacro("index.ndti", NDTI, "red", "green"); - otbRadiometricWaterIndicesMacro("index.srwi", SRWI, "rho860", "rho1240"); - - if( m_ImageList->Size() == 0 ) - { - otbAppLogCRITICAL("No indices selected..."); - return; - } - - m_Concatener->SetInput( m_ImageList ); - m_Concatener->UpdateOutputInformation(); - SetParameterOutputImage("out", m_Concatener->GetOutput()); - } - - FilterListType::Pointer m_FilterList; - ImageListType::Pointer m_ImageList; - ImageListToVectorImageFilterType::Pointer m_Concatener; - -}; - -} -} - -OTB_APPLICATION_EXPORT(otb::Wrapper::RadiometricWaterIndices) diff --git a/Applications/Segmentation/otbSegmentation.cxx b/Applications/Segmentation/otbSegmentation.cxx index 1eb6a8a6a04258dec9a49e150043258877c93bbc..42775c5e9aa2dd9eab1a7eb1fdbc54253afa6cec 100644 --- a/Applications/Segmentation/otbSegmentation.cxx +++ b/Applications/Segmentation/otbSegmentation.cxx @@ -29,6 +29,13 @@ #include "otbVectorImageToAmplitudeImageFilter.h" #include "itkGradientMagnitudeImageFilter.h" #include "otbWatershedSegmentationFilter.h" +#include "otbMultiScaleConvexOrConcaveClassificationFilter.h" +#include "itkBinaryBallStructuringElement.h" +#include "otbMorphologicalOpeningProfileFilter.h" +#include "otbMorphologicalClosingProfileFilter.h" +#include "otbProfileToProfileDerivativeFilter.h" +#include "otbProfileDerivativeToMultiScaleCharacteristicsFilter.h" +#include "itkScalarConnectedComponentImageFilter.h" // Large scale vectorization framework #include "otbStreamingImageToOGRLayerSegmentationFilter.h" @@ -38,7 +45,6 @@ #include "otbOGRLayerStreamStitchingFilter.h" #include "otbGeoInformationConversion.h" - namespace otb { namespace Wrapper @@ -79,6 +85,11 @@ public: FunctorType, MaskImageType > ConnectedComponentSegmentationFilterType; + typedef itk::ScalarConnectedComponentImageFilter + <LabelImageType, + LabelImageType> LabeledConnectedComponentSegmentationFilterType; + + // Watershed typedef otb::VectorImageToAmplitudeImageFilter <FloatVectorImageType, @@ -90,6 +101,18 @@ public: typedef otb::WatershedSegmentationFilter <FloatImageType,LabelImageType> WatershedSegmentationFilterType; + // Geodesic morphology multiscale segmentation + typedef itk::BinaryBallStructuringElement<FloatImageType::PixelType, 2> StructuringElementType; + typedef otb::MorphologicalOpeningProfileFilter<FloatImageType, FloatImageType, StructuringElementType> + OpeningProfileFilterType; + typedef otb::MorphologicalClosingProfileFilter<FloatImageType, FloatImageType, StructuringElementType> + ClosingProfileFilterType; + typedef otb::ProfileToProfileDerivativeFilter<FloatImageType, FloatImageType> DerivativeFilterType; + typedef otb::ProfileDerivativeToMultiScaleCharacteristicsFilter<FloatImageType,FloatImageType, LabelImageType> + MultiScaleCharacteristicsFilterType; + typedef otb::MultiScaleConvexOrConcaveClassificationFilter<FloatImageType,LabelImageType> MultiScaleClassificationFilterType; + + // mask filter typedef otb::MaskMuParserFilter @@ -112,6 +135,11 @@ public: <FloatVectorImageType, ConnectedComponentSegmentationFilterType> ConnectedComponentStreamingVectorizedSegmentationOGRType; + typedef otb::StreamingImageToOGRLayerSegmentationFilter + <LabelImageType, + LabeledConnectedComponentSegmentationFilterType> + LabeledConnectedComponentStreamingVectorizedSegmentationOGRType; + typedef otb::OGRLayerStreamStitchingFilter <FloatVectorImageType> FusionFilterType; @@ -134,7 +162,7 @@ private: // Documentation SetDocName("Segmentation"); - SetDocLongDescription("This application allows to perform various segmentation algorithms on an multispectral image." + SetDocLongDescription("This application allows to perform various segmentation algorithms on a multispectral image." "Available segmentation algorithms are two different versions of Mean-Shift segmentation algorithm (one being multi-threaded)," " simple pixel based connected components according to a user-defined criterion, and watershed from the gradient of the intensity" " (norm of spectral bands vector). The application has two different modes that affects the nature of its output.\n\nIn raster mode," @@ -241,6 +269,22 @@ private: AddChoice("mode.raster", "Standard segmentation with labeled raster output"); SetParameterDescription("mode.raster","In this mode, the application will output a standard labeled raster. This mode can not handle large data."); + // GeoMorpho + AddChoice("filter.geomorpho","Multiscale Geodesic Morphology"); + + AddParameter(ParameterType_Int,"filter.geomorpho.size","Profile Size"); + SetParameterDescription("filter.geomorpho.size","TODO"); + SetDefaultParameterInt("filter.geomorpho.size",5); + AddParameter(ParameterType_Int,"filter.geomorpho.step","Profile Step"); + SetParameterDescription("filter.geomorpho.step","TODO"); + SetDefaultParameterInt("filter.geomorpho.step",1); + AddParameter(ParameterType_Int,"filter.geomorpho.start","Profile Start"); + SetParameterDescription("filter.geomorpho.start","TODO"); + SetDefaultParameterInt("filter.geomorpho.start",1); + AddParameter(ParameterType_Float,"filter.geomorpho.sigma","Sigma for decision rule"); + SetParameterDescription("filter.geomorpho.sigma","TODO"); + SetDefaultParameterFloat("filter.geomorpho.sigma",1.); + //Raster mode parameters AddParameter(ParameterType_OutputImage, "mode.raster.out", "Output labeled image"); SetParameterDescription( "mode.raster.out", "The output labeled image."); @@ -345,7 +389,7 @@ private: typedef TSegmentationFilter SegmentationFilterType; typedef typename SegmentationFilterType::Pointer SegmentationFilterPointerType; typedef otb::StreamingImageToOGRLayerSegmentationFilter - <FloatVectorImageType, + <TInputImage, SegmentationFilterType> StreamingVectorizedSegmentationOGRType; // Retrieve tile size parameter @@ -637,6 +681,73 @@ private: gradientMagnitudeFilter->GetOutput(), layer, 0); } + + else + if (segType == "geomorpho") + { + otbAppLogINFO(<<"Using multiscale geodesic morphology segmentation."<<std::endl); + + + unsigned int profileSize = GetParameterInt("filter.geomorpho.size"); + unsigned int initialValue = GetParameterInt("filter.geomorpho.start"); + unsigned int step = GetParameterInt("filter.geomorpho.step"); + double sigma = GetParameterFloat("filter.geomorpho.sigma"); + + + AmplitudeFilterType::Pointer amplitudeFilter = AmplitudeFilterType::New(); + + amplitudeFilter->SetInput(this->GetParameterFloatVectorImage("in")); + + OpeningProfileFilterType::Pointer oprofileFilter = OpeningProfileFilterType::New(); + oprofileFilter->SetInput(amplitudeFilter->GetOutput()); + oprofileFilter->SetProfileSize(profileSize); + oprofileFilter->SetInitialValue(initialValue); + oprofileFilter->SetStep(step); + + ClosingProfileFilterType::Pointer cprofileFilter = ClosingProfileFilterType::New(); + cprofileFilter->SetInput(amplitudeFilter->GetOutput()); + cprofileFilter->SetProfileSize(profileSize); + cprofileFilter->SetInitialValue(initialValue); + cprofileFilter->SetStep(step); + + DerivativeFilterType::Pointer oderivativeFilter = DerivativeFilterType::New(); + oderivativeFilter->SetInput(oprofileFilter->GetOutput()); + + DerivativeFilterType::Pointer cderivativeFilter = DerivativeFilterType::New(); + cderivativeFilter->SetInput(cprofileFilter->GetOutput()); + + MultiScaleCharacteristicsFilterType::Pointer omsCharFilter = MultiScaleCharacteristicsFilterType::New(); + omsCharFilter->SetInput(oderivativeFilter->GetOutput()); + omsCharFilter->SetInitialValue(initialValue); + omsCharFilter->SetStep(step); + + MultiScaleCharacteristicsFilterType::Pointer cmsCharFilter = MultiScaleCharacteristicsFilterType::New(); + cmsCharFilter->SetInput(cderivativeFilter->GetOutput()); + cmsCharFilter->SetInitialValue(initialValue); + cmsCharFilter->SetStep(step); + + MultiScaleClassificationFilterType::Pointer classificationFilter = MultiScaleClassificationFilterType::New(); + classificationFilter->SetOpeningProfileDerivativeMaxima(omsCharFilter->GetOutput()); + classificationFilter->SetOpeningProfileCharacteristics(omsCharFilter->GetOutputCharacteristics()); + classificationFilter->SetClosingProfileDerivativeMaxima(cmsCharFilter->GetOutput()); + classificationFilter->SetClosingProfileCharacteristics(cmsCharFilter->GetOutputCharacteristics()); + classificationFilter->SetSigma(sigma); + classificationFilter->SetLabelSeparator(initialValue + profileSize * step); + + LabeledConnectedComponentStreamingVectorizedSegmentationOGRType::Pointer + ccVectorizationFilter = LabeledConnectedComponentStreamingVectorizedSegmentationOGRType::New(); + + if (HasValue("mode.vector.inmask")) + { + ccVectorizationFilter->GetSegmentationFilter()->SetMaskImage( + this->GetParameterUInt32Image("mode.vector.inmask")); + } + + streamSize = GenericApplySegmentation<LabelImageType, LabeledConnectedComponentSegmentationFilterType> ( + ccVectorizationFilter, classificationFilter->GetOutput(), + layer, 0); + + } else { otbAppLogFATAL(<<"non defined filtering method "<<GetParameterInt("filter")<<std::endl); diff --git a/Code/UtilitiesAdapters/OssimAdapters/otbSensorModelAdapter.cxx b/Code/UtilitiesAdapters/OssimAdapters/otbSensorModelAdapter.cxx index a8df4fbbb701be967a7c7f35f23cd209500b11bc..c7ef65c8fe4e731accbd5a833889d0e71de2f97f 100644 --- a/Code/UtilitiesAdapters/OssimAdapters/otbSensorModelAdapter.cxx +++ b/Code/UtilitiesAdapters/OssimAdapters/otbSensorModelAdapter.cxx @@ -120,7 +120,9 @@ void SensorModelAdapter::ForwardTransformPoint(double x, double y, double z, otbMsgDevMacro(<< "USING DEM ! "); - while ((diffHeight > m_Epsilon) && (nbIter < m_NbIter)) + bool nanHeight = false; + + while (!nanHeight && (diffHeight > m_Epsilon) && (nbIter < m_NbIter)) { otbMsgDevMacro(<< "Iter " << nbIter); @@ -128,10 +130,18 @@ void SensorModelAdapter::ForwardTransformPoint(double x, double y, double z, heightTmp = this->m_DEMHandler->GetHeightAboveMSL(lon, lat); - this->m_SensorModel->lineSampleHeightToWorld(ossimPoint, heightTmp, ossimGPointRef); - + if(ossim::isnan(heightTmp)) + { + nanHeight = true; + this->m_SensorModel->lineSampleToWorld(ossimPoint, ossimGPointRef); + } + else + { + this->m_SensorModel->lineSampleHeightToWorld(ossimPoint, heightTmp, ossimGPointRef); + } + diffHeight = fabs(heightTmp - height); - + ++nbIter; } ossimGPoint = ossimGPointRef; @@ -245,4 +255,41 @@ double SensorModelAdapter::Optimize() return precision; } +bool SensorModelAdapter::ReadGeomFile(const std::string & infile) +{ + ossimKeywordlist geom; + + geom.add(infile.c_str()); + + m_SensorModel = ossimSensorModelFactory::instance()->createProjection(geom); + + if (m_SensorModel == NULL) + { + m_SensorModel = ossimplugins::ossimPluginProjectionFactory::instance()->createProjection(geom); + } + + return (m_SensorModel != NULL); +} + +bool SensorModelAdapter::WriteGeomFile(const std::string & outfile) +{ + // If tie points and model are allocated + if(m_SensorModel != NULL) + { + // try to retrieve a sensor model + ossimSensorModel * sensorModel = NULL; + sensorModel = dynamic_cast<ossimSensorModel *>(m_SensorModel); + + ossimKeywordlist geom; + + bool success = sensorModel->saveState(geom); + + if(success) + { + return geom.write(outfile.c_str()); + } + } + return false; +} + } // namespace otb diff --git a/Code/UtilitiesAdapters/OssimAdapters/otbSensorModelAdapter.h b/Code/UtilitiesAdapters/OssimAdapters/otbSensorModelAdapter.h index c5f67ee978161e16bd0bf948eb7c97bd41cf23fd..150feab485f9bf1fdbb2085fb01d393de9b8fe03 100644 --- a/Code/UtilitiesAdapters/OssimAdapters/otbSensorModelAdapter.h +++ b/Code/UtilitiesAdapters/OssimAdapters/otbSensorModelAdapter.h @@ -86,6 +86,12 @@ public: /** Is sensor model valid method. return false if the m_SensorModel is null*/ bool IsValidSensorModel(); + /** Read geom file and instanciate sensor model */ + bool ReadGeomFile(const std::string & infile); + + /** Write geom file corresponding to sensor model */ + bool WriteGeomFile(const std::string& outfile); + protected: SensorModelAdapter(); virtual ~SensorModelAdapter(); diff --git a/Testing/Applications/CMakeLists.txt b/Testing/Applications/CMakeLists.txt index e5e7d402b411eeeecca35faf8660face7a1a5073..fc72509173b3d97a0863b36b0a0fb1863256dc4a 100644 --- a/Testing/Applications/CMakeLists.txt +++ b/Testing/Applications/CMakeLists.txt @@ -57,7 +57,6 @@ add_subdirectory(FeatureExtraction) add_subdirectory(Hyperspectral) add_subdirectory(Projections) add_subdirectory(Radiometry) -add_subdirectory(RadiometricIndices) add_subdirectory(Rasterization) add_subdirectory(Segmentation) add_subdirectory(Utils) diff --git a/Testing/Applications/FeatureExtraction/CMakeLists.txt b/Testing/Applications/FeatureExtraction/CMakeLists.txt index 3c56ac1fd567cc82e5d612ea77301eab2379cd08..39f8f973645aa7d8e6d1af8425a396771b624eb2 100644 --- a/Testing/Applications/FeatureExtraction/CMakeLists.txt +++ b/Testing/Applications/FeatureExtraction/CMakeLists.txt @@ -21,6 +21,30 @@ OTB_TEST_APPLICATION(NAME apTvFeLineSegmentDetectionNoRescale ENDIF(OTB_DATA_USE_LARGEINPUT) +OTB_TEST_APPLICATION(NAME apTvFERadiometricIndices_veg + APP RadiometricIndices + OPTIONS -in ${INPUTDATA}/veryverySmallFSATSW.tif + -channels.red 3 + -channels.green 2 + -channels.nir 4 + -list Vegetation:NDVI Vegetation:RVI Vegetation:IPVI + -out ${TEMP}/apTvFERadiometricIndices_veg.tif + VALID --compare-image ${NOTOL} + ${BASELINE}/apTvRIRadiometricVegetationIndices.tif + ${TEMP}/apTvFERadiometricIndices_veg.tif) + +OTB_TEST_APPLICATION(NAME apTvFERadiometricIndices_wat + APP RadiometricIndices + OPTIONS -in ${INPUTDATA}/veryverySmallFSATSW.tif + -list Water:NDWI2 + -channels.red 3 + -channels.green 2 + -channels.nir 4 + -out ${TEMP}/apTvFERadiometricIndices_wat.tif + VALID --compare-image ${NOTOL} + ${BASELINE}/apTvRIRadiometricWaterIndices_.tif + ${TEMP}/apTvFERadiometricIndices_wat.tif) + OTB_TEST_APPLICATION(NAME apTvFEHaralickTextureExtraction APP HaralickTextureExtraction OPTIONS -in ${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif diff --git a/Testing/Applications/RadiometricIndices/CMakeLists.txt b/Testing/Applications/RadiometricIndices/CMakeLists.txt deleted file mode 100644 index 5f499e63ce81b3b6613066b8e0601149800b5338..0000000000000000000000000000000000000000 --- a/Testing/Applications/RadiometricIndices/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -OTB_TEST_APPLICATION(NAME apTvRIRadiometricVegetationIndices - APP RadiometricVegetationIndices - OPTIONS -in ${INPUTDATA}/veryverySmallFSATSW.tif - -index.ndvi 1 - -index.rvi 1 - -index.ipvi 1 - -out ${TEMP}/apTvRIRadiometricVegetationIndices.tif - VALID --compare-image ${NOTOL} - ${BASELINE}/apTvRIRadiometricVegetationIndices.tif - ${TEMP}/apTvRIRadiometricVegetationIndices.tif) - -OTB_TEST_APPLICATION(NAME apTvRIRadiometricWaterIndices - APP RadiometricWaterIndices - OPTIONS -in ${INPUTDATA}/veryverySmallFSATSW.tif - -index.ndwi 0 - -index.ndwi2 1 - -index.srwi 1 - -channels.rho860 1 - -channels.rho1240 2 - -out ${TEMP}/apTvRIRadiometricWaterIndices.tif - VALID --compare-image ${NOTOL} - ${BASELINE}/apTvRIRadiometricWaterIndices.tif - ${TEMP}/apTvRIRadiometricWaterIndices.tif) - -OTB_TEST_APPLICATION(NAME apTvRIRadiometricIndices_veg - APP RadiometricIndices - OPTIONS -in ${INPUTDATA}/veryverySmallFSATSW.tif - -channels.red 3 - -channels.green 2 - -channels.nir 4 - -list Vegetation:NDVI Vegetation:RVI Vegetation:IPVI - -out ${TEMP}/apTvRIRadiometricIndices_veg.tif - VALID --compare-image ${NOTOL} - ${BASELINE}/apTvRIRadiometricVegetationIndices.tif - ${TEMP}/apTvRIRadiometricIndices_veg.tif) - -OTB_TEST_APPLICATION(NAME apTvRIRadiometricIndices_wat - APP RadiometricIndices - OPTIONS -in ${INPUTDATA}/veryverySmallFSATSW.tif - -list Water:NDWI2 - -channels.red 3 - -channels.green 2 - -channels.nir 4 - -out ${TEMP}/apTvRIRadiometricIndices_wat.tif - VALID --compare-image ${NOTOL} - ${BASELINE}/apTvRIRadiometricWaterIndices_.tif - ${TEMP}/apTvRIRadiometricIndices_wat.tif) \ No newline at end of file