ITK  5.1.0
Insight Toolkit
itkRankHistogram.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  * http://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 // histogram from the moving histogram operations
19 #ifndef itkRankHistogram_h
20 #define itkRankHistogram_h
21 
22 #include "itkIntTypes.h"
23 #include "itkNumericTraits.h"
24 
25 #include <map>
26 #include <vector>
27 
28 namespace itk
29 {
30 namespace Function
31 {
32 
33 /* \class RankHistogram
34  * \brief A simple histogram class hierarchy. One specialization will
35  * be maps, the other vectors.
36  *
37  * This version is intended for keeping track of arbitrary ranks. It
38  * is based on the code from consolidatedMorphology.
39  *
40  * This is a modified version for use with masks. Need to allow for
41  * the situation in which the map is empty.
42  *
43  * This code was contributed in the Insight Journal paper:
44  * "Efficient implementation of kernel filtering"
45  * by Beare R., Lehmann G
46  * https://hdl.handle.net/1926/555
47  * http://www.insight-journal.org/browse/publication/160
48  *
49  * /sa VectorRankHistogram
50  */
51 template <typename TInputPixel>
53 {
54 public:
55  using Compare = std::less<TInputPixel>;
56 
58  {
59  m_Rank = 0.5;
60  m_Below = m_Entries = 0;
61  // can't set m_RankIt until something has been put in the histogram
62  m_Initialized = false;
64  {
66  }
67  else
68  {
70  }
72  m_RankIt = m_Map.begin(); // equivalent to setting to the initial value
73  }
74 
75  ~RankHistogram() = default;
76 
78  operator=(const RankHistogram & hist)
79  {
80  if (this != &hist)
81  {
82  m_Map = hist.m_Map;
83  m_Rank = hist.m_Rank;
84  m_Below = hist.m_Below;
85  m_Entries = hist.m_Entries;
86  m_InitVal = hist.m_InitVal;
87  m_RankValue = hist.m_RankValue;
89  if (m_Initialized)
90  {
91  m_RankIt = m_Map.find(m_RankValue);
92  }
93  }
94  return *this;
95  }
96 
97  void
98  AddPixel(const TInputPixel & p)
99  {
100  m_Map[p]++;
101  if (!m_Initialized)
102  {
103  m_Initialized = true;
104  m_RankIt = m_Map.begin();
105  m_Entries = m_Below = 0;
106  m_RankValue = p;
107  }
108  if (m_Compare(p, m_RankValue) || p == m_RankValue)
109  {
110  ++m_Below;
111  }
112  ++m_Entries;
113  }
114 
115  void
116  RemovePixel(const TInputPixel & p)
117  {
118  m_Map[p]--;
119  if (m_Compare(p, m_RankValue) || p == m_RankValue)
120  {
121  --m_Below;
122  }
123  --m_Entries;
124  // this is the change that makes this version less efficient. The
125  // simplest approach I can think of with maps, though
126  if (m_Entries <= 0)
127  {
128  m_Initialized = false;
129  m_Below = 0;
130  m_Map.clear();
131  }
132  }
133 
134  bool
136  {
137  return m_Initialized;
138  }
139 
140  TInputPixel
142  {
143  SizeValueType count = 0;
144  SizeValueType target = (int)(m_Rank * (m_Entries - 1)) + 1;
145  for (typename MapType::iterator it = m_Map.begin(); it != m_Map.end(); it++)
146  {
147  count += it->second;
148  if (count >= target)
149  {
150  return it->first;
151  }
152  }
154  }
155 
156  TInputPixel
157  GetValue(const TInputPixel &)
158  {
159  SizeValueType target = (SizeValueType)(m_Rank * (m_Entries - 1)) + 1;
160  SizeValueType total = m_Below;
161  SizeValueType ThisBin;
162  bool eraseFlag = false;
163 
164  if (total < target)
165  {
166  auto searchIt = m_RankIt;
167  typename MapType::iterator eraseIt;
168 
169  while (searchIt != m_Map.end())
170  {
171  // cleaning up the map - probably a better way of organising
172  // the loop. Currently makes sure that the search iterator is
173  // incremented before deleting
174  ++searchIt;
175  ThisBin = searchIt->second;
176  total += ThisBin;
177  if (eraseFlag)
178  {
179  m_Map.erase(eraseIt);
180  eraseFlag = false;
181  }
182  if (ThisBin <= 0)
183  {
184  eraseFlag = true;
185  eraseIt = searchIt;
186  }
187  if (total >= target)
188  {
189  break;
190  }
191  }
192  if (searchIt == m_Map.end())
193  {
194  --searchIt;
195  }
196  m_RankValue = searchIt->first;
197  m_RankIt = searchIt;
198  }
199  else
200  {
201  auto searchIt = m_RankIt;
202  typename MapType::iterator eraseIt;
203 
204  while (searchIt != m_Map.begin())
205  {
206  ThisBin = searchIt->second;
207  unsigned int tbelow = total - ThisBin;
208  if (tbelow < target) // we've overshot
209  {
210  break;
211  }
212  if (eraseFlag)
213  {
214  m_Map.erase(eraseIt);
215  eraseFlag = false;
216  }
217  if (ThisBin <= 0)
218  {
219  eraseIt = searchIt;
220  eraseFlag = true;
221  }
222  total = tbelow;
223 
224  --searchIt;
225  }
226  m_RankValue = searchIt->first;
227  m_RankIt = searchIt;
228  }
229 
230  m_Below = total;
231  itkAssertInDebugAndIgnoreInReleaseMacro(m_RankValue == GetValueBruteForce());
232  return (m_RankValue);
233  }
234 
235  void
236  SetRank(float rank)
237  {
238  m_Rank = rank;
239  }
240 
241  void
243  {}
244 
245  void
247  {}
248 
249  static bool
251  {
252  return false;
253  }
254 
255 protected:
256  float m_Rank;
257 
258 private:
259  using MapType = typename std::map<TInputPixel, SizeValueType, Compare>;
260 
264  TInputPixel m_RankValue;
265  TInputPixel m_InitVal;
268 
269  // This iterator will point at the desired rank value
270  typename MapType::iterator m_RankIt;
271 };
272 
273 
274 template <typename TInputPixel>
276 {
277 public:
278  using Compare = std::less<TInputPixel>;
279 
281  {
284  m_Vec.resize(m_Size, 0);
286  {
288  }
289  else
290  {
292  }
293  m_Entries = m_Below = 0;
295  m_Rank = 0.5;
296  }
297 
298  ~VectorRankHistogram() = default;
299 
300  bool
302  {
303  return m_Entries > 0;
304  }
305 
306  TInputPixel
308  {
309  SizeValueType count = 0;
310  SizeValueType target = (SizeValueType)(m_Rank * (m_Entries - 1)) + 1;
311  for (SizeValueType i = 0; i < m_Size; i++)
312  {
313  count += m_Vec[i];
314  if (count >= target)
315  {
317  }
318  }
320  }
321 
322  TInputPixel
323  GetValue(const TInputPixel &)
324  {
325  return GetValueBruteForce();
326  }
327 
328  void
329  AddPixel(const TInputPixel & p)
330  {
332 
333  m_Vec[q]++;
334  if (m_Compare(p, m_RankValue) || p == m_RankValue)
335  {
336  ++m_Below;
337  }
338  ++m_Entries;
339  }
340 
341  void
342  RemovePixel(const TInputPixel & p)
343  {
345 
346  itkAssertInDebugAndIgnoreInReleaseMacro(q >= 0);
347  itkAssertInDebugAndIgnoreInReleaseMacro(q < (int)m_Vec.size());
348  itkAssertInDebugAndIgnoreInReleaseMacro(m_Entries >= 1);
349  itkAssertInDebugAndIgnoreInReleaseMacro(m_Vec[q] > 0);
350 
351  m_Vec[q]--;
352  --m_Entries;
353 
354  if (m_Compare(p, m_RankValue) || p == m_RankValue)
355  {
356  --m_Below;
357  }
358  }
359 
360  void
361  SetRank(float rank)
362  {
363  m_Rank = rank;
364  }
365 
366  void
368  {}
369 
370  void
372  {}
373 
374  static bool
376  {
377  return true;
378  }
379 
380 protected:
381  float m_Rank;
382 
383 private:
384  using VecType = typename std::vector<SizeValueType>;
385 
389  TInputPixel m_RankValue;
390  TInputPixel m_InitVal;
391  int m_Below;
393 };
394 
395 // now create MorphologicalGradientHistogram specializations using the VectorMorphologicalGradientHistogram
396 // as base class
397 
399 
400 template <>
401 class RankHistogram<unsigned char> : public VectorRankHistogram<unsigned char>
402 {};
403 
404 template <>
405 class RankHistogram<signed char> : public VectorRankHistogram<signed char>
406 {};
407 
408 template <>
409 class RankHistogram<bool> : public VectorRankHistogram<bool>
410 {};
411 
413 
414 } // end namespace Function
415 } // end namespace itk
416 #endif
itk::Function::RankHistogram::m_Below
SizeValueType m_Below
Definition: itkRankHistogram.h:262
itk::Function::VectorRankHistogram
Definition: itkRankHistogram.h:275
itk::Function::RankHistogram::GetValueBruteForce
TInputPixel GetValueBruteForce()
Definition: itkRankHistogram.h:141
itk::Function::VectorRankHistogram::RemovePixel
void RemovePixel(const TInputPixel &p)
Definition: itkRankHistogram.h:342
itk::Function::RankHistogram::operator=
RankHistogram & operator=(const RankHistogram &hist)
Definition: itkRankHistogram.h:78
itk::Function::RankHistogram::UseVectorBasedAlgorithm
static bool UseVectorBasedAlgorithm()
Definition: itkRankHistogram.h:250
itk::Function::RankHistogram::IsValid
bool IsValid()
Definition: itkRankHistogram.h:135
itk::Function::VectorRankHistogram::m_InitVal
TInputPixel m_InitVal
Definition: itkRankHistogram.h:390
itk::Function::RankHistogram::RankHistogram
RankHistogram()
Definition: itkRankHistogram.h:57
itk::Function::RankHistogram::RemovePixel
void RemovePixel(const TInputPixel &p)
Definition: itkRankHistogram.h:116
itk::NumericTraits::NonpositiveMin
static constexpr T NonpositiveMin()
Definition: itkNumericTraits.h:97
itk::Function::VectorRankHistogram::m_Compare
Compare m_Compare
Definition: itkRankHistogram.h:388
itk::Function::VectorRankHistogram::m_Rank
float m_Rank
Definition: itkRankHistogram.h:381
itk::Function::VectorRankHistogram::VectorRankHistogram
VectorRankHistogram()
Definition: itkRankHistogram.h:280
itk::Function::RankHistogram::RemoveBoundary
void RemoveBoundary()
Definition: itkRankHistogram.h:246
itk::Function::VectorRankHistogram::m_Vec
VecType m_Vec
Definition: itkRankHistogram.h:386
itk::Function::VectorRankHistogram::UseVectorBasedAlgorithm
static bool UseVectorBasedAlgorithm()
Definition: itkRankHistogram.h:375
itk::Function::VectorRankHistogram::AddPixel
void AddPixel(const TInputPixel &p)
Definition: itkRankHistogram.h:329
itk::Function::VectorRankHistogram::GetValue
TInputPixel GetValue(const TInputPixel &)
Definition: itkRankHistogram.h:323
itk::Function::VectorRankHistogram::m_Size
SizeValueType m_Size
Definition: itkRankHistogram.h:387
itk::Function::VectorRankHistogram::SetRank
void SetRank(float rank)
Definition: itkRankHistogram.h:361
itk::Function::RankHistogram::m_RankIt
MapType::iterator m_RankIt
Definition: itkRankHistogram.h:270
itk::Function::RankHistogram::~RankHistogram
~RankHistogram()=default
itk::Function::RankHistogram::AddBoundary
void AddBoundary()
Definition: itkRankHistogram.h:242
itk::Function::RankHistogram::m_InitVal
TInputPixel m_InitVal
Definition: itkRankHistogram.h:265
itk::Function::RankHistogram::Compare
std::less< TInputPixel > Compare
Definition: itkRankHistogram.h:55
itk::Function::VectorRankHistogram::m_RankValue
TInputPixel m_RankValue
Definition: itkRankHistogram.h:389
itk::Function::VectorRankHistogram::~VectorRankHistogram
~VectorRankHistogram()=default
itk::Function::VectorRankHistogram::IsValid
bool IsValid()
Definition: itkRankHistogram.h:301
itk::Function::VectorRankHistogram::Compare
std::less< TInputPixel > Compare
Definition: itkRankHistogram.h:278
itk::Function::VectorRankHistogram::m_Entries
int m_Entries
Definition: itkRankHistogram.h:392
itk::Function::RankHistogram::m_Map
MapType m_Map
Definition: itkRankHistogram.h:261
itkIntTypes.h
itk::Function::VectorRankHistogram::AddBoundary
void AddBoundary()
Definition: itkRankHistogram.h:367
itk::NumericTraits
Define additional traits for native types such as int or float.
Definition: itkNumericTraits.h:58
itk::NumericTraits::max
static constexpr T max(const T &)
Definition: itkNumericTraits.h:167
itk::Function::VectorRankHistogram::VecType
typename std::vector< SizeValueType > VecType
Definition: itkRankHistogram.h:384
itk::Function::RankHistogram::GetValue
TInputPixel GetValue(const TInputPixel &)
Definition: itkRankHistogram.h:157
itk::Function::RankHistogram::m_RankValue
TInputPixel m_RankValue
Definition: itkRankHistogram.h:264
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkArray.h:26
itk::Function::RankHistogram::m_Rank
float m_Rank
Definition: itkRankHistogram.h:256
itk::Function::VectorRankHistogram::RemoveBoundary
void RemoveBoundary()
Definition: itkRankHistogram.h:371
itk::OffsetValueType
signed long OffsetValueType
Definition: itkIntTypes.h:94
itk::Function::VectorRankHistogram::GetValueBruteForce
TInputPixel GetValueBruteForce()
Definition: itkRankHistogram.h:307
itk::Function::VectorRankHistogram::m_Below
int m_Below
Definition: itkRankHistogram.h:391
itkNumericTraits.h
itk::Function::RankHistogram
Definition: itkRankHistogram.h:52
itk::Function::RankHistogram::m_Compare
Compare m_Compare
Definition: itkRankHistogram.h:266
itk::Function::RankHistogram::m_Entries
SizeValueType m_Entries
Definition: itkRankHistogram.h:263
itk::Function::RankHistogram::SetRank
void SetRank(float rank)
Definition: itkRankHistogram.h:236
itk::Function::RankHistogram::AddPixel
void AddPixel(const TInputPixel &p)
Definition: itkRankHistogram.h:98
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:83
itk::Function::RankHistogram::m_Initialized
bool m_Initialized
Definition: itkRankHistogram.h:267
itk::Function::RankHistogram::MapType
typename std::map< TInputPixel, SizeValueType, Compare > MapType
Definition: itkRankHistogram.h:259