diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index ad591a5cf23eb8971fe1fec2a2304367f294eaf8..50e651b602cbd332f98e6c58403e793b8d2d0624 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -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) + diff --git a/app/otbMeanResample.cxx b/app/otbMeanResample.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a9522e50d85903b0f06953f73940d93423568483 --- /dev/null +++ b/app/otbMeanResample.cxx @@ -0,0 +1,122 @@ +/*========================================================================= + + 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 ) diff --git a/include/otbMeanResampleImageFilter.h b/include/otbMeanResampleImageFilter.h new file mode 100644 index 0000000000000000000000000000000000000000..550d37ef5de15addb069c382969d27c186076496 --- /dev/null +++ b/include/otbMeanResampleImageFilter.h @@ -0,0 +1,101 @@ +/*========================================================================= + + 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_ */ diff --git a/include/otbMeanResampleImageFilter.hxx b/include/otbMeanResampleImageFilter.hxx new file mode 100644 index 0000000000000000000000000000000000000000..168ab991371137994b3c0244f03e24c727b0fc7b --- /dev/null +++ b/include/otbMeanResampleImageFilter.hxx @@ -0,0 +1,147 @@ +/*========================================================================= + + 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 + + +