OTB  10.0.0
Orfeo Toolbox
otbEstimateInnerProductPCAImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2024 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbEstimateInnerProductPCAImageFilter_hxx
22 #define otbEstimateInnerProductPCAImageFilter_hxx
23 
25 
26 #include <vnl/algo/vnl_generalized_eigensystem.h>
27 #include <vnl/vnl_math.h>
28 
29 namespace otb
30 {
31 
35 template <class TInputImage, class TOutputImage>
37  : m_NumberOfPrincipalComponentsRequired(1), m_CenterData(true)
38 {
39  this->DynamicMultiThreadingOn();
40 }
41 
45 template <class TInputImage, class TOutputImage>
46 void EstimateInnerProductPCAImageFilter<TInputImage, TOutputImage>::PrintSelf(std::ostream& os, itk::Indent indent) const
47 {
48  this->Superclass::PrintSelf(os, indent);
49 }
50 
54 template <class TInputImage, class TOutputImage>
56 {
57  Superclass::GenerateOutputInformation();
58  this->GetOutput()->SetNumberOfComponentsPerPixel(m_NumberOfPrincipalComponentsRequired);
59 }
61 
65 template <class TInputImage, class TOutputImage>
67 {
68  // Instantiation object
69  StreamingInnerProductPointer streamingInnerProduct = StreamingInnerProductType::New();
70  streamingInnerProduct->SetInput(const_cast<InputImageType*>(this->GetInput()));
71  streamingInnerProduct->SetCenterData(m_CenterData);
72  streamingInnerProduct->Update();
73  m_InnerProduct = streamingInnerProduct->GetInnerProduct();
75 
76  MatrixType identityMatrix(m_InnerProduct.rows(), m_InnerProduct.columns());
77  identityMatrix.set_identity();
78  vnl_generalized_eigensystem eigenVectors_eigenValues(m_InnerProduct, identityMatrix);
79  m_EigenVectorsOfInnerProductMatrix = eigenVectors_eigenValues.V;
80 }
81 
82 template <class TInputImage, class TOutputImage>
84 {
85  typename InputImageType::ConstPointer inputPtr = this->GetInput();
86  typename OutputImageType::Pointer outputPtr = this->GetOutput();
87 
88  // Define the portion of the input to walk for this thread, using
89  // the CallCopyOutputRegionToInputRegion method allows for the input
90  // and output images to be different dimensions
91  unsigned int numberOfTrainingImages = inputPtr->GetNumberOfComponentsPerPixel();
92 
93  InputImageRegionType inputRegionForThread;
94  this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
95 
96  // Define the iterators
97  itk::ImageRegionConstIterator<TInputImage> inputIt(inputPtr, inputRegionForThread);
98  itk::ImageRegionIterator<TOutputImage> outputIt(outputPtr, outputRegionForThread);
99 
100  inputIt.GoToBegin();
101  outputIt.GoToBegin();
102 
103  while (!inputIt.IsAtEnd())
104  {
105  InputPixelType inputPixel = inputIt.Get();
106  OutputPixelType outputPixel;
107  outputPixel.SetSize(m_NumberOfPrincipalComponentsRequired);
108  outputPixel.Fill(0);
109 
110  for (unsigned int img_number = 0; img_number < numberOfTrainingImages; ++img_number)
111  {
112  unsigned int indexNumberOfTrainingImages = numberOfTrainingImages - 1;
113  for (unsigned int vec_number = 0; vec_number < m_NumberOfPrincipalComponentsRequired; ++vec_number, indexNumberOfTrainingImages--)
114  {
115  outputPixel[vec_number] += static_cast<OutputInternalPixelType>(
116  static_cast<double>(inputPixel[img_number]) * static_cast<double>(m_EigenVectorsOfInnerProductMatrix[img_number][indexNumberOfTrainingImages]));
117  }
118  }
119  outputIt.Set(outputPixel);
120  ++inputIt;
121  ++outputIt;
122  }
123 }
124 }
125 
126 #endif
StreamingInnerProductType::Pointer StreamingInnerProductPointer
void PrintSelf(std::ostream &os, itk::Indent indent) const override
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) override
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.