diff --git a/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx b/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx index 3a1f53eff353c5e962867dc24547d698015cbd21..a7353577a912f3e42268757e3e4a2e311fcd40e6 100644 --- a/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx +++ b/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx @@ -196,7 +196,7 @@ private: UCLSUnmixingFilterType::New(); unmixer->SetInput(inputImage); - unmixer->SetMatrix(endMembersMatrix); + unmixer->GetModifiableFunctor().SetMatrix(endMembersMatrix); unmixer->SetNumberOfThreads(1); // FIXME : currently buggy abundanceMap = unmixer->GetOutput(); diff --git a/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.h b/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.h index 68a52ea5ba97f7ead9d3bdc2645bb47e25ba1c2f..82d541808c4745a271ebb3f78e0b1c28cb242019 100644 --- a/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.h +++ b/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.h @@ -22,7 +22,7 @@ #define otbUnConstrainedLeastSquareImageFilter_h #include "itkMacro.h" -#include "otbUnaryFunctorImageFilter.h" +#include "otbFunctorImageFilter.h" #include "vnl/algo/vnl_svd.h" #include <boost/shared_ptr.hpp> @@ -33,8 +33,9 @@ namespace Functor { /** \class UnConstrainedLeastSquareFunctor * - * \brief TODO + * \brief Solves a least square system on a pixel * + * \sa UnConstrainedLeastSquareImageFilter * * \ingroup OTBUnmixing */ @@ -49,51 +50,14 @@ public: typedef vnl_vector<PrecisionType> VectorType; typedef vnl_matrix<PrecisionType> MatrixType; - UnConstrainedLeastSquareFunctor() : m_OutputSize(0) {} - virtual ~UnConstrainedLeastSquareFunctor() {} - - unsigned int GetOutputSize() const - { - return m_OutputSize; - } - - bool operator != (const UnConstrainedLeastSquareFunctor& itkNotUsed(other)) const - { - return true; - } - - bool operator == (const UnConstrainedLeastSquareFunctor& other) const - { - return !(*this != other); - } - - void SetMatrix(const MatrixType& m) - { - //std::cout << "m : " << m.rows() << " " << m.cols() << std::endl; - m_Svd.reset( new SVDType(m) ); - m_Inv = m_Svd->inverse(); - m_OutputSize = m.cols(); - } - - OutputType operator ()(const InputType& in) const - { - // TODO : support different types between input and output ? - VectorType inVector(in.Size()); - for (unsigned int i = 0; i < in.GetSize(); ++i ) - { - inVector[i] = in[i]; - } - - VectorType outVector = m_Inv * inVector; - - OutputType out(outVector.size()); - for (unsigned int i = 0; i < out.GetSize(); ++i ) - { - out[i] = outVector[i]; - } - - return out; - } + UnConstrainedLeastSquareFunctor() : m_OutputSize(0) {}; + virtual ~UnConstrainedLeastSquareFunctor() = default; + + size_t OutputSize(const std::array<size_t,1> & nbBands) const; + + void SetMatrix(const MatrixType& m); + + OutputType operator ()(const InputType& in) const; private: @@ -106,7 +70,7 @@ private: }; } -/** \class UnConstrainedLeastSquareImageFilter +/** \typedef UnConstrainedLeastSquareImageFilter * * \brief Solves a least square system for each pixel * @@ -127,63 +91,10 @@ private: * * \ingroup OTBUnmixing */ -template <class TInputImage, class TOutputImage, class TPrecision> -class ITK_EXPORT UnConstrainedLeastSquareImageFilter : - public otb::UnaryFunctorImageFilter<TInputImage, TOutputImage, - Functor::UnConstrainedLeastSquareFunctor<typename TInputImage::PixelType, - typename TOutputImage::PixelType, TPrecision> > -{ -public: - /** Standard class typedefs. */ - typedef UnConstrainedLeastSquareImageFilter Self; - typedef otb::UnaryFunctorImageFilter - <TInputImage, - TOutputImage, - Functor::UnConstrainedLeastSquareFunctor< - typename TInputImage::PixelType, - typename TOutputImage::PixelType, - TPrecision> - > Superclass; - - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; - - typedef Functor::UnConstrainedLeastSquareFunctor< - typename TInputImage::PixelType, - typename TOutputImage::PixelType, - TPrecision> FunctorType; - - typedef typename FunctorType::MatrixType MatrixType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(UnConstrainedLeastSquareImageFilter, otb::UnaryFunctorImageFilter); - - /** Pixel types. */ - typedef typename TInputImage::PixelType InputPixelType; - typedef typename TOutputImage::PixelType OutputPixelType; - - void SetMatrix(const MatrixType& m) - { - this->GetFunctor().SetMatrix(m); - this->Modified(); - } - -protected: - UnConstrainedLeastSquareImageFilter(); - - ~UnConstrainedLeastSquareImageFilter() override {} - - void PrintSelf(std::ostream& os, itk::Indent indent) const override; - -private: - UnConstrainedLeastSquareImageFilter(const Self &) = delete; - - void operator =(const Self&) = delete; - -}; +template <typename TInputImage, typename TOutputImage, typename TPrecision> +using UnConstrainedLeastSquareImageFilter = FunctorImageFilter< + Functor::UnConstrainedLeastSquareFunctor<typename TInputImage::PixelType, + typename TOutputImage::PixelType, TPrecision> >; } // end namespace otb diff --git a/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.hxx b/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.hxx index 151b927bff869ce5eb808b3c86aaa06d3d646315..4d939d25694fb35d27817472e58ac036c16d83ed 100644 --- a/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.hxx +++ b/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.hxx @@ -25,24 +25,51 @@ namespace otb { +namespace Functor +{ -/** - * - */ -template <class TInputImage, class TOutputImage, class TPrecision> -UnConstrainedLeastSquareImageFilter<TInputImage, TOutputImage, TPrecision> -::UnConstrainedLeastSquareImageFilter() +template <class TInput, class TOutput, class TPrecision> +size_t +UnConstrainedLeastSquareFunctor<TInput, TOutput, TPrecision> +::OutputSize(const std::array<size_t,1> & itkNotUsed(nbBands)) const { + return m_OutputSize; } -template <class TInputImage, class TOutputImage, class TPrecision> +template <class TInput, class TOutput, class TPrecision> void -UnConstrainedLeastSquareImageFilter<TInputImage, TOutputImage, TPrecision> -::PrintSelf(std::ostream& os, itk::Indent indent) const +UnConstrainedLeastSquareFunctor<TInput, TOutput, TPrecision> +::SetMatrix(const MatrixType& m) { - Superclass::PrintSelf(os, indent); + m_Svd.reset( new SVDType(m) ); + m_Inv = m_Svd->inverse(); + m_OutputSize = m.cols(); } -} // end namespace +template <class TInput, class TOutput, class TPrecision> +typename UnConstrainedLeastSquareFunctor<TInput, TOutput, TPrecision>::OutputType +UnConstrainedLeastSquareFunctor<TInput, TOutput, TPrecision> +::operator ()(const InputType& in) const +{ + VectorType inVector(in.Size()); + for (unsigned int i = 0; i < in.GetSize(); ++i ) + { + inVector[i] = in[i]; + } + + VectorType outVector = m_Inv * inVector; + + OutputType out(outVector.size()); + for (unsigned int i = 0; i < out.GetSize(); ++i ) + { + out[i] = outVector[i]; + } + + return out; + } + + +} // end namespace Functor +} // end namespace otb #endif diff --git a/Modules/Hyperspectral/Unmixing/test/otbUnConstrainedLeastSquareImageFilter.cxx b/Modules/Hyperspectral/Unmixing/test/otbUnConstrainedLeastSquareImageFilter.cxx index 3a031bdd0849948aa2b2d2b539283f9bd9a0a3f2..1ab8e00bae0ef3f179021d087d733db5f01926fc 100644 --- a/Modules/Hyperspectral/Unmixing/test/otbUnConstrainedLeastSquareImageFilter.cxx +++ b/Modules/Hyperspectral/Unmixing/test/otbUnConstrainedLeastSquareImageFilter.cxx @@ -57,7 +57,7 @@ int otbUnConstrainedLeastSquareImageFilterTest(int itkNotUsed(argc), char * argv UnConstrainedLeastSquareSolverType::New(); unmixer->SetInput(readerImage->GetOutput()); - unmixer->SetMatrix(endMember2Matrix->GetMatrix()); + unmixer->GetModifiableFunctor().SetMatrix(endMember2Matrix->GetMatrix()); WriterType::Pointer writer = WriterType::New(); writer->SetFileName(outputImage);