21 #ifndef otbApplyGainFilter_hxx
22 #define otbApplyGainFilter_hxx
25 #include "itkImageRegionIterator.h"
26 #include "itkImageRegionConstIteratorWithIndex.h"
27 #include "itkContinuousIndex.h"
33 template <
class TInputImage,
class TLut,
class TOutputImage>
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();
41 m_ThumbSizeFromSpacing =
true;
43 this->DynamicMultiThreadingOn();
46 template <
class TInputImage,
class TLut,
class TOutputImage>
53 template <
class TInputImage,
class TLut,
class TOutputImage>
56 return static_cast<const InputImageType*
>(this->itk::ProcessObject::GetInput(0));
59 template <
class TInputImage,
class TLut,
class TOutputImage>
63 this->SetNthInput(1,
const_cast<LutType*
>(lut));
66 template <
class TInputImage,
class TLut,
class TOutputImage>
69 return static_cast<const LutType*
>(this->itk::ProcessObject::GetInput(1));
72 template <
class TInputImage,
class TLut,
class TOutputImage>
75 typename InputImageType::Pointer input(
const_cast<InputImageType*
>(GetInputImage()));
76 typename LutType::Pointer lut(
const_cast<LutType*
>(GetInputLut()));
77 typename OutputImageType::Pointer output(this->GetOutput());
79 lut->SetRequestedRegion(lut->GetLargestPossibleRegion());
80 input->SetRequestedRegion(output->GetRequestedRegion());
81 if (input->GetRequestedRegion().GetNumberOfPixels() == 0)
83 input->SetRequestedRegionToLargestPossibleRegion();
87 template <
class TInputImage,
class TLut,
class TOutputImage>
90 typename LutType::ConstPointer lut(GetInputLut());
91 typename InputImageType::ConstPointer input(GetInputImage());
92 if (m_ThumbSizeFromSpacing)
94 m_ThumbSize[0] = std::round(lut->GetSignedSpacing()[0] / input->GetSignedSpacing()[0]);
95 m_ThumbSize[1] = std::round(lut->GetSignedSpacing()[1] / input->GetSignedSpacing()[1]);
97 m_Step =
static_cast<double>(m_Max - m_Min) /
static_cast<double>(lut->GetVectorLength() - 1);
100 template <
class TInputImage,
class TLut,
class TOutputImage>
105 typename InputImageType::ConstPointer input(GetInputImage());
106 typename LutType::ConstPointer lut(GetInputLut());
107 typename OutputImageType::Pointer output(this->GetOutput());
108 typename InputImageType::RegionType inputRegionForThread(outputRegionForThread);
111 itk::ImageRegionConstIteratorWithIndex<InputImageType> it(input, inputRegionForThread);
112 itk::ImageRegionIterator<OutputImageType> oit(output, outputRegionForThread);
114 unsigned int pixelLutValue(0);
115 double gain(0.0), newValue(0);
118 for (it.GoToBegin(), oit.GoToBegin(); !oit.IsAtEnd() || !it.IsAtEnd(); ++oit, ++it)
120 currentPixel = it.Get();
121 newValue =
static_cast<double>(currentPixel);
122 if (!((currentPixel == m_NoData && m_NoDataFlag) || currentPixel > m_Max || currentPixel < m_Min))
124 pixelLutValue =
static_cast<unsigned int>(std::round((currentPixel - m_Min) / m_Step));
125 gain = InterpolateGain(lut, pixelLutValue, it.GetIndex());
130 assert(oit.IsAtEnd() && it.IsAtEnd());
133 template <
class TInputImage,
class TLut,
class TOutputImage>
135 typename InputImageType::IndexType index)
137 typename InputImageType::PointType pixelPoint;
138 typename itk::ContinuousIndex<double, 2> pixelIndex;
139 typename InputImageType::ConstPointer input(GetInputImage());
140 typename LutType::ConstPointer lut(GetInputLut());
141 input->TransformIndexToPhysicalPoint(index, pixelPoint);
142 lut->TransformPhysicalPointToContinuousIndex(pixelPoint, pixelIndex);
143 std::vector<typename LutType::IndexType> neighbors(4);
144 neighbors[0][0] = std::floor(pixelIndex[0]);
145 neighbors[0][1] = std::floor(pixelIndex[1]);
146 neighbors[1][0] = neighbors[0][0] + 1;
147 neighbors[1][1] = neighbors[0][1];
148 neighbors[2][0] = neighbors[0][0];
149 neighbors[2][1] = neighbors[0][1] + 1;
150 neighbors[3][0] = neighbors[0][0] + 1;
151 neighbors[3][1] = neighbors[0][1] + 1;
152 float gain(0.f), w(0.f), wtm(0.f);
153 typename LutType::IndexType maxIndex;
154 maxIndex[0] = lut->GetLargestPossibleRegion().GetSize()[0];
155 maxIndex[1] = lut->GetLargestPossibleRegion().GetSize()[1];
156 for (
auto i : neighbors)
158 if (i[0] < 0 || i[1] < 0 || i[0] >= maxIndex[0] || i[1] >= maxIndex[1])
160 if (gridLut->GetPixel(i)[pixelLutValue] == -1)
162 wtm = (1 - std::abs(pixelIndex[0] - i[0])) * (1 - std::abs(pixelIndex[1] - i[1]));
163 gain += gridLut->GetPixel(i)[pixelLutValue] * wtm;
178 template <
class TInputImage,
class TLut,
class TOutputImage>
181 Superclass::PrintSelf(os, indent);
182 os << indent <<
"Is no data activated : " << m_NoDataFlag << std::endl;
183 os << indent <<
"No Data : " << m_NoData << std::endl;
184 os << indent <<
"Minimum : " << m_Min << std::endl;
185 os << indent <<
"Maximum : " << m_Max << std::endl;
186 os << indent <<
"Step : " << m_Step << std::endl;
187 os << indent <<
"Look up table size : " << m_LutSize << std::endl;
188 os << indent <<
"Is ThumbSize from sapcing is activated : " << m_NoDataFlag << std::endl;
189 os << indent <<
"Thumbnail size : " << m_ThumbSize << std::endl;
const LutType * GetInputLut() const
void GenerateInputRequestedRegion() override
const InputImageType * GetInputImage() const
void SetInputLut(const LutType *lut)
double InterpolateGain(typename LutType::ConstPointer gridLut, unsigned int pixelValue, typename InputImageType::IndexType index)
InputImageType::InternalPixelType InputPixelType
OutputImageType::RegionType OutputImageRegionType
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) override
void SetInputImage(const InputImageType *input)
void BeforeThreadedGenerateData() override
void PrintSelf(std::ostream &os, itk::Indent indent) const override
TInputImage InputImageType
OutputImageType::InternalPixelType OutputPixelType
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.