21 #ifndef otbMultivariateAlterationDetectorImageFilter_hxx
22 #define otbMultivariateAlterationDetectorImageFilter_hxx
27 #include "vnl/algo/vnl_matrix_inverse.h"
28 #include "vnl/algo/vnl_generalized_eigensystem.h"
30 #include "itkImageRegionIterator.h"
31 #include "itkProgressReporter.h"
35 template <
class TInputImage,
class TOutputImage>
38 this->SetNumberOfRequiredInputs(2);
39 m_CovarianceEstimator = CovarianceEstimatorType::New();
42 template <
class TInputImage,
class TOutputImage>
46 this->SetNthInput(0,
const_cast<TInputImage*
>(image1));
49 template <
class TInputImage,
class TOutputImage>
53 if (this->GetNumberOfInputs() < 1)
57 return static_cast<const TInputImage*
>(this->itk::ProcessObject::GetInput(0));
60 template <
class TInputImage,
class TOutputImage>
64 this->SetNthInput(1,
const_cast<TInputImage*
>(image2));
67 template <
class TInputImage,
class TOutputImage>
71 if (this->GetNumberOfInputs() < 2)
75 return static_cast<const TInputImage*
>(this->itk::ProcessObject::GetInput(1));
79 template <
class TInputImage,
class TOutputImage>
83 Superclass::GenerateOutputInformation();
86 const TInputImage* input1Ptr = this->GetInput1();
87 const TInputImage* input2Ptr = this->GetInput2();
88 TOutputImage* outputPtr =
const_cast<TOutputImage*
>(this->GetOutput());
91 unsigned int nbComp1 = input1Ptr->GetNumberOfComponentsPerPixel();
92 unsigned int nbComp2 = input2Ptr->GetNumberOfComponentsPerPixel();
93 unsigned int outNbComp = std::max(nbComp1, nbComp2);
95 outputPtr->SetNumberOfComponentsPerPixel(outNbComp);
97 if (input1Ptr->GetLargestPossibleRegion() != input2Ptr->GetLargestPossibleRegion())
99 itkExceptionMacro(<<
"Input images does not have the same size!");
104 concatenateFilter->SetInput1(input1Ptr);
105 concatenateFilter->SetInput2(input2Ptr);
109 m_CovarianceEstimator->SetInput(concatenateFilter->GetOutput());
110 m_CovarianceEstimator->Update();
111 m_CovarianceMatrix = m_CovarianceEstimator->GetCovariance();
112 m_MeanValues = m_CovarianceEstimator->GetMean();
115 VnlMatrixType s11 = m_CovarianceMatrix.GetVnlMatrix().extract(nbComp1, nbComp1);
116 VnlMatrixType s22 = m_CovarianceMatrix.GetVnlMatrix().extract(nbComp2, nbComp2, nbComp1, nbComp1);
117 VnlMatrixType s12 = m_CovarianceMatrix.GetVnlMatrix().extract(nbComp1, nbComp2, 0, nbComp1);
124 for (
unsigned int i = 0; i < nbComp1; ++i)
126 m_Mean1[i] = m_MeanValues[i];
129 for (
unsigned int i = 0; i < nbComp2; ++i)
131 m_Mean2[i] = m_MeanValues[nbComp1 + i];
134 if (nbComp1 == nbComp2)
143 vnl_generalized_eigensystem ges(s12s22is21, s11);
148 m_Rho = ges.D.get_diagonal();
149 m_Rho = m_Rho.apply(&std::sqrt);
158 invstderr1.set_diagonal(diag1);
166 for (
unsigned int i = 0; i < nbComp1; ++i)
168 aux5 = aux5 + aux4.get_row(i);
171 sign1.set_diagonal(aux5);
176 m_V2 = invs22 * s21 * m_V1;
181 aux2 = aux2.apply(&std::sqrt);
185 aux3.set_diagonal(aux2);
193 sl.update(s12, 0, nbComp1);
194 sl.update(s21, nbComp1, 0);
195 sr.update(s11, 0, 0);
196 sr.update(s22, nbComp1, nbComp1);
198 vnl_generalized_eigensystem ges(sl, sr);
204 m_V1 = V.extract(nbComp1, nbComp1);
205 m_V2 = V.extract(nbComp2, nbComp2, nbComp1, 0);
207 m_Rho = ges.D.get_diagonal().flip().extract(std::max(nbComp1, nbComp2), 0);
213 aux2 = aux2.apply(&std::sqrt);
217 aux3.set_diagonal(aux2);
224 invstderr1.set_diagonal(diag1);
232 for (
unsigned int i = 0; i < nbComp1; ++i)
234 aux5 = aux5 + aux4.get_row(i);
237 sign1.set_diagonal(aux5);
243 aux1 = m_V2.transpose() * (s22 * m_V2);
244 aux2 = aux1.get_diagonal();
245 aux2 = aux2.apply(&std::sqrt);
249 aux3.set_diagonal(aux2);
254 aux5 = (m_V1.transpose() * s12 * m_V2).transpose().get_diagonal();
255 sign2.set_diagonal(aux5);
263 template <
class TInputImage,
class TOutputImage>
265 itk::ThreadIdType threadId)
268 const TInputImage* input1Ptr = this->GetInput1();
269 const TInputImage* input2Ptr = this->GetInput2();
270 TOutputImage* outputPtr = this->GetOutput();
273 typedef itk::ImageRegionConstIterator<InputImageType> ConstIteratorType;
274 typedef itk::ImageRegionIterator<OutputImageType> IteratorType;
276 IteratorType outIt(outputPtr, outputRegionForThread);
277 ConstIteratorType inIt1(input1Ptr, outputRegionForThread);
278 ConstIteratorType inIt2(input2Ptr, outputRegionForThread);
285 unsigned int nbComp1 = input1Ptr->GetNumberOfComponentsPerPixel();
286 unsigned int nbComp2 = input2Ptr->GetNumberOfComponentsPerPixel();
287 unsigned int outNbComp = outputPtr->GetNumberOfComponentsPerPixel();
290 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
292 while (!inIt1.IsAtEnd() && !inIt2.IsAtEnd() && !outIt.IsAtEnd())
300 for (
unsigned int i = 0; i < nbComp1; ++i)
302 x1[i] = inIt1.Get()[i];
305 for (
unsigned int i = 0; i < nbComp2; ++i)
307 x2[i] = inIt2.Get()[i];
313 for (
unsigned int i = 0; i < nbComp1; ++i)
318 for (
unsigned int i = 0; i < nbComp2; ++i)
320 x2bis[i] = second[i];
325 typename OutputImageType::PixelType outPixel(outNbComp);
327 if (nbComp1 == nbComp2)
329 for (
unsigned int i = 0; i < outNbComp; ++i)
331 outPixel[i] = mad[i];
336 for (
unsigned int i = 0; i < outNbComp; ++i)
338 outPixel[i] = mad[outNbComp - i - 1];
340 if (i < outNbComp - std::min(nbComp1, nbComp2))
342 outPixel[i] *= std::sqrt(2.);
352 progress.CompletedPixel();