Skip to content
Snippets Groups Projects
Commit cf1f8741 authored by Ludovic Hussonnois's avatar Ludovic Hussonnois
Browse files

ENH: Add MorphologicalMutltiScaleDecomposition application.

use otbGeodesicMorphologyIterativeDecompositionFilter and create Vector image of 3*N bands for each level (leveling, convex, concave) * N. For mono scale decomposition set the number of iteration to 1.
parent 4438a57d
No related branches found
No related tags found
No related merge requests found
...@@ -2,6 +2,7 @@ set(OTBAppMorphology_LINK_LIBS ...@@ -2,6 +2,7 @@ set(OTBAppMorphology_LINK_LIBS
${OTBImageBase_LIBRARIES} ${OTBImageBase_LIBRARIES}
${OTBApplicationEngine_LIBRARIES} ${OTBApplicationEngine_LIBRARIES}
${OTBObjectList_LIBRARIES} ${OTBObjectList_LIBRARIES}
${OTBMorphologicalProfiles_LIBRARIES}
) )
otb_create_application( otb_create_application(
...@@ -13,3 +14,14 @@ otb_create_application( ...@@ -13,3 +14,14 @@ otb_create_application(
NAME GrayScaleMorphologicalOperation NAME GrayScaleMorphologicalOperation
SOURCES otbGrayScaleMorphologicalOperation.cxx SOURCES otbGrayScaleMorphologicalOperation.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES}) LINK_LIBRARIES ${${otb-module}_LIBRARIES})
#otb_create_application(
# NAME MorphologicalClassification
# SOURCES otbMorphologicalClassification.cxx
# LINK_LIBRARIES ${${otb-module}_LIBRARIES})
otb_create_application(
NAME MorphologicalMultiScaleDecomposition
SOURCES otbMorphologicalMultiScaleDecomposition.cxx
LINK_LIBRARIES ${${otb-module}_LIBRARIES})
/*=========================================================================
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 <geos_c.h>
#include <itkComposeImageFilter.h>
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "itkBinaryBallStructuringElement.h"
#include "itkBinaryCrossStructuringElement.h"
#include "itkBinaryDilateImageFilter.h"
#include "itkBinaryErodeImageFilter.h"
#include "itkBinaryMorphologicalOpeningImageFilter.h"
#include "itkBinaryMorphologicalClosingImageFilter.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbImageList.h"
#include "otbImageListToVectorImageFilter.h"
#include "itkTimeProbe.h"
#include "otbConvexOrConcaveClassificationFilter.h"
#include "otbMorphologicalProfilesSegmentationFilter.h"
#include "otbGeodesicMorphologyIterativeDecompositionImageFilter.h"
namespace otb {
namespace Wrapper {
class MorphologicalMultiScaleDecomposition : public Application {
public:
/** Standard class typedefs. */
typedef MorphologicalMultiScaleDecomposition Self;
typedef Application Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef FloatVectorImageType::InternalPixelType InputPixelType;
typedef float OutputPixelType;
typedef otb::Image<InputPixelType, 2> InputImageType;
typedef otb::VectorImage<OutputPixelType, 2> TOutputVectorImage;
typedef otb::MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType, InputPixelType>
ExtractorFilterType;
typedef itk::BinaryBallStructuringElement<InputPixelType, 2> BallStructuringElementType;
typedef itk::BinaryCrossStructuringElement<InputPixelType, 2> CrossStructuringElementType;
/** Standard macro */
itkNewMacro( Self );
itkTypeMacro( MorphologicalMultiScaleDecomposition, otb::Application );
private:
void DoInit() ITK_OVERRIDE
{
SetName( "MorphologicalMultiScaleDecomposition" );
SetDescription( "Performs morphological operations on an input image channel" );
// Documentation
SetDocName( "Morphological Multi Scale Decomposition" );
SetDocLongDescription("This application performs on a mono band image" );
SetDocLimitations( "None" );
SetDocAuthors( "OTB-Team" );
SetDocSeeAlso( "otbGeodesicMorphologyDecompositionImageFilter class" );
AddDocTag( "MorphologicalMultiScaleDecomposition" );
AddParameter( ParameterType_InputImage, "in", "Input Image" );
SetParameterDescription( "in", "The input image to be classified." );
// TODO comment
AddParameter( ParameterType_OutputImage, "out", "Output Image" );
SetParameterDescription( "out", "TODO" );
AddParameter( ParameterType_Int, "channel", "Selected Channel" );
SetParameterDescription( "channel", "The selected channel index for input image" );
SetDefaultParameterInt( "channel", 1 );
SetMinimumParameterIntValue( "channel", 1 );
AddRAMParameter();
// Strucring Element (Ball | Cross)
AddParameter( ParameterType_Choice, "structype", "Structuring Element Type" );
SetParameterDescription( "structype", "Choice of the structuring element type" );
AddChoice( "structype.ball", "Ball" );
AddChoice( "structype.cross", "Cross" );
AddParameter( ParameterType_Int, "radius", "Radius of the kernel" );
SetParameterDescription( "radius", "Radius of the kernel" );
SetDefaultParameterInt( "radius", 5 );
SetMinimumParameterIntValue( "radius", 1 );
AddParameter( ParameterType_Int, "channel", "Selected Channel" );
SetParameterDescription( "channel", "The selected channel index for input image" );
SetDefaultParameterInt( "channel", 1 );
SetMinimumParameterIntValue( "channel", 1 );
AddParameter( ParameterType_Int, "step", "Selected Step" );
SetParameterDescription( "step", "Increment radius by this step for each iteration" );
SetDefaultParameterInt( "step", 1 );
SetMinimumParameterIntValue( "step", 1 );
AddParameter( ParameterType_Int, "levels", "Number of levels use for multiscale" );
SetParameterDescription( "levels", "Number of levels use for multiscale" );
SetDefaultParameterInt( "levels", 1 );
SetMinimumParameterIntValue( "levels", 1 );
// TODO Doc example parameter settings
/*
SetDocExampleParameterValue("in", "qb_RoadExtract.tif");
SetDocExampleParameterValue("out", "opened.tif");
SetDocExampleParameterValue("channel", "1");
SetDocExampleParameterValue("channel.leveling", "1");
SetDocExampleParameterValue("sigma", "5");
*/
}
void DoUpdateParameters() ITK_OVERRIDE
{
// Nothing to do here : all parameters are independent
}
void DoExecute() ITK_OVERRIDE
{
FloatVectorImageType::Pointer inImage = GetParameterImage( "in" );
inImage->UpdateOutputInformation();
int nBComp = inImage->GetNumberOfComponentsPerPixel();
int selectedChannel = GetParameterInt( "channel" );
if ( selectedChannel > nBComp )
{
itkExceptionMacro( << "The specified channel index for input image is invalid." );
}
m_ExtractorFilter = ExtractorFilterType::New();
m_ExtractorFilter->SetInput( inImage );
m_ExtractorFilter->SetStartX( static_cast<unsigned int>(inImage->GetLargestPossibleRegion().GetIndex( 0 )) );
m_ExtractorFilter->SetStartY( static_cast<unsigned int>(inImage->GetLargestPossibleRegion().GetIndex( 1 )) );
m_ExtractorFilter->SetSizeX( inImage->GetLargestPossibleRegion().GetSize( 0 ) );
m_ExtractorFilter->SetSizeY( inImage->GetLargestPossibleRegion().GetSize( 1 ) );
m_ExtractorFilter->SetChannel( static_cast<unsigned int>(GetParameterInt( "channel" )) );
m_ExtractorFilter->UpdateOutputInformation();
unsigned int numberOfLevels = static_cast<unsigned int>(GetParameterInt( "levels" ));
unsigned int initValue = static_cast<unsigned int>(GetParameterInt( "radius" ));
unsigned int step = static_cast<unsigned int>(GetParameterInt( "step" ));
if(GetParameterString("structype") == "ball")
{
performDecomposition<BallStructuringElementType>(numberOfLevels, step, initValue);
}
else // Cross
{
performDecomposition<CrossStructuringElementType>(numberOfLevels, step, initValue);
}
}
template<typename StructuringElement>
void performDecomposition(unsigned int numberOfLevels, unsigned int step, unsigned int initValue)
{
typedef otb::GeodesicMorphologyIterativeDecompositionImageFilter<InputImageType, StructuringElement> TDecompositionImageFilter;
typedef typename TDecompositionImageFilter::OutputImageListType TImageList;
typedef typename TImageList::Iterator TImageListIterator;
typedef otb::ImageListToVectorImageFilter<TImageList, TOutputVectorImage> TListToVectorImageFilter;
typename TDecompositionImageFilter::Pointer decompositionImageFilter;
decompositionImageFilter = TDecompositionImageFilter::New();
decompositionImageFilter->SetInput( m_ExtractorFilter->GetOutput() );
decompositionImageFilter->SetNumberOfIterations( numberOfLevels );
decompositionImageFilter->SetInitialValue( initValue );
decompositionImageFilter->SetStep( step );
decompositionImageFilter->Update();
// Retrieving iterators on the results images
TImageListIterator itAnalyse = decompositionImageFilter->GetOutput()->Begin();
TImageListIterator itConvexMap = decompositionImageFilter->GetConvexOutput()->Begin();
TImageListIterator itConcaveMap = decompositionImageFilter->GetConcaveOutput()->Begin();
typename TImageList::Pointer imageList = TImageList::New();
// Compose the results images
while ( (itAnalyse != decompositionImageFilter->GetOutput()->End())
&& (itConvexMap != decompositionImageFilter->GetConvexOutput()->End())
&& (itConcaveMap != decompositionImageFilter->GetConcaveOutput()->End())
)
{
imageList->PushBack(itAnalyse.Get());
imageList->PushBack(itConvexMap.Get());
imageList->PushBack(itConcaveMap.Get());
++itAnalyse;
++itConvexMap;
++itConcaveMap;
}
typename TListToVectorImageFilter::Pointer listToVectorImageFilter = TListToVectorImageFilter::New();
listToVectorImageFilter->SetInput(imageList);
listToVectorImageFilter->Update();
SetParameterOutputImage("out", listToVectorImageFilter->GetOutput());
}
ExtractorFilterType::Pointer m_ExtractorFilter;
};
}
}
OTB_APPLICATION_EXPORT( otb::Wrapper::MorphologicalMultiScaleDecomposition )
...@@ -6,6 +6,7 @@ otb_module(OTBAppMorphology ...@@ -6,6 +6,7 @@ otb_module(OTBAppMorphology
OTBObjectList OTBObjectList
OTBITK OTBITK
OTBApplicationEngine OTBApplicationEngine
OTBMorphologicalProfiles
TEST_DEPENDS TEST_DEPENDS
OTBTestKernel OTBTestKernel
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment