Commit e4c5deae authored by Cyrille Valladeau's avatar Cyrille Valladeau

ENH : add a filter that make simple operation betwwen image and vectorimage (+,-,*,/) + tests

parent c9568cde
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
Some parts of this code are derived from ITK. See ITKCopyright.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.
=========================================================================*/
#ifndef __otbImageAndVectorImageOperationFilter_h
#define __otbImageAndVectorImageOperationFilter_h
#include "itkBinaryFunctorImageFilter.h"
#include "itkImageToImageFilter.h"
namespace otb
{
namespace Functor
{
template <typename TInput,typename TVectorInput, typename TOutput>
class ITK_EXPORT ImageAndVectorImageOperationFunctor
{
public:
typedef typename TVectorInput::ValueType InternalInputPixelType;
typedef typename TOutput::ValueType InternalOutputPixelType;
typedef enum{MULTIPLICATION, ADDITION, DIVISON, SUBSTRACTION } OperatorType;
ImageAndVectorImageOperationFunctor()
{
m_Operator = ADDITION;//1;
};
~ImageAndVectorImageOperationFunctor(){};
void SetOperator(OperatorType oper)
{
m_Operator = oper;
}
OperatorType GetOperator()
{
return m_Operator;
}
inline TOutput operator() (const TInput & inPix, const TVectorInput & vInPix)
{
TOutput out;
out.SetSize( vInPix.Size() );
TVectorInput vInTmp = vInPix;
switch(m_Operator)
{
case MULTIPLICATION:
{
vInTmp *= static_cast<InternalInputPixelType>(inPix);
break;
}
case ADDITION:
{
vInTmp += static_cast<InternalInputPixelType>(inPix);
break;
}
case DIVISON:
{
if(inPix!=0)
vInTmp /= static_cast<InternalInputPixelType>(inPix);
else
{
vInTmp.Fill(0);
}
break;
}
case SUBSTRACTION:
{
vInTmp -= static_cast<InternalInputPixelType>(inPix);
break;
}
default:
{
}
}
for(unsigned int i=0; i<vInTmp.Size(); i++)
{
out[i] = static_cast<InternalInputPixelType>(vInTmp[i]);
}
return out;
}
protected:
OperatorType m_Operator;
};
}
/** \class ImageAndVectorImageOperationFilter
* \brief Provides simple pixel to pixel operation between Image and VectorImage.
*
* Apply an operation (multiplication, division, addition or substraction) between
* the input image and each channel of the vector input image.
* Use SetOperation( MULTIPLICATION, ADDITION, DIVISON or SUBSTRACTION ) to select the wanted operation.
* Default is an addition.
*
* This class is templated over the input Image and VectorImage and output VectorImage types.
*
* \sa itkMultiplyImageFilter
* \ingroup itkBinaryFunctorImageFilter
*/
template <class TInputImage, class TVectorInputImage, class TOutputImage>
class ITK_EXPORT ImageAndVectorImageOperationFilter:
public itk::BinaryFunctorImageFilter<TInputImage,
TVectorInputImage,
TOutputImage,
Functor::ImageAndVectorImageOperationFunctor<ITK_TYPENAME TInputImage::PixelType,
ITK_TYPENAME TVectorInputImage::PixelType,
ITK_TYPENAME TOutputImage::PixelType > >
//ImageToImageFilter< TVectorInputImage, TOutputImage >
{
public:
/** Standard class typedefs. */
typedef ImageAndVectorImageOperationFilter Self;
//typedef itk::ImageToImageFilter<TVectorInputImage, TOutputImage> Superclass;
typedef Functor::ImageAndVectorImageOperationFunctor<ITK_TYPENAME TInputImage::PixelType,
ITK_TYPENAME TVectorInputImage::PixelType,
ITK_TYPENAME TOutputImage::PixelType > FunctorType;
typedef itk::BinaryFunctorImageFilter<TInputImage, TVectorInputImage, TOutputImage, FunctorType> 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(ImageAndVectorImageOperationFilter,itk::BinaryFunctorImageFilter);
/** Typedef for the images. */
typedef TInputImage InputImageType;
typedef typename InputImageType::PixelType InputPixelType;
typedef TVectorInputImage VectorInputImageType;
typedef typename VectorInputImageType::PixelType VectorInputPixelType;
typedef TOutputImage OutputImageType;
typedef typename OutputImageType::PixelType OutputPixelType;
/** Operation type typedef. */
typedef typename FunctorType::OperatorType OperatorType;
/** Set the input images of this process object. */
void SetInput( const InputImageType *input );
void SetVectorInput( const VectorInputImageType *input );
/** Get the input images of this process object. */
const InputImageType * GetInput();
const VectorInputImageType * GetVectorInput();
/** Accessors */
itkGetMacro(UseAddition, bool);
itkGetMacro(UseMultiplication, bool);
itkGetMacro(UseDivision, bool);
itkGetMacro(UseSubstraction, bool);
void UseAddition()
{
m_UseAddition = true;
m_UseMultiplication = false;
m_UseDivision = false;
m_UseSubstraction = false;
this->GetFunctor().SetOperator(static_cast<OperatorType>(1));
this->Modified();
}
void UseMultiplication()
{
m_UseAddition = false;
m_UseMultiplication = true;
m_UseDivision = false;
m_UseSubstraction = false;
this->GetFunctor().SetOperator(static_cast<OperatorType>(0));
this->Modified();
}
void UseDivision()
{
m_UseAddition = false;
m_UseMultiplication = false;
m_UseDivision = true;
m_UseSubstraction = false;
this->GetFunctor().SetOperator(static_cast<OperatorType>(2));
this->Modified();
}
void UseSubstraction()
{
m_UseAddition = false;
m_UseMultiplication = false;
m_UseDivision = false;
m_UseSubstraction = true;
this->GetFunctor().SetOperator(static_cast<OperatorType>(3));
this->Modified();
}
protected:
ImageAndVectorImageOperationFilter();
~ImageAndVectorImageOperationFilter();
/** This is a source, so it must set the spacing, size, and largest possible
* region for the output image that it will produce.
* \sa ProcessObject::GenerateOutputInformation() */
virtual void GenerateOutputInformation();
private:
ImageAndVectorImageOperationFilter(const ImageAndVectorImageOperationFilter &); //purposely not implemented
void operator=(const ImageAndVectorImageOperationFilter&); //purposely not implemented
bool m_UseAddition;
bool m_UseMultiplication;
bool m_UseDivision;
bool m_UseSubstraction;
};
} // end namespace otb
#ifndef ITK_MANUAL_INSTANTIATION
#include "otbImageAndVectorImageOperationFilter.txx"
#endif
#endif
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
Some parts of this code are derived from ITK. See ITKCopyright.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.
=========================================================================*/
#ifndef __otbImageAndVectorImageOperationFilter_txx
#define __otbImageAndVectorImageOperationFilter_txx
#include "otbImageAndVectorImageOperationFilter.h"
#include "itkObjectFactory.h"
namespace otb
{
template <class TInputImage, class TVectorInputImage, class TOutputImage>
ImageAndVectorImageOperationFilter<TInputImage, TVectorInputImage, TOutputImage>
::ImageAndVectorImageOperationFilter()
{
this->UseAddition();
}
template <class TInputImage, class TVectorInputImage, class TOutputImage>
ImageAndVectorImageOperationFilter<TInputImage, TVectorInputImage, TOutputImage>
::~ImageAndVectorImageOperationFilter()
{
}
template <class TInputImage, class TVectorInputImage, class TOutputImage>
void
ImageAndVectorImageOperationFilter<TInputImage, TVectorInputImage, TOutputImage>
::SetInput(const InputImageType *input)
{
this->SetNthInput(0, const_cast< InputImageType * >(input) );
}
template <class TInputImage, class TVectorInputImage, class TOutputImage>
void
ImageAndVectorImageOperationFilter<TInputImage, TVectorInputImage, TOutputImage>
::SetVectorInput(const VectorInputImageType *input)
{
this->SetNthInput(1, const_cast< VectorInputImageType * >(input) );
}
template <class TInputImage, class TVectorInputImage, class TOutputImage>
const typename ImageAndVectorImageOperationFilter<TInputImage, TVectorInputImage, TOutputImage>::InputImageType *
ImageAndVectorImageOperationFilter<TInputImage, TVectorInputImage, TOutputImage>
::GetInput()
{
if (this->GetNumberOfInputs() < 1)
return 0;
return dynamic_cast<const InputImageType*>(this->GetInput(0));
}
template <class TInputImage, class TVectorInputImage, class TOutputImage>
const typename ImageAndVectorImageOperationFilter<TInputImage, TVectorInputImage, TOutputImage>::VectorInputImageType *
ImageAndVectorImageOperationFilter<TInputImage, TVectorInputImage, TOutputImage>
::GetVectorInput()
{
if (this->GetNumberOfInputs() < 2)
return 0;
return dynamic_cast<const VectorInputImageType*>(this->itk::ProcessObject::GetInput(1));
}
/**
*
*/
template <class TInputImage, class TVectorInputImage, class TOutputImage>
void
ImageAndVectorImageOperationFilter<TInputImage, TVectorInputImage, TOutputImage>
::GenerateOutputInformation()
{
// call the superclass' implementation of this method
Superclass::GenerateOutputInformation();
this->GetOutput()->SetNumberOfComponentsPerPixel( this->GetVectorInput()->GetNumberOfComponentsPerPixel());
}
} // end namespace otb
#endif
......@@ -1532,6 +1532,28 @@ ADD_TEST(bfTvSubsampleImageFilter ${BASICFILTERS_TESTS12}
${TEMP}/bfSubsampleImageFilterOnePixelOutOf2.tif
)
# ----- otbImageAndVectorImageOperationFilter --------------------------------------
ADD_TEST(bfTuImageAndVectorImageOperationFilterNew ${BASICFILTERS_TESTS12}
otbImageAndVectorImageOperationFilterNew)
ADD_TEST(bfTvImageAndVectorImageOperationFilterTest ${BASICFILTERS_TESTS12}
--compare-n-images ${NOTOL} 4
${TEMP}/bfTvImageAndVectorImageOperationFilterTestAdd.tif
${BASELINE}/bfTvImageAndVectorImageOperationFilterTestAdd.tif
${TEMP}/bfTvImageAndVectorImageOperationFilterTestSub.tif
${BASELINE}/bfTvImageAndVectorImageOperationFilterTestSub.tif
${TEMP}/bfTvImageAndVectorImageOperationFilterTestMul.tif
${BASELINE}/bfTvImageAndVectorImageOperationFilterTestMul.tif
${TEMP}/bfTvImageAndVectorImageOperationFilterTestDiv.tif
${BASELINE}/bfTvImageAndVectorImageOperationFilterTestDiv.tif
otbImageAndVectorImageOperationFilterTest
${INPUTDATA}/checkerboard_128_128.png
${INPUTDATA}/poupees_sub.png
${TEMP}/bfTvImageAndVectorImageOperationFilterTestAdd.tif
${TEMP}/bfTvImageAndVectorImageOperationFilterTestSub.tif
${TEMP}/bfTvImageAndVectorImageOperationFilterTestMul.tif
${TEMP}/bfTvImageAndVectorImageOperationFilterTestDiv.tif
)
# A enrichir
......@@ -1734,6 +1756,8 @@ otbChangeLabelImageFilterNew.cxx
otbChangeLabelImageFilter.cxx
otbSubsampleImageFilterNew.cxx
otbSubsampleImageFilter.cxx
otbImageAndVectorImageOperationFilterNew.cxx
otbImageAndVectorImageOperationFilterTest.cxx
)
INCLUDE_DIRECTORIES(${OTB_SOURCE_DIR}/Testing/Code)
......
......@@ -33,4 +33,6 @@ REGISTER_TEST(otbChangeLabelImageFilterNew);
REGISTER_TEST(otbChangeLabelImageFilter);
REGISTER_TEST(otbSubsampleImageFilterNew);
REGISTER_TEST(otbSubsampleImageFilter);
REGISTER_TEST(otbImageAndVectorImageOperationFilterNew);
REGISTER_TEST(otbImageAndVectorImageOperationFilterTest);
}
/*=========================================================================
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.
=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#include "itkExceptionObject.h"
#include <iostream>
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageAndVectorImageOperationFilter.h"
int otbImageAndVectorImageOperationFilterNew( int argc, char * argv[] )
{
typedef double PixelType;
typedef otb::Image<PixelType, 2> ScalarImageType;
typedef otb::VectorImage<PixelType, 2> VectorImageType;
typedef otb::ImageAndVectorImageOperationFilter<ScalarImageType, VectorImageType, VectorImageType> FilterType;
FilterType::Pointer filter = FilterType::New();
return EXIT_SUCCESS;
}
/*=========================================================================
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.
=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#include "itkExceptionObject.h"
#include <iostream>
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbImageAndVectorImageOperationFilter.h"
int otbImageAndVectorImageOperationFilterTest( int argc, char * argv[] )
{
const char * infname = argv[1];
const char * invectfname = argv[2];
const char * outfnameAdd = argv[3];
const char * outfnameSub = argv[4];
const char * outfnameMul = argv[5];
const char * outfnameDiv = argv[6];
typedef double PixelType;
typedef otb::Image<PixelType, 2> ScalarImageType;
typedef otb::VectorImage<PixelType, 2> VectorImageType;
typedef otb::ImageFileReader<ScalarImageType> ReaderType;
typedef otb::ImageFileReader<VectorImageType> VectorReaderType;
typedef otb::ImageFileWriter<VectorImageType> WriterType;
typedef otb::ImageAndVectorImageOperationFilter<ScalarImageType, VectorImageType, VectorImageType> FilterType;
ReaderType::Pointer reader = ReaderType::New();
VectorReaderType::Pointer vectorReader = VectorReaderType::New();
FilterType::Pointer filter = FilterType::New();
WriterType::Pointer writerAdd = WriterType::New();
WriterType::Pointer writerSub = WriterType::New();
WriterType::Pointer writerMul = WriterType::New();
WriterType::Pointer writerDiv = WriterType::New();
reader->SetFileName(infname);
vectorReader->SetFileName(invectfname);
filter->SetInput(reader->GetOutput());
filter->SetVectorInput(vectorReader->GetOutput());
filter->UseAddition();
writerAdd->SetInput( filter->GetOutput() );
writerAdd->SetFileName(outfnameAdd);
writerAdd->Update();
filter->UseSubstraction();
writerSub->SetInput( filter->GetOutput() );
writerSub->SetFileName(outfnameSub);
writerSub->Update();
filter->UseMultiplication();
writerMul->SetInput( filter->GetOutput() );
writerMul->SetFileName(outfnameMul);
writerMul->Update();
filter->UseDivision();
writerDiv->SetInput( filter->GetOutput() );
writerDiv->SetFileName(outfnameDiv);
writerDiv->Update();
return EXIT_SUCCESS;
}
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