OTB  9.0.0
Orfeo Toolbox
otbMaximumAutocorrelationFactorImageFilter.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 otbMaximumAutocorrelationFactorImageFilter_hxx
22 #define otbMaximumAutocorrelationFactorImageFilter_hxx
23 
26 #include "otbMath.h"
27 #include "itkSubtractImageFilter.h"
28 
29 #include "vnl/algo/vnl_matrix_inverse.h"
30 #include "vnl/algo/vnl_generalized_eigensystem.h"
31 
32 #include "itkChangeInformationImageFilter.h"
33 #include "itkImageRegionIterator.h"
34 #include "itkProgressReporter.h"
35 
36 namespace otb
37 {
38 template <class TInputImage, class TOutputImage>
40 {
41  m_CovarianceEstimator = CovarianceEstimatorType::New();
42  m_CovarianceEstimatorH = CovarianceEstimatorType::New();
43  m_CovarianceEstimatorV = CovarianceEstimatorType::New();
44 }
45 
46 template <class TInputImage, class TOutputImage>
48 {
49  // Call superclass implementation
50  Superclass::GenerateOutputInformation();
51 
52  // Retrieve input images pointers
53  TInputImage* inputPtr = const_cast<TInputImage*>(this->GetInput());
54  // TOutputImage * outputPtr = this->GetOutput();
55 
56  // TODO: set the number of output components
57  unsigned int nbComp = inputPtr->GetNumberOfComponentsPerPixel();
58 
59  // Compute Dh and Dv
61  typedef itk::SubtractImageFilter<InternalImageType, InternalImageType, InternalImageType> DifferenceFilterType;
62  typedef itk::ChangeInformationImageFilter<InternalImageType> ChangeInformationImageFilter;
63 
64  InputImageRegionType largestInputRegion = inputPtr->GetLargestPossibleRegion();
65  InputImageRegionType referenceRegion;
66  InputImageSizeType size = largestInputRegion.GetSize();
67  size[0] -= 1;
68  size[1] -= 1;
69  referenceRegion.SetSize(size);
70  InputImageIndexType index = largestInputRegion.GetIndex();
71  referenceRegion.SetIndex(index);
72 
73  InputImageRegionType dhRegion;
74  InputImageRegionType dvRegion;
75 
76  index[0] += 1;
77 
78  dhRegion.SetSize(size);
79  dhRegion.SetIndex(index);
80 
81  index[0] -= 1;
82  index[1] += 1;
83 
84  dvRegion.SetSize(size);
85  dvRegion.SetIndex(index);
86 
87  typename ExtractFilterType::Pointer referenceExtract = ExtractFilterType::New();
88  referenceExtract->SetInput(inputPtr);
89  referenceExtract->SetExtractionRegion(referenceRegion);
90 
91  typename ExtractFilterType::Pointer dhExtract = ExtractFilterType::New();
92  dhExtract->SetInput(inputPtr);
93  dhExtract->SetExtractionRegion(dhRegion);
94 
95  typename ChangeInformationImageFilter::Pointer dhExtractShift = ChangeInformationImageFilter::New();
96  dhExtractShift->SetInput(dhExtract->GetOutput());
97  dhExtractShift->SetReferenceImage(referenceExtract->GetOutput());
98  dhExtractShift->SetUseReferenceImage(true);
99  dhExtractShift->SetChangeOrigin(true);
100 
101  typename ExtractFilterType::Pointer dvExtract = ExtractFilterType::New();
102  dvExtract->SetInput(inputPtr);
103  dvExtract->SetExtractionRegion(dvRegion);
104 
105  typename ChangeInformationImageFilter::Pointer dvExtractShift = ChangeInformationImageFilter::New();
106  dvExtractShift->SetInput(dvExtract->GetOutput());
107  dvExtractShift->SetReferenceImage(referenceExtract->GetOutput());
108  dvExtractShift->SetUseReferenceImage(true);
109  dvExtractShift->SetChangeOrigin(true);
110 
111 
112  typename DifferenceFilterType::Pointer diffh = DifferenceFilterType::New();
113  diffh->SetInput1(referenceExtract->GetOutput());
114  diffh->SetInput2(dhExtractShift->GetOutput());
115 
116  typename DifferenceFilterType::Pointer diffv = DifferenceFilterType::New();
117  diffv->SetInput1(referenceExtract->GetOutput());
118  diffv->SetInput2(dvExtractShift->GetOutput());
119 
120  // Compute pooled sigma (using sigmadh and sigmadv)
121  m_CovarianceEstimatorH->SetInput(diffh->GetOutput());
122  m_CovarianceEstimatorH->Update();
123  VnlMatrixType sigmadh = m_CovarianceEstimatorH->GetCovariance().GetVnlMatrix();
124 
125  m_CovarianceEstimatorV->SetInput(diffv->GetOutput());
126  m_CovarianceEstimatorV->Update();
127  VnlMatrixType sigmadv = m_CovarianceEstimatorV->GetCovariance().GetVnlMatrix();
128 
129  // Simple pool
130  VnlMatrixType sigmad = 0.5 * (sigmadh + sigmadv);
131 
132  // Compute the original image covariance
133  referenceExtract->SetExtractionRegion(inputPtr->GetLargestPossibleRegion());
134  m_CovarianceEstimator->SetInput(referenceExtract->GetOutput());
135  m_CovarianceEstimator->Update();
136  VnlMatrixType sigma = m_CovarianceEstimator->GetCovariance().GetVnlMatrix();
137 
138  m_Mean = VnlVectorType(nbComp, 0);
139 
140  for (unsigned int i = 0; i < nbComp; ++i)
141  {
142  m_Mean[i] = m_CovarianceEstimator->GetMean()[i];
143  }
144 
145  vnl_generalized_eigensystem ges(sigmad, sigma);
146  VnlMatrixType d = ges.D;
147  m_V = ges.V;
148 
149  m_AutoCorrelation = VnlVectorType(nbComp, 1.);
150  m_AutoCorrelation -= 0.5 * d.get_diagonal();
151 
152  VnlMatrixType invstderr = VnlMatrixType(nbComp, nbComp, 0);
153  invstderr.set_diagonal(sigma.get_diagonal());
154  invstderr = invstderr.apply(&std::sqrt);
155  invstderr = invstderr.apply(&InverseValue);
156 
157  VnlMatrixType invstderrmaf = VnlMatrixType(nbComp, nbComp, 0);
158  invstderrmaf.set_diagonal((m_V.transpose() * sigma * m_V).get_diagonal());
159  invstderrmaf = invstderrmaf.apply(&std::sqrt);
160  invstderrmaf = invstderrmaf.apply(&InverseValue);
161 
162  VnlMatrixType aux1 = invstderr * sigma * m_V * invstderrmaf;
163 
164  VnlMatrixType sign = VnlMatrixType(nbComp, nbComp, 0);
165 
166  VnlVectorType aux2 = VnlVectorType(nbComp, 0);
167 
168  for (unsigned int i = 0; i < nbComp; ++i)
169  {
170  aux2 = aux2 + aux1.get_row(i);
171  }
172 
173  sign.set_diagonal(aux2);
174  sign = sign.apply(&SignOfValue);
175 
176  // There is no need for scaling since vnl_generalized_eigensystem
177  // already gives unit variance
178  m_V = m_V * sign;
179 }
180 
181 template <class TInputImage, class TOutputImage>
183  itk::ThreadIdType threadId)
184 {
185  // Retrieve input images pointers
186  const TInputImage* inputPtr = this->GetInput();
187  TOutputImage* outputPtr = this->GetOutput();
188 
189 
190  typedef itk::ImageRegionConstIterator<InputImageType> ConstIteratorType;
191  typedef itk::ImageRegionIterator<OutputImageType> IteratorType;
192 
193  IteratorType outIt(outputPtr, outputRegionForThread);
194  ConstIteratorType inIt(inputPtr, outputRegionForThread);
195 
196  inIt.GoToBegin();
197  outIt.GoToBegin();
198 
199  // Get the number of components for each image
200  unsigned int outNbComp = outputPtr->GetNumberOfComponentsPerPixel();
201 
202 
203  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
204 
205  while (!inIt.IsAtEnd() && !outIt.IsAtEnd())
206  {
207  VnlVectorType x(outNbComp, 0);
208  VnlVectorType maf(outNbComp, 0);
209 
210  for (unsigned int i = 0; i < outNbComp; ++i)
211  {
212  x[i] = inIt.Get()[i];
213  }
214 
215  maf = (x - m_Mean) * m_V;
216 
217  typename OutputImageType::PixelType outPixel(outNbComp);
218 
219  for (unsigned int i = 0; i < outNbComp; ++i)
220  {
221  outPixel[i] = maf[i];
222  }
223 
224  outIt.Set(outPixel);
225 
226  ++inIt;
227  ++outIt;
228  progress.CompletedPixel();
229  }
230 }
231 }
232 
233 #endif
otbMaximumAutocorrelationFactorImageFilter.h
otb::MaximumAutocorrelationFactorImageFilter::VnlVectorType
vnl_vector< RealType > VnlVectorType
Definition: otbMaximumAutocorrelationFactorImageFilter.h:112
otb::MaximumAutocorrelationFactorImageFilter::InputImageIndexType
InputImageRegionType::IndexType InputImageIndexType
Definition: otbMaximumAutocorrelationFactorImageFilter.h:90
otb::MaximumAutocorrelationFactorImageFilter::InputImageSizeType
InputImageRegionType::SizeType InputImageSizeType
Definition: otbMaximumAutocorrelationFactorImageFilter.h:89
otbMultiChannelExtractROI.h
otb::MaximumAutocorrelationFactorImageFilter::OutputImageRegionType
OutputImageType::RegionType OutputImageRegionType
Definition: otbMaximumAutocorrelationFactorImageFilter.h:95
otbMath.h
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::InverseValue
T InverseValue(const T &value)
Definition: otbMath.h:96
otb::MaximumAutocorrelationFactorImageFilter::GenerateOutputInformation
void GenerateOutputInformation() override
Definition: otbMaximumAutocorrelationFactorImageFilter.hxx:47
otb::MaximumAutocorrelationFactorImageFilter::VnlMatrixType
vnl_matrix< RealType > VnlMatrixType
Definition: otbMaximumAutocorrelationFactorImageFilter.h:113
otb::MultiChannelExtractROI
Extract a spatial or spectral subset of a multi-channel image.
Definition: otbMultiChannelExtractROI.h:47
otb::MaximumAutocorrelationFactorImageFilter::InputImageRegionType
InputImageType::RegionType InputImageRegionType
Definition: otbMaximumAutocorrelationFactorImageFilter.h:88
otb::MaximumAutocorrelationFactorImageFilter::ThreadedGenerateData
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId) override
Definition: otbMaximumAutocorrelationFactorImageFilter.hxx:182
otb::MaximumAutocorrelationFactorImageFilter::MaximumAutocorrelationFactorImageFilter
MaximumAutocorrelationFactorImageFilter()
Definition: otbMaximumAutocorrelationFactorImageFilter.hxx:39
otb::SignOfValue
T SignOfValue(const T &value)
Definition: otbMath.h:102