OTB  9.0.0
Orfeo Toolbox
otbFastICAInternalOptimizerVectorImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 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 otbFastICAInternalOptimizerVectorImageFilter_hxx
22 #define otbFastICAInternalOptimizerVectorImageFilter_hxx
24 
25 #include <itkMacro.h>
26 #include <itkImageRegionIterator.h>
27 
28 #include <vnl/vnl_math.h>
29 #include <vnl/vnl_matrix.h>
30 
31 namespace otb
32 {
33 
34 template <class TInputImage, class TOutputImage>
36 {
37  this->SetNumberOfRequiredInputs(2);
38 
39  m_CurrentBandForLoop = 0;
40  m_Beta = 0.;
41  m_Den = 0.;
42 
43  m_NonLinearity = [](double x) { return std::tanh(x); };
44  m_NonLinearityDerivative = [](double x) { return 1 - std::pow(std::tanh(x), 2.); };
45 
46  m_TransformFilter = TransformFilterType::New();
47 }
48 
49 template <class TInputImage, class TOutputImage>
51 {
52  Superclass::GenerateOutputInformation();
53 
54  this->GetOutput()->SetNumberOfComponentsPerPixel(this->GetInput(0)->GetNumberOfComponentsPerPixel());
55 }
56 
57 template <class TInputImage, class TOutputImage>
59 {
60  if (m_W.empty())
61  {
62  throw itk::ExceptionObject(__FILE__, __LINE__, "Give the initial W matrix", ITK_LOCATION);
63  }
64 
65  m_BetaVector.resize(this->GetNumberOfThreads());
66  m_DenVector.resize(this->GetNumberOfThreads());
67  m_NbSamples.resize(this->GetNumberOfThreads());
68 
69  std::fill(m_BetaVector.begin(), m_BetaVector.end(), 0.);
70  std::fill(m_DenVector.begin(), m_DenVector.end(), 0.);
71  std::fill(m_NbSamples.begin(), m_NbSamples.end(), 0.);
72 }
73 
74 template <class TInputImage, class TOutputImage>
76  itk::ThreadIdType threadId)
77 {
78  InputRegionType inputRegion;
79  this->CallCopyOutputRegionToInputRegion(inputRegion, outputRegionForThread);
80 
81  itk::ImageRegionConstIterator<InputImageType> input0It(this->GetInput(0), inputRegion);
82  itk::ImageRegionConstIterator<InputImageType> input1It(this->GetInput(1), inputRegion);
83  itk::ImageRegionIterator<OutputImageType> outputIt(this->GetOutput(), outputRegionForThread);
84 
85  unsigned int nbBands = this->GetInput(0)->GetNumberOfComponentsPerPixel();
86  input0It.GoToBegin();
87  input1It.GoToBegin();
88  outputIt.GoToBegin();
89 
90  double beta = 0.;
91  double den = 0.;
92  double nbSample = 0.;
93 
94  while (!input0It.IsAtEnd() && !input1It.IsAtEnd() && !outputIt.IsAtEnd())
95  {
96  double x = static_cast<double>(input1It.Get()[GetCurrentBandForLoop()]);
97  double g_x = m_NonLinearity(x);
98 
99  double x_g_x = x * g_x;
100  beta += x_g_x;
101 
102  double gp = m_NonLinearityDerivative(x);
103  den += gp;
104 
105  nbSample += 1.;
106 
107  typename OutputImageType::PixelType z(nbBands);
108  for (unsigned int bd = 0; bd < nbBands; bd++)
109  z[bd] = g_x * input0It.Get()[bd];
110  outputIt.Set(z);
111 
112  ++input0It;
113  ++input1It;
114  ++outputIt;
115  } // end while loop
116 
117  m_BetaVector[threadId] += beta;
118  m_DenVector[threadId] += den;
119  m_NbSamples[threadId] += nbSample;
120 }
121 
122 template <class TInputImage, class TOutputImage>
124 {
125  double beta = 0;
126  double den = 0.;
127  double nbSample = 0;
128 
129  for (itk::ThreadIdType i = 0; i < this->GetNumberOfThreads(); ++i)
130  {
131  beta += m_BetaVector[i];
132  den += m_DenVector[i];
133  nbSample += m_NbSamples[i];
134  }
135 
136  m_Beta = beta / nbSample;
137  m_Den = den / nbSample - m_Beta;
138 }
139 
140 } // end of namespace otb
141 
142 #endif
otb::FastICAInternalOptimizerVectorImageFilter::InputRegionType
InputImageType::RegionType InputRegionType
Definition: otbFastICAInternalOptimizerVectorImageFilter.h:68
otb::FastICAInternalOptimizerVectorImageFilter::Reset
virtual void Reset() override
Definition: otbFastICAInternalOptimizerVectorImageFilter.hxx:58
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otbFastICAInternalOptimizerVectorImageFilter.h
otb::FastICAInternalOptimizerVectorImageFilter::Synthetize
virtual void Synthetize() override
Definition: otbFastICAInternalOptimizerVectorImageFilter.hxx:123
otb::FastICAInternalOptimizerVectorImageFilter::GenerateOutputInformation
void GenerateOutputInformation() override
Definition: otbFastICAInternalOptimizerVectorImageFilter.hxx:50
otb::FastICAInternalOptimizerVectorImageFilter::ThreadedGenerateData
void ThreadedGenerateData(const OutputRegionType &, itk::ThreadIdType) override
Definition: otbFastICAInternalOptimizerVectorImageFilter.hxx:75
otb::FastICAInternalOptimizerVectorImageFilter::FastICAInternalOptimizerVectorImageFilter
FastICAInternalOptimizerVectorImageFilter()
Definition: otbFastICAInternalOptimizerVectorImageFilter.hxx:35
otb::FastICAInternalOptimizerVectorImageFilter::OutputRegionType
OutputImageType::RegionType OutputRegionType
Definition: otbFastICAInternalOptimizerVectorImageFilter.h:71