OTB  9.0.0
Orfeo Toolbox
otbApplyGainFilter.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 otbApplyGainFilter_hxx
22 #define otbApplyGainFilter_hxx
23 
24 #include "otbApplyGainFilter.h"
25 #include "itkImageRegionIterator.h"
26 #include "itkImageRegionConstIteratorWithIndex.h"
27 #include "itkContinuousIndex.h"
28 
29 #include <limits>
30 
31 namespace otb
32 {
33 template <class TInputImage, class TLut, class TOutputImage>
35 {
36  this->SetNumberOfRequiredInputs(2);
37  m_Min = std::numeric_limits<InputPixelType>::quiet_NaN();
38  m_Max = std::numeric_limits<InputPixelType>::quiet_NaN();
39  m_NoData = std::numeric_limits<InputPixelType>::quiet_NaN();
40  m_NoDataFlag = false;
41  m_ThumbSizeFromSpacing = true;
42  m_Step = -1;
43 }
44 
45 template <class TInputImage, class TLut, class TOutputImage>
47 {
48  // Process object is not const-correct so the const casting is required.
49  this->SetNthInput(0, const_cast<InputImageType*>(input));
50 }
51 
52 template <class TInputImage, class TLut, class TOutputImage>
54 {
55  return static_cast<const InputImageType*>(this->itk::ProcessObject::GetInput(0));
56 }
57 
58 template <class TInputImage, class TLut, class TOutputImage>
60 {
61  // Process object is not const-correct so the const casting is required.
62  this->SetNthInput(1, const_cast<LutType*>(lut));
63 }
64 
65 template <class TInputImage, class TLut, class TOutputImage>
67 {
68  return static_cast<const LutType*>(this->itk::ProcessObject::GetInput(1));
69 }
70 
71 template <class TInputImage, class TLut, class TOutputImage>
73 {
74  typename InputImageType::Pointer input(const_cast<InputImageType*>(GetInputImage()));
75  typename LutType::Pointer lut(const_cast<LutType*>(GetInputLut()));
76  typename OutputImageType::Pointer output(this->GetOutput());
77 
78  lut->SetRequestedRegion(lut->GetLargestPossibleRegion());
79  input->SetRequestedRegion(output->GetRequestedRegion());
80  if (input->GetRequestedRegion().GetNumberOfPixels() == 0)
81  {
82  input->SetRequestedRegionToLargestPossibleRegion();
83  }
84 }
85 
86 template <class TInputImage, class TLut, class TOutputImage>
88 {
89  typename LutType::ConstPointer lut(GetInputLut());
90  typename InputImageType::ConstPointer input(GetInputImage());
91  if (m_ThumbSizeFromSpacing)
92  {
93  m_ThumbSize[0] = std::round(lut->GetSignedSpacing()[0] / input->GetSignedSpacing()[0]);
94  m_ThumbSize[1] = std::round(lut->GetSignedSpacing()[1] / input->GetSignedSpacing()[1]);
95  }
96  m_Step = static_cast<double>(m_Max - m_Min) / static_cast<double>(lut->GetVectorLength() - 1);
97 }
98 
99 template <class TInputImage, class TLut, class TOutputImage>
101  itk::ThreadIdType itkNotUsed(threadId))
102 {
103  assert(m_Step > 0);
104  // TODO error
105  // support progress methods/callbacks
106  // itk::ProgressReporter progress(this , threadId ,
107  // outputRegionForThread.GetNumberOfPixels() );
108 
109  typename InputImageType::ConstPointer input(GetInputImage());
110  typename LutType::ConstPointer lut(GetInputLut());
111  typename OutputImageType::Pointer output(this->GetOutput());
112  typename InputImageType::RegionType inputRegionForThread(outputRegionForThread);
113 
114 
115  itk::ImageRegionConstIteratorWithIndex<InputImageType> it(input, inputRegionForThread);
116  itk::ImageRegionIterator<OutputImageType> oit(output, outputRegionForThread);
117 
118  unsigned int pixelLutValue(0);
119  double gain(0.0), newValue(0);
120  InputPixelType currentPixel(0);
121 
122  for (it.GoToBegin(), oit.GoToBegin(); !oit.IsAtEnd() || !it.IsAtEnd(); ++oit, ++it)
123  {
124  currentPixel = it.Get();
125  newValue = static_cast<double>(currentPixel);
126  if (!((currentPixel == m_NoData && m_NoDataFlag) || currentPixel > m_Max || currentPixel < m_Min))
127  {
128  pixelLutValue = static_cast<unsigned int>(std::round((currentPixel - m_Min) / m_Step));
129  gain = InterpolateGain(lut, pixelLutValue, it.GetIndex());
130  newValue *= gain;
131  }
132  oit.Set(static_cast<OutputPixelType>(newValue));
133  }
134  assert(oit.IsAtEnd() && it.IsAtEnd());
135 }
136 
137 template <class TInputImage, class TLut, class TOutputImage>
138 double ApplyGainFilter<TInputImage, TLut, TOutputImage>::InterpolateGain(typename LutType::ConstPointer gridLut, unsigned int pixelLutValue,
139  typename InputImageType::IndexType index)
140 {
141  typename InputImageType::PointType pixelPoint;
142  typename itk::ContinuousIndex<double, 2> pixelIndex;
143  typename InputImageType::ConstPointer input(GetInputImage());
144  typename LutType::ConstPointer lut(GetInputLut());
145  input->TransformIndexToPhysicalPoint(index, pixelPoint);
146  lut->TransformPhysicalPointToContinuousIndex(pixelPoint, pixelIndex);
147  std::vector<typename LutType::IndexType> neighbors(4);
148  neighbors[0][0] = std::floor(pixelIndex[0]);
149  neighbors[0][1] = std::floor(pixelIndex[1]);
150  neighbors[1][0] = neighbors[0][0] + 1;
151  neighbors[1][1] = neighbors[0][1];
152  neighbors[2][0] = neighbors[0][0];
153  neighbors[2][1] = neighbors[0][1] + 1;
154  neighbors[3][0] = neighbors[0][0] + 1;
155  neighbors[3][1] = neighbors[0][1] + 1;
156  float gain(0.f), w(0.f), wtm(0.f);
157  typename LutType::IndexType maxIndex;
158  maxIndex[0] = lut->GetLargestPossibleRegion().GetSize()[0];
159  maxIndex[1] = lut->GetLargestPossibleRegion().GetSize()[1];
160  for (auto i : neighbors)
161  {
162  if (i[0] < 0 || i[1] < 0 || i[0] >= maxIndex[0] || i[1] >= maxIndex[1])
163  continue;
164  if (gridLut->GetPixel(i)[pixelLutValue] == -1)
165  continue;
166  wtm = (1 - std::abs(pixelIndex[0] - i[0])) * (1 - std::abs(pixelIndex[1] - i[1]));
167  gain += gridLut->GetPixel(i)[pixelLutValue] * wtm;
168  w += wtm;
169  }
170  if (w == 0)
171  {
172  w = 1;
173  gain = 1;
174  }
175 
176  return gain / w;
177 }
178 
182 template <class TInputImage, class TLut, class TOutputImage>
183 void ApplyGainFilter<TInputImage, TLut, TOutputImage>::PrintSelf(std::ostream& os, itk::Indent indent) const
184 {
185  Superclass::PrintSelf(os, indent);
186  os << indent << "Is no data activated : " << m_NoDataFlag << std::endl;
187  os << indent << "No Data : " << m_NoData << std::endl;
188  os << indent << "Minimum : " << m_Min << std::endl;
189  os << indent << "Maximum : " << m_Max << std::endl;
190  os << indent << "Step : " << m_Step << std::endl;
191  os << indent << "Look up table size : " << m_LutSize << std::endl;
192  os << indent << "Is ThumbSize from sapcing is activated : " << m_NoDataFlag << std::endl;
193  os << indent << "Thumbnail size : " << m_ThumbSize << std::endl;
194 }
196 
197 
198 } // End namespace otb
199 
200 #endif
otb::ApplyGainFilter::LutType
TLut LutType
Definition: otbApplyGainFilter.h:55
otb::ApplyGainFilter::InterpolateGain
double InterpolateGain(typename LutType::ConstPointer gridLut, unsigned int pixelValue, typename InputImageType::IndexType index)
Definition: otbApplyGainFilter.hxx:138
otb::ApplyGainFilter::OutputPixelType
OutputImageType::InternalPixelType OutputPixelType
Definition: otbApplyGainFilter.h:57
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::ApplyGainFilter::BeforeThreadedGenerateData
void BeforeThreadedGenerateData() override
Definition: otbApplyGainFilter.hxx:87
otb::ApplyGainFilter::InputPixelType
InputImageType::InternalPixelType InputPixelType
Definition: otbApplyGainFilter.h:56
otb::ApplyGainFilter::InputImageType
TInputImage InputImageType
Definition: otbApplyGainFilter.h:47
otb::ApplyGainFilter::OutputImageRegionType
OutputImageType::RegionType OutputImageRegionType
Definition: otbApplyGainFilter.h:58
otbApplyGainFilter.h
otb::ApplyGainFilter::GetInputImage
const InputImageType * GetInputImage() const
Definition: otbApplyGainFilter.hxx:53
otb::ApplyGainFilter::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbApplyGainFilter.hxx:183
otb::ApplyGainFilter::ApplyGainFilter
ApplyGainFilter()
Definition: otbApplyGainFilter.hxx:34
otb::ApplyGainFilter::GetInputLut
const LutType * GetInputLut() const
Definition: otbApplyGainFilter.hxx:66
otb::ApplyGainFilter::SetInputLut
void SetInputLut(const LutType *lut)
Definition: otbApplyGainFilter.hxx:59
otb::ApplyGainFilter::ThreadedGenerateData
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId) override
Definition: otbApplyGainFilter.hxx:100
otb::ApplyGainFilter::GenerateInputRequestedRegion
void GenerateInputRequestedRegion() override
Definition: otbApplyGainFilter.hxx:72
otb::ApplyGainFilter::SetInputImage
void SetInputImage(const InputImageType *input)
Definition: otbApplyGainFilter.hxx:46