Commit 05296882 authored by remi cresson's avatar remi cresson
Browse files

ADD: new application for landscape fragmentation extraction

parent 2ea8b7c4
......@@ -3,3 +3,8 @@ cmake_minimum_required (VERSION 2.8)
OTB_CREATE_APPLICATION(NAME TimeSeriesIndexTrend
SOURCES otbTimeSeriesIndexTrend.cxx
LINK_LIBRARIES OTBCommon)
OTB_CREATE_APPLICATION(NAME LandscapeFragmentation
SOURCES otbLandscapeFragmentation.cxx
LINK_LIBRARIES OTBCommon)
\ No newline at end of file
/*=========================================================================
Program: NDVITimeSeries
Language: C++
Copyright (c) Remi Cresson (IRSTEA). All rights reserved.
See LICENSE 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 "itkFixedArray.h"
#include "itkObjectFactory.h"
// Elevation handler
#include "otbWrapperElevationParametersHandler.h"
#include "otbWrapperApplicationFactory.h"
#include "otbWrapperCompositeApplication.h"
// Application engine
#include "otbStandardFilterWatcher.h"
#include "itkFixedArray.h"
// LayerStack
#include "otbImageListToVectorImageFilter.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbImageList.h"
#include "otbMultiChannelExtractROI.h"
// Vectorization
#include "otbLabelImageToVectorDataFilter.h"
namespace otb
{
namespace Wrapper
{
class LandscapeFragmentation : public CompositeApplication
{
public:
/** Standard class typedefs. */
typedef LandscapeFragmentation Self;
typedef Application Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Standard macro */
itkNewMacro(Self);
itkTypeMacro(LandscapeFragmentation, otb::Wrapper::CompositeApplication);
/** Typedefs for image concatenation */
typedef otb::ImageList<FloatImageType> ImageListType;
typedef ImageListToVectorImageFilter<ImageListType, FloatVectorImageType> ListConcatenerFilterType;
typedef MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType,
FloatImageType::PixelType> ExtractROIFilterType;
typedef ObjectList<ExtractROIFilterType> ExtractROIFilterListType;
typedef otb::MultiChannelExtractROI<FloatVectorImageType::InternalPixelType,
FloatVectorImageType::InternalPixelType> ExtractFilterType;
/** Typedefs for vector data generation */
typedef otb::LabelImageToVectorDataFilter<UInt32ImageType> VectorizationFilterType;
private:
void DoInit()
{
SetName("LandscapeFragmentation");
SetDescription("Compute the landscape fragmentation index of the land");
// Documentation
SetDocName("LandscapeFragmentation");
SetDocLongDescription("This application implements the method of Belon et al. (http://dx.doi.org/10.3390/rs9060600)");
SetDocLimitations("None");
SetDocAuthors("Remi Cresson");
SetDocSeeAlso(" ");
ClearApplications();
// Add applications
AddApplication("ImageTimeSeriesGapFilling", "gapfillling" , "Image time series gap filling" );
AddApplication("DimensionalityReduction" , "pca" , "Principal component analysis" );
AddApplication("LSGRM" , "lsgrm" , "Large scale generic region merging" );
// Fixed parameters
GetInternalApplication("gapfillling")->SetParameterString("it" , "linear" , false );
GetInternalApplication("gapfillling")->SetParameterInt ("comp" , 1 , false );
GetInternalApplication("pca" )->SetParameterString("method" , "pca" , false );
GetInternalApplication("lsgrm" )->SetParameterString("criterion" , "bs" , false );
GetInternalApplication("lsgrm" )->SetParameterString("tiling" , "auto" , false );
// Shared parameters
ShareParameter("mask" , "gapfillling.mask" , "Mask" , "Input time series mask" );
ShareParameter("id" , "gapfillling.id" , "DatesFile" , "Input time series dates file" );
ShareParameter("cw" , "lsgrm.criterion.bs.cw" , "SpectralH" , "Weight for the spectral homogeneity" );
ShareParameter("sw" , "lsgrm.criterion.bs.sw" , "SpatialH" , "Weight for the spatial homogeneity" );
ShareParameter("th" , "lsgrm.threshold" , "Threshold" , "Segmentation threshold (scale factor)" );
ShareParameter("tmpdir", "lsgrm.tmpdir" , "TempDir" , "Temporary directory for segmentation" );
// Input NDVI time series images
AddParameter(ParameterType_InputImageList, "ndvits", "Input NDVI time series images");
// PCA ranges
AddParameter(ParameterType_Int, "cbegin", "Component range begin" );
AddParameter(ParameterType_Int, "cend" , "Component range end" );
SetMinimumParameterIntValue("cbegin", 1);
SetMinimumParameterIntValue("cend" , 1);
SetDefaultParameterInt ("cbegin", 2);
MandatoryOff("cbegin");
MandatoryOff("cend");
// Output vector
AddParameter(ParameterType_OutputVectorData, "outvec", "Output land units map (vector)");
// ram
AddRAMParameter();
ShareParameter("ram" , "gapfillling.ram");
ShareParameter("ram" , "pca.ram");
}
void DoUpdateParameters()
{
// Nothing to do here : all parameters are independent
}
void DoExecute()
{
// Get the NDVI time series input image list
FloatVectorImageListType::Pointer inNDVIList = this->GetParameterImageList("ndvits");
// Create one stack for input NDVI images list
m_NDVIConcatener = ListConcatenerFilterType::New();
m_NDVIImageList = ImageListType::New();
m_NDVIExtractorList = ExtractROIFilterListType::New();
// Split each input vector image into image
// and generate an mono channel image list
inNDVIList->GetNthElement(0)->UpdateOutputInformation();
FloatVectorImageType::SizeType size = inNDVIList->GetNthElement(0)->GetLargestPossibleRegion().GetSize();
for( unsigned int i=0; i<inNDVIList->Size(); i++ )
{
FloatVectorImageType::Pointer vectIm = inNDVIList->GetNthElement(i);
vectIm->UpdateOutputInformation();
if( size != vectIm->GetLargestPossibleRegion().GetSize() )
{
otbAppLogFATAL("Input NDVI image size number " << i << " mismatch");
}
for( unsigned int j=0; j<vectIm->GetNumberOfComponentsPerPixel(); j++)
{
ExtractROIFilterType::Pointer extractor = ExtractROIFilterType::New();
extractor->SetInput( vectIm );
extractor->SetChannel( j+1 );
extractor->UpdateOutputInformation();
m_NDVIExtractorList->PushBack( extractor );
m_NDVIImageList->PushBack( extractor->GetOutput() );
}
}
m_NDVIConcatener->SetInput( m_NDVIImageList );
m_NDVIConcatener->UpdateOutputInformation();
otbAppLogINFO("Size of the time series: " <<
m_NDVIConcatener->GetOutput()->GetNumberOfComponentsPerPixel() );
FloatVectorImageType::Pointer stack = m_NDVIConcatener->GetOutput();
// Gapfilling
GetInternalApplication("gapfillling")->SetParameterInputImage("in",
static_cast<InputImageParameter::ImageBaseType*> (stack.GetPointer()));
ExecuteInternal("gapfillling");
// PCA
GetInternalApplication("pca")->SetParameterInputImage("in",
GetInternalApplication("gapfillling")->GetParameterOutputImage("out"));
ExecuteInternal("pca");
// Extract channels
m_ExtractChannelsFilter = ExtractFilterType::New();
unsigned int nbOfBands = m_NDVIConcatener->GetOutput()->GetNumberOfComponentsPerPixel();
unsigned int chbegin = GetParameterInt("cbegin");
if (chbegin > nbOfBands)
{
otbAppLogWARNING("Input parameter cbegin must be lower than the number of components. Using default.");
chbegin = 2;
}
unsigned int chend = nbOfBands;
if (HasValue("cend"))
{
unsigned int inputChEnd = GetParameterInt("cend");
if (inputChEnd > nbOfBands)
{
otbAppLogWARNING("Input parameter cend is greater than the number of components. Using default.")
}
else if (inputChEnd < chbegin)
{
otbAppLogWARNING("Input parameter cend must be greater than cbegin. Using default.")
}
else
{
chend = inputChEnd;
}
}
m_ExtractChannelsFilter = ExtractFilterType::New();
m_ExtractChannelsFilter->SetFirstChannel(chbegin);
m_ExtractChannelsFilter->SetLastChannel(chend);
m_ExtractChannelsFilter->SetInput(static_cast<FloatVectorImageType*>(
GetInternalApplication("pca")->GetParameterOutputImage("out")));
// Segmentation
FloatVectorImageType::Pointer extractedPCAChans = m_ExtractChannelsFilter->GetOutput();
extractedPCAChans->UpdateOutputInformation();
GetInternalApplication("lsgrm")->SetParameterInputImage("in",
static_cast<InputImageParameter::ImageBaseType*> (extractedPCAChans.GetPointer()));
ExecuteInternal("lsgrm");
// Vectorization
m_VectorizationFilter = VectorizationFilterType::New();
m_VectorizationFilter->SetInput(static_cast<UInt32ImageType*>(
GetInternalApplication("lsgrm")->GetParameterOutputImage("out")));
SetParameterOutputVectorData("outvec", m_VectorizationFilter->GetOutput());
} // DOExecute()
void AfterExecuteAndWriteOutputs()
{
// Nothing to do
}
// Layerstack
ListConcatenerFilterType::Pointer m_NDVIConcatener;
ExtractROIFilterListType::Pointer m_NDVIExtractorList;
ImageListType::Pointer m_NDVIImageList;
ExtractFilterType::Pointer m_ExtractChannelsFilter;
VectorizationFilterType::Pointer m_VectorizationFilter;
};
}
}
OTB_APPLICATION_EXPORT( otb::Wrapper::LandscapeFragmentation )
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment