21 #ifndef otbComputeGainLutFilter_hxx
22 #define otbComputeGainLutFilter_hxx
25 #include "itkImageRegionIterator.h"
33 template <
class TInputImage,
class TOutputImage>
38 m_Min = std::numeric_limits<double>::quiet_NaN();
39 m_Max = std::numeric_limits<double>::quiet_NaN();
41 this->DynamicMultiThreadingOn();
44 template <
class TInputImage,
class TOutputImage>
47 m_NbBin = this->GetInput()->GetNumberOfComponentsPerPixel();
48 m_Step =
static_cast<double>(m_Max - m_Min) /
static_cast<double>(m_NbBin - 1);
51 template <
class TInputImage,
class TOutputImage>
57 typename InputImageType::ConstPointer input(this->GetInput());
58 typename OutputImageType::Pointer output(this->GetOutput());
60 itk::ImageRegionConstIterator<InputImageType> it(input, outputRegionForThread);
62 itk::ImageRegionIterator<OutputImageType> oit(output, outputRegionForThread);
65 target.SetSize(m_NbBin);
72 for (it.GoToBegin(), oit.GoToBegin(); !oit.IsAtEnd() || !it.IsAtEnd(); ++oit, ++it)
74 currentHisto = it.Get();
77 if (IsValid(currentHisto))
79 CreateTarget(currentHisto, target);
80 Equalized(currentHisto, target, lut);
84 assert(oit.IsAtEnd() && it.IsAtEnd());
87 template <
class TInputImage,
class TOutputImage>
90 double denum(countValue * m_Step + m_Min);
93 return static_cast<OutputPixelType>((countMapValue * m_Step + m_Min) / denum);
96 template <
class TInputImage,
class TOutputImage>
99 unsigned int countValue(0), countMapValue(0);
102 unsigned int countInput(inputHisto[0] + inputHisto[countValue]);
103 lut[m_NbBin - 1] = 1;
104 unsigned int countTarget(targetHisto[countMapValue]);
106 while ((countMapValue < m_NbBin) && countValue < (m_NbBin - 1))
108 if (countInput > countTarget)
111 countTarget += targetHisto[countMapValue];
115 lut[countValue] = PostProcess(countValue, countMapValue);
117 countInput += inputHisto[countValue];
120 for (
unsigned int i = 0; i < m_NbBin; i++)
129 template <
class TInputImage,
class TOutputImage>
132 unsigned int nbPixel(0);
133 for (
unsigned int i = 0; i < m_NbBin; i++)
135 nbPixel += inputHisto[i];
137 unsigned int rest(nbPixel % m_NbBin), height(nbPixel / m_NbBin);
138 targetHisto.Fill(height);
139 for (
unsigned int i = 0; i < rest; i++)
141 ++targetHisto[(m_NbBin - rest) / 2 + i];
145 template <
class TInputImage,
class TOutputImage>
148 long acc = std::accumulate(&inputHisto[0], &inputHisto[m_NbBin - 1], 0);
149 return acc >= (0.5 * m_NbPixel);
155 template <
class TInputImage,
class TOutputImage>
158 Superclass::PrintSelf(os, indent);
159 os << indent <<
"Minimum: " << m_Min << std::endl;
160 os << indent <<
"Maximum: " << m_Max << std::endl;
161 os << indent <<
"Step: " << m_Step << std::endl;
162 os << indent <<
"Number of bin: " << m_NbBin << std::endl;
163 os << indent <<
"Number of pixel by histogram: " << m_NbPixel << std::endl;
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) override
void PrintSelf(std::ostream &os, itk::Indent indent) const override
bool IsValid(const HistoType &inputHisto)
void Equalized(const HistoType &inputHisto, HistoType &targetHisto, LutType &lut)
OutputImageType::RegionType OutputImageRegionType
OutputImageType::PixelType LutType
void CreateTarget(const HistoType &inputHisto, HistoType &targetHisto)
void BeforeThreadedGenerateData() override
InputImageType::PixelType HistoType
OutputPixelType PostProcess(unsigned int countMapValue, unsigned int countValue)
OutputImageType::InternalPixelType OutputPixelType
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.