ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkAdaptiveEqualizationHistogram.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkAdaptiveEqualizationHistogram_h
19#define itkAdaptiveEqualizationHistogram_h
20
21#include <unordered_map>
23#include "itkMath.h"
24#include <cmath>
25
26namespace itk::Function
27{
28
29/* \class AdaptiveEqualizationHistogram
30 *
31 * Implements the function class for a moving histogram algorithm for
32 * adaptive histogram equalization.
33 *
34 * \sa AdaptiveHistogramEqualizationImageFilter
35 * \sa MovingHistogramImageFilter
36 * \ingroup ITKImageStatistics
37 */
38template <class TInputPixel, class TOutputPixel>
40{
41public:
42 using RealType = float;
43
45
46 // ~AdaptiveEqualizationHistogram() {} default is ok
47
48 void
49 AddPixel(const TInputPixel & p)
50 {
51 m_Map[p]++;
52 }
53
54 void
55 RemovePixel(const TInputPixel & p)
56 {
57
58 // insert new item if one doesn't exist
59 auto it = m_Map.find(p);
60
61 itkAssertInDebugAndIgnoreInReleaseMacro(it != m_Map.end());
62
63 if (--(it->second) == 0)
64 {
65 m_Map.erase(it);
66 }
67 }
68
69 TOutputPixel
70 GetValue(const TInputPixel & pixel)
71 {
72
73 // Normalize input pixels to [-0.5 0.5] gray level.
74 // AdaptiveHistogramEqualization compute kernel components with
75 // float, but use double for accumulate and temporaries.
76 const double iscale = static_cast<double>(m_Maximum) - m_Minimum;
77 if (iscale == 0.0)
78 {
79 // Constant image: equalization is an identity mapping.
80 return static_cast<TOutputPixel>(pixel);
81 }
82
83 double sum = 0.0;
84 auto itMap = m_Map.begin();
85 const RealType u = (static_cast<double>(pixel) - m_Minimum) / iscale - 0.5;
86 while (itMap != m_Map.end())
87 {
88 const RealType v = (static_cast<double>(itMap->first) - m_Minimum) / iscale - 0.5;
89 const double ikernel = m_KernelSize - m_BoundaryCount;
90 sum += itMap->second * CumulativeFunction(u, v) / ikernel;
91
92 ++itMap;
93 }
94
95 return (TOutputPixel)(iscale * (sum + 0.5) + m_Minimum);
96 }
97
98 void
100 {
102 }
103
104 void
106 {
108 }
109
110 void
112 {
113 m_Alpha = alpha;
114 }
115 void
117 {
118 m_Beta = beta;
119 }
120 void
122 {
123 m_KernelSize = kernelSize;
124 }
125
126 void
127 SetMinimum(TInputPixel minimum)
128 {
129 m_Minimum = minimum;
130 }
131 void
132 SetMaximum(TInputPixel maximum)
133 {
134 m_Maximum = maximum;
135 }
136
137private:
141
142 TInputPixel m_Minimum;
143 TInputPixel m_Maximum;
144
147 {
148 // Calculate cumulative function
149 const RealType s = itk::Math::sgn(u - v);
150 const RealType ad = itk::Math::Absolute(2.0 * (u - v));
151
152 return 0.5 * s * std::pow(ad, m_Alpha) - m_Beta * 0.5 * s * ad + m_Beta * u;
153 }
154
155private:
156 using MapType = std::unordered_map<TInputPixel, size_t, StructHashFunction<TInputPixel>>;
157
158
160 size_t m_BoundaryCount{ 0 };
161};
162
163} // namespace itk::Function
164
165#endif // itkAdaptiveHistogramHistogram_h
std::unordered_map< TInputPixel, vcl_size_t, StructHashFunction< TInputPixel > > MapType
constexpr auto Absolute(T x) noexcept
Returns the absolute value of a number.
Definition itkMath.h:1134
constexpr int sgn(T x)
Sign of a value: -1, 0, or +1.
Definition itkMath.h:872