Commit 03f565d6 authored by Julien Malik's avatar Julien Malik
Browse files

ENH: support premultiplication by matrix in MatrixImageFilter

parent 52e5d16f
......@@ -25,10 +25,15 @@ namespace otb
{
/** \class MatrixImageFilter
* \brief Apply a transition matrix over the channel of an image.
* \brief Apply a matrix multiplication over the channels of an image.
*
* The templates are the input and output image type.
* The transition matrix is given using the SetTransitionMatrix() method. The waiting type is a vnl_matrix<double> (ie. MatrixType).
* The transition matrix is given using the SetTransitionMatrix() method.
* The awaited type must be compatible with vnl_matrix<double>
*
* The multiplication can be done as \f$ p . M \f$ or \f$ M . p \f$ where \f$ p \f$ is the pixel and \f$ M \f$ is the vector.
* The behavior can be chosen with
*
* The number of rows of the matrix must be the input image number of channels, the number of columns is the number of channels of the output image.
*
* For example, if the image has 2 bands, the matrix is \f$ \begin{pmatrix} \alpha & \beta \\ \gama & \delta \end{pmatrix} \f$
......@@ -95,6 +100,10 @@ public:
return m_Matrix;
}
itkGetConstMacro( MatrixByVector, bool );
itkSetMacro( MatrixByVector, bool );
itkBooleanMacro( MatrixByVector );
protected:
MatrixImageFilter();
virtual ~MatrixImageFilter() {}
......@@ -120,10 +129,13 @@ private:
MatrixImageFilter(const Self &); //purposely not implemented
void operator =(const Self&); //purposely not implemented
/** Radius declaration */
//SizeType m_Radius;
/** Matrix declaration */
MatrixType m_Matrix;
/** If set to true, the applied operation is \f$ M . p \f$ where p is the pixel represented as a column vector.
Otherwise the applied operation is \f$ p . M \f$ where p is the pixel represented as a row vector.
*/
bool m_MatrixByVector;
};
} // end namespace otb
......
......@@ -30,7 +30,7 @@ namespace otb
*
*/
template <class TInputImage, class TOutputImage, class TMatrix>
MatrixImageFilter<TInputImage, TOutputImage, TMatrix>::MatrixImageFilter() : m_Matrix()
MatrixImageFilter<TInputImage, TOutputImage, TMatrix>::MatrixImageFilter() : m_MatrixByVector(false)
{
}
......@@ -40,18 +40,33 @@ void MatrixImageFilter<TInputImage, TOutputImage, TMatrix>::GenerateOutputInform
// call the superclass' implementation of this method
Superclass::GenerateOutputInformation();
if( this->GetInput()->GetNumberOfComponentsPerPixel() != m_Matrix.rows() )
if ( m_MatrixByVector )
{
itkExceptionMacro("Invalid Matrix size. Number of columns must be the same as the image number of channels.");
if( this->GetInput()->GetNumberOfComponentsPerPixel() != m_Matrix.cols() )
{
itkExceptionMacro("Invalid Matrix size. Number of columns must be the same as the image number of channels.");
}
if( m_Matrix.rows() == 0 )
{
itkExceptionMacro("Invalid Matrix size. Number of rows can't be null.");
}
this->GetOutput()->SetNumberOfComponentsPerPixel( m_Matrix.rows() );
}
if( m_Matrix.cols() == 0 )
if ( !m_MatrixByVector )
{
itkExceptionMacro("Invalid Matrix size. Number of rows can't be null.");
if( this->GetInput()->GetNumberOfComponentsPerPixel() != m_Matrix.rows() )
{
itkExceptionMacro("Invalid Matrix size. Number of rows must be the same as the image number of channels.");
}
if( m_Matrix.cols() == 0 )
{
itkExceptionMacro("Invalid Matrix size. Number of columns can't be null.");
}
this->GetOutput()->SetNumberOfComponentsPerPixel( m_Matrix.cols() );
}
this->GetOutput()->SetNumberOfComponentsPerPixel( m_Matrix.cols() );
}
template<class TInputImage, class TOutputImage, class TMatrix>
......@@ -74,8 +89,8 @@ void MatrixImageFilter<TInputImage, TOutputImage, TMatrix>::ThreadedGenerateData
inIt.GoToBegin();
outIt.GoToBegin();
const unsigned int inSize = m_Matrix.rows();
const unsigned int outSize = m_Matrix.cols();
const unsigned int inSize = m_MatrixByVector ? m_Matrix.cols() : m_Matrix.rows();
const unsigned int outSize = m_MatrixByVector ? m_Matrix.rows() : m_Matrix.cols();
VectorType inVect(inSize, InputRealType(0.));
VectorType outVect(outSize, InputRealType(0.));
......@@ -91,7 +106,7 @@ void MatrixImageFilter<TInputImage, TOutputImage, TMatrix>::ThreadedGenerateData
inVect[i] = static_cast<InputRealType>(inPix[i]);
}
outVect = inVect*m_Matrix;
outVect = m_MatrixByVector ? m_Matrix*inVect : inVect*m_Matrix;
for(unsigned int i=0; i<outSize; i++)
{
......@@ -115,6 +130,7 @@ MatrixImageFilter<TInputImage, TOutputImage, TMatrix>::PrintSelf(std::ostream& o
{
Superclass::PrintSelf(os, indent);
os << indent << "Matrix: " << m_Matrix << std::endl;
os << indent << "MatrixByVector: " << m_MatrixByVector << std::endl;
}
} // end namespace otb
......
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