An error occurred while loading the file. Please try again.
-
Victor Poughon authoredb8578d99
/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "itkMeanImageFilter.h"
#include "itkDiscreteGaussianImageFilter.h"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "otbPerBandVectorImageFilter.h"
namespace otb
{
namespace Wrapper
{
enum
{
Smoothing_Mean,
Smoothing_Gaussian,
Smoothing_Anisotropic
};
typedef otb::Image<FloatVectorImageType::InternalPixelType, 2> ImageType;
class Smoothing : public Application
{
public:
/** Standard class typedefs. */
typedef Smoothing Self;
typedef Application Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Standard macro */
itkNewMacro(Self);
itkTypeMacro(Smoothing, otb::Application);
private:
void DoInit() override
{
SetName( "Smoothing" );
SetDescription( "Apply a smoothing filter to an image" );
SetDocLongDescription( "This application applies a smoothing filter to an "
"image. Three methodes can be used: a gaussian filter , a mean filter "
", or an anisotropic diffusion using the Perona-Malik algorithm." );
SetDocLimitations( "None") ;
SetDocAuthors( "OTB-Team" );
SetDocSeeAlso(" ");
AddDocTag(Tags::Filter);
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
AddParameter( ParameterType_InputImage , "in" , "Input Image" );
SetParameterDescription( "in", "Input image to smooth." );
AddParameter( ParameterType_OutputImage , "out" , "Output Image" );
SetParameterDescription( "out" , "Output smoothed image." );
AddParameter( ParameterType_Choice, "type" , "Smoothing Type" );
SetParameterDescription( "type", "Smoothing kernel to apply" );
AddChoice( "type.mean" , "Mean" );
AddParameter( ParameterType_Radius , "type.mean.radius" , "Radius" );
SetParameterDescription( "type.mean.radius" ,
"Kernel's radius (in pixels)" );
SetDefaultParameterInt( "type.mean.radius" , 2 );
AddChoice( "type.gaussian" , "Gaussian" );
AddParameter( ParameterType_Float, "type.gaussian.radius" , "Radius" );
SetParameterDescription( "type.gaussian.radius",
"Standard deviation of the gaussian kernel used to filter the image");
SetDefaultParameterFloat( "type.gaussian.radius" , 2.0 );
// TODO rename this parameter
AddChoice( "type.anidif" , "Anisotropic Diffusion" );
AddParameter( ParameterType_Float , "type.anidif.timestep", "Time Step" );
SetParameterDescription( "type.anidif.timestep" ,
"Time step that will be used to discretize the diffusion equation" );
AddParameter( ParameterType_Int , "type.anidif.nbiter" , "Nb Iterations" );
SetParameterDescription( "type.anidif.nbiter" ,
"Number of iterations needed to get the result" );
AddParameter( ParameterType_Float , "type.anidif.conductance" ,
"Conductance" );
SetParameterDescription( "type.anidif.conductance" ,
"Controls the sensitivity of the conductance term in the diffusion "
"equation. The lower it is the stronger the features will be preserved" );
SetDefaultParameterFloat( "type.anidif.timestep" , 0.125 );
SetDefaultParameterInt( "type.anidif.nbiter" , 10 );
SetDefaultParameterInt( "type.anidif.conductance" , 1. );
SetParameterString( "type" , "anidif");
AddRAMParameter();
// Doc example parameter settings
SetExampleComment( "Image smoothing using a mean filter." , 0 );
SetDocExampleParameterValue( "in" , "Romania_Extract.tif" );
SetDocExampleParameterValue( "out" , "smoothedImage_mean.png uchar" );
SetDocExampleParameterValue( "type" , "mean");
unsigned int exId = AddExample( "Image smoothing using an anisotropic "
"diffusion filter." );
SetDocExampleParameterValue( "in" , "Romania_Extract.tif" , exId );
SetDocExampleParameterValue( "out" , "smoothedImage_ani.png float" , exId );
SetDocExampleParameterValue( "type" , "anidif" , exId );
SetDocExampleParameterValue( "type.anidif.timestep" , "0.1" , exId );
SetDocExampleParameterValue( "type.anidif.nbiter" , "5" , exId );
SetDocExampleParameterValue( "type.anidif.conductance" , "1.5" , exId );
SetOfficialDocLink();
}
void DoUpdateParameters() override
{
// Nothing to do here: all parameters are independent
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
}
void DoExecute() override
{
GetLogger()->Debug("Entering DoExecute\n");
FloatVectorImageType::Pointer inImage = GetParameterImage("in");
switch ( GetParameterInt("type") )
{
case Smoothing_Mean:
{
GetLogger()->Debug("Using mean");
typedef itk::MeanImageFilter<ImageType, ImageType> MeanFilterType;
typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, MeanFilterType>
PerBandMeanFilterType;
PerBandMeanFilterType::Pointer perBand
= PerBandMeanFilterType::New();
perBand->SetInput(inImage);
MeanFilterType::InputSizeType radius;
radius.Fill( GetParameterInt("type.mean.radius") );
perBand->GetFilter()->SetRadius(radius);
perBand->UpdateOutputInformation();
m_FilterRef = perBand;
SetParameterOutputImage("out", perBand->GetOutput());
}
break;
case Smoothing_Gaussian:
{
GetLogger()->Debug("Using gaussian");
typedef itk::DiscreteGaussianImageFilter<ImageType, ImageType> DiscreteGaussianFilterType;
typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, DiscreteGaussianFilterType>
PerBandDiscreteGaussianFilterType;
PerBandDiscreteGaussianFilterType::Pointer perBand
= PerBandDiscreteGaussianFilterType::New();
perBand->SetInput(inImage);
double radius = GetParameterFloat("type.gaussian.radius");
double variance = radius * radius;
perBand->GetFilter()->SetVariance(variance);
perBand->GetFilter()->SetUseImageSpacing(false);
perBand->UpdateOutputInformation();
m_FilterRef = perBand;
SetParameterOutputImage("out", perBand->GetOutput());
}
break;
case Smoothing_Anisotropic:
{
GetLogger()->Debug("Using anisotropic diffusion");
typedef itk::GradientAnisotropicDiffusionImageFilter<ImageType, ImageType> GradientAnisotropicDiffusionFilterType;
typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, GradientAnisotropicDiffusionFilterType>
PerBandGradientAnisotropicDiffusionFilterType;
PerBandGradientAnisotropicDiffusionFilterType::Pointer perBand
= PerBandGradientAnisotropicDiffusionFilterType::New();
perBand->SetInput(inImage);
const int aniDifNbIter = GetParameterInt("type.anidif.nbiter");
perBand->GetFilter()->SetNumberOfIterations(static_cast<unsigned int>(aniDifNbIter));
const float aniDifTimeStep = GetParameterFloat("type.anidif.timestep");
perBand->GetFilter()->SetTimeStep(static_cast<double>(aniDifTimeStep));
211212213214215216217218219220221222223224225226227228229230231
perBand->GetFilter()->SetConductanceParameter(GetParameterFloat("type.anidif.conductance"));
perBand->GetFilter()->SetUseImageSpacing(false);
perBand->UpdateOutputInformation();
m_FilterRef = perBand;
SetParameterOutputImage("out", perBand->GetOutput());
}
break;
}
}
itk::LightObject::Pointer m_FilterRef;
};
}
}
OTB_APPLICATION_EXPORT(otb::Wrapper::Smoothing)