Commit 9e8f08ce authored by remi cresson's avatar remi cresson
Browse files

ADD: new app to resample an image based on the means of pixels

No related merge requests found
Showing with 374 additions and 0 deletions
+374 -0
......@@ -8,3 +8,7 @@ OTB_CREATE_APPLICATION(NAME ExtractGeom
SOURCES otbExtractGeom.cxx
LINK_LIBRARIES OTBCommon)
OTB_CREATE_APPLICATION(NAME MeanResample
SOURCES otbMeanResample.cxx
LINK_LIBRARIES OTBCommon)
/*=========================================================================
Copyright (c) Remi Cresson (IRSTEA). All rights reserved.
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"
// Application engine
#include "otbStandardFilterWatcher.h"
#include "itkFixedArray.h"
// Filter
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbMeanResampleImageFilter.h"
using namespace std;
namespace otb
{
namespace Wrapper
{
class MeanResample : public Application
{
public:
/** Standard class typedefs. */
typedef MeanResample Self;
typedef Application Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef MultiToMonoChannelExtractROI<FloatVectorImageType::InternalPixelType,FloatVectorImageType::InternalPixelType> ExtractFilterType;
typedef otb::MeanResampleImageFilter<FloatImageType> FilterType;
/** Standard macro */
itkNewMacro(Self);
itkTypeMacro(MeanResample, Application);
void DoInit()
{
SetName("MeanResample");
SetDescription("Resample an image using the mean value of the pixels over a square neighborhood");
// Documentation
SetDocName("ExtractBand");
SetDocLongDescription("This application decimates an input image using the mean value of the pixels neighborhood");
SetDocLimitations("None");
SetDocAuthors("Remi Cresson");
SetDocSeeAlso(" ");
AddDocTag(Tags::Manip);
AddParameter(ParameterType_InputImage, "in", "Input XS Image");
SetParameterDescription("in"," Input image.");
AddParameter(ParameterType_Int, "stepx", "step x" );
SetMinimumParameterIntValue("stepx", 2);
SetDefaultParameterInt("stepx", 2);
AddParameter(ParameterType_Int, "stepy", "step y" );
SetMinimumParameterIntValue("stepy", 2);
SetDefaultParameterInt("stepy", 2);
AddParameter(ParameterType_OutputImage, "out", "Output image");
SetParameterDescription("out"," Output image.");
AddRAMParameter();
// Doc example parameter settings
SetDocExampleParameterValue("stepx", "2");
SetDocExampleParameterValue("stepy", "2");
SetDocExampleParameterValue("in", "QB_Toulouse_Ortho_XS.tif");
SetDocExampleParameterValue("out", "QB_Toulouse_Ortho_XS_resampled_2x2.tif uint16");
}
void DoUpdateParameters()
{
// Nothing to do here : all parameters are independent
}
void DoExecute()
{
FloatVectorImageType* xs = GetParameterImage("in");
m_ExtractFilter = ExtractFilterType::New();
m_ExtractFilter->SetInput(xs);
m_ExtractFilter->SetChannel(1);
unsigned int stepx = GetParameterInt("stepx");
unsigned int stepy = GetParameterInt("stepy");
m_Filter = FilterType::New();
m_Filter->SetStepX(stepx);
m_Filter->SetStepY(stepy);
m_Filter->SetInput(m_ExtractFilter->GetOutput());
SetParameterOutputImage("out", m_Filter->GetOutput());
}
ExtractFilterType::Pointer m_ExtractFilter;
FilterType::Pointer m_Filter;
};
}
}
OTB_APPLICATION_EXPORT( otb::Wrapper::MeanResample )
/*=========================================================================
Copyright (c) Remi Cresson (IRSTEA). All rights reserved.
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.
=========================================================================*/
#ifndef MeanResampleImageFilter_H_
#define MeanResampleImageFilter_H_
#include "otbImage.h"
#include "itkImageToImageFilter.h"
#include "itkNumericTraits.h"
#include "itkSimpleDataObjectDecorator.h"
#include "itkImageRegionConstIterator.h"
#include "itkImageRegionIterator.h"
// No data
#include "otbNoDataHelper.h"
namespace otb
{
/**
* \class MeanResampleImageFilter
* \brief This filter decimates an input image using the mean value of the pixels neighborhood.
*
* \ingroup TimeSeriesUtils
*/
template <class TImage>
class ITK_EXPORT MeanResampleImageFilter :
public itk::ImageToImageFilter<TImage, TImage>
{
public:
/** Standard class typedefs. */
typedef MeanResampleImageFilter Self;
typedef itk::ImageToImageFilter<TImage, TImage> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(MeanResampleImageFilter, itk::ImageToImageFilter);
/** Iterators typedefs */
typedef TImage ImageType;
typedef typename ImageType::RegionType ImageRegionType;
typedef typename ImageType::Pointer ImagePointer;
typedef typename ImageType::PointType ImagePointType;
typedef typename ImageType::InternalPixelType ImagePixelValueType;
typedef typename ImageType::PixelType ImagePixelType;
typedef typename ImageType::IndexType ImageIndexType;
typedef typename ImageType::SpacingType ImageSpacingType;
typedef typename ImageType::SizeType ImageSizeType;
typedef typename itk::ImageRegionConstIterator<TImage> InputImageIteratorType;
typedef typename itk::ImageRegionIterator<TImage> OutputImageIteratorType;
itkSetMacro(NoDataValue, ImagePixelValueType);
itkGetMacro(NoDataValue, ImagePixelValueType);
itkSetMacro(StepX, unsigned int);
itkSetMacro(StepY, unsigned int);
protected:
MeanResampleImageFilter();
virtual ~MeanResampleImageFilter() {};
virtual void GenerateOutputInformation(void);
virtual void GenerateInputRequestedRegion(void);
virtual void ThreadedGenerateData(const ImageRegionType& outputRegionForThread,
itk::ThreadIdType threadId);
private:
MeanResampleImageFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
unsigned int m_StepX;
unsigned int m_StepY;
ImagePixelValueType m_NoDataValue;
};
} // end namespace gtb
#include <otbMeanResampleImageFilter.hxx>
#endif /* MeanResampleImageFilter_H_ */
/*=========================================================================
Copyright (c) Remi Cresson (IRSTEA). All rights reserved.
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.
=========================================================================*/
#ifndef __MeanResampleImageFilter_hxx
#define __MeanResampleImageFilter_hxx
#include <otbMeanResampleImageFilter.h>
#include "itkProgressReporter.h"
namespace otb
{
/**
*
*/
template <class TImage>
MeanResampleImageFilter<TImage>
::MeanResampleImageFilter()
{
m_StepX = 1;
m_StepY = 1;
m_NoDataValue = 0;
}
template <class TImage>
void
MeanResampleImageFilter<TImage>
::GenerateOutputInformation()
{
Superclass::GenerateOutputInformation();
// Grab input image
ImageType * inputImage = static_cast<ImageType * >(
Superclass::ProcessObject::GetInput(0) );
ImageType * outputPtr = this->GetOutput();
// The new output image has the same origin
ImagePointType origin = inputImage->GetOrigin();
origin[0] += 0.5 * inputImage->GetSignedSpacing()[0] * (m_StepX - 1);
origin[1] += 0.5 * inputImage->GetSignedSpacing()[1] * (m_StepY - 1);
outputPtr->SetOrigin ( origin );
// New spacing for the output image
ImageSpacingType spacing = inputImage->GetSignedSpacing();
spacing[0] *= m_StepX;
spacing[1] *= m_StepY;
outputPtr->SetSignedSpacing (spacing);
// New size for the output image
ImageRegionType inRegion = inputImage->GetLargestPossibleRegion();
ImageRegionType outRegion;
outRegion.SetIndex(0, 0);
outRegion.SetIndex(1, 0);
outRegion.SetSize (0, inRegion.GetSize()[0] / m_StepX);
outRegion.SetSize (1, inRegion.GetSize()[1] / m_StepY);
outputPtr->SetLargestPossibleRegion( outRegion );
}
template <class TImage>
void
MeanResampleImageFilter<TImage>
::GenerateInputRequestedRegion()
{
// Output requested region
const ImageRegionType outRegion = this->GetOutput()->GetRequestedRegion();
// Grab input image
ImageType * inputImage = static_cast<ImageType * >(
Superclass::ProcessObject::GetInput(0) );
ImageRegionType inRegion;
inRegion.SetIndex(0, outRegion.GetIndex()[0] * m_StepX);
inRegion.SetIndex(1, outRegion.GetIndex()[1] * m_StepY);
inRegion.SetSize (0, outRegion.GetSize()[0] * m_StepX);
inRegion.SetSize (1, outRegion.GetSize()[1] * m_StepY);
inRegion.Crop(inputImage->GetLargestPossibleRegion());
inputImage->SetRequestedRegion(inRegion);
}
/**
*
*/
template <class TImage>
void
MeanResampleImageFilter<TImage>
::ThreadedGenerateData(const ImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
{
// Support progress methods/callbacks
itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels() );
// Iterate through the thread region
OutputImageIteratorType outputIt(this->GetOutput(), outputRegionForThread);
// Grab input image
ImageType * inputImage = static_cast<ImageType * >(
Superclass::ProcessObject::GetInput(0) );
for ( outputIt.GoToBegin(); !outputIt.IsAtEnd(); ++outputIt)
{
// sum
float accum = 0.0;
float npix = 0.0;
for (unsigned int x = 0; x < m_StepX ; x++)
for (unsigned int y = 0; y < m_StepY ; y++)
{
ImageIndexType index = outputIt.GetIndex();
index[0] *= m_StepX;
index[1] *= m_StepY;
index[0] += x;
index[1] += y;
if (inputImage->GetLargestPossibleRegion().IsInside(index))
{
float pixVal = inputImage->GetPixel(index);
if (pixVal != m_NoDataValue)
{
accum += pixVal;
npix += 1.0;
}
}
}
// normalize
if (npix > 0.0)
accum /= npix;
outputIt.Set(accum);
progress.CompletedPixel();
} // Next pixel
}
}
#endif
Supports Markdown
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