aimstil  5.0.5
NeighborhoodConfigurations.h
Go to the documentation of this file.
1 #ifndef TIL_NEIGHBORHOOD_CONFIGURATION_H
2 #define TIL_NEIGHBORHOOD_CONFIGURATION_H
3 
4 // includes from TIL library
5 #include "til/til_common.h"
6 #include "til/labels.h"
7 #include "til/Neighborhood.h"
8 #include "til/templateTools.h"
9 
10 
11 // Namespace
12 namespace til {
13 
14 
15 // This class only collects code common to most morphological assessment
16 // class. Basically, it handles neighborhoods and foreground/background
17 // intensity values
18 
19 template <class _TImage, class _TNeighborhood>
21 {
22 
23 public: // typedefs
24 
25  typedef _TImage TImage;
26  typedef _TNeighborhood TNeighborhood;
27  typedef typename TImage::value_type value_type;
29 
30 
31 public: // constructors & destructor
32 
33  explicit PT_NeighborhoodConfigurations(const TNeighborhood &nh)
34  {
35  m_foreground = 1;
36  m_background = 0;
37  m_nh = nh;
38  //this->setNeighborhood(nh);
39  }
40 
41 
42 public: // set & get
43 
44  void setForeground(value_type foreground) { m_foreground = foreground; }
45  void setBackground(value_type background) { m_background = background; }
46 
47  value_type getForeground() const { return m_foreground; }
48  value_type getBackground() const { return m_background; }
49 
50 
51 public: // functions
52 
53  // This function is used in if_next functions
54  // It says that nothing is to be updated when going to the next pixel
55  static void next() {}
56 
57 
58 protected: // data
59 
60  // The neighborhood
61  TNeighborhood m_nh;
62 
63 private: // data
64 
65  // Foreground and background values
66  value_type m_foreground;
67  value_type m_background;
68 };
69 
70 
71 template <class TVolumetricIterator, class _TNeighborhood = Neighborhood>
72 class NeighborhoodConfigurations : public ImageFunctor_label
73 {
74 public: // typedefs
75 
76  typedef _TNeighborhood TNeighborhood;
77  typedef typename TVolumetricIterator::value_type value_type;
78 
79 public: // constructors & destructor
80 
81 
83  : m_foreground(1), m_background(0), m_nh()
84  {}
85 
86  // TODO: when value_type is not numeric, it might be that this class won't
87  // even compile because of the default values -- which is bad
88  NeighborhoodConfigurations(const TNeighborhood &nh)
89  : m_foreground(1), m_background(0), m_nh(nh) {};
90 
91  NeighborhoodConfigurations(value_type foreground, value_type background, const TNeighborhood &nh = TNeighborhood())
92  : m_foreground(foreground), m_background(background), m_nh(nh) {};
93 
94 public: // set & get
95 
96  //void setForeground(value_type foreground) { m_foreground = foreground; }
97  //void setBackground(value_type background) { m_background = background; }
98 
99  value_type getForeground() const { return m_foreground; }
100  value_type getBackground() const { return m_background; }
101 
102 
103 protected: // data
104 
105  // neighborhood
106  TNeighborhood m_nh;
107 
108 private: // data
109 
110  // foreground value for all morphological considerations
111  const value_type m_foreground;
112  // background value for all morphological considerations
113  const value_type m_background;
114 };
115 
116 
117 
118 
119 
120 // This class checks whether a point is interior, i.e. if all its neighbors
121 // are also foreground.
122 
123 template < class _TImage, class _TNeighborhood = Neighborhood >
124 class PT_IsInterior : public PT_NeighborhoodConfigurations<_TImage,_TNeighborhood>
125 {
126 public: // typedefs
127 
128  typedef _TImage TImage;
129  typedef _TNeighborhood TNeighborhood;
130  typedef typename TImage::value_type value_type;
132 
133 public: // constructors & destructor
134 
135  PT_IsInterior(const TNeighborhood &nh = _TNeighborhood())
136  : PT_NeighborhoodConfigurations<TImage,TNeighborhood>(nh) {}
137 
138 public:
139 
140  INLINE bool _compute(const ConstVolumetricIterator &iIm) const
141  {
142  if (
143  // First 6 neighbors
144  this->cond<-1, 0, 0>(iIm) &&
145  this->cond< 0,-1, 0>(iIm) &&
146  this->cond< 0, 0,-1>(iIm) &&
147  this->cond<+1, 0, 0>(iIm) &&
148  this->cond< 0,+1, 0>(iIm) &&
149  this->cond< 0, 0,+1>(iIm) &&
150 
151  // Next 12
152  this->cond<-1,-1, 0>(iIm) &&
153  this->cond<-1, 0,-1>(iIm) &&
154  this->cond< 0,-1,-1>(iIm) &&
155  this->cond<+1,+1, 0>(iIm) &&
156  this->cond<+1, 0,+1>(iIm) &&
157  this->cond< 0,+1,+1>(iIm) &&
158  this->cond<-1,+1, 0>(iIm) &&
159  this->cond<-1, 0,+1>(iIm) &&
160  this->cond< 0,-1,+1>(iIm) &&
161  this->cond<+1,-1, 0>(iIm) &&
162  this->cond<+1, 0,-1>(iIm) &&
163  this->cond< 0,+1,-1>(iIm) &&
164 
165  // Last 8
166  this->cond<-1,-1,-1>(iIm) &&
167  this->cond<+1,+1,+1>(iIm) &&
168  this->cond<+1,-1,-1>(iIm) &&
169  this->cond<-1,+1,-1>(iIm) &&
170  this->cond<-1,-1,+1>(iIm) &&
171  this->cond<-1,+1,+1>(iIm) &&
172  this->cond<+1,-1,+1>(iIm) &&
173  this->cond<+1,+1,-1>(iIm)
174  )
175  {
176  return true;
177  }
178  else
179  {
180  return false;
181  }
182  }
183 
184 
185  INLINE bool compute(const ConstVolumetricIterator &iIm) const
186  {
187  if (*iIm != this->getForeground())
188  {
189  return false;
190  }
191 
192  return _compute(iIm);
193  }
194 
195 private: // functions
196 
197  template <int i, int j, int k>
198  bool cond(const ConstVolumetricIterator &iIm) const
199  {
200  return (
201  !this->m_nh.template isNeighbor<i,j,k>() || // There is no neighbor
202  !containsNeighbor<i,j,k>(iIm) || // Or it is not in image
203  iIm.template getUnsafeValue<i,j,k>() == this->getForeground() // or it is foreground
204  );
205  }
206 
207 };
208 
209 // This class checks whether a point is interior, i.e. if all its neighbors
210 // are also foreground.
211 
212 template < class _TImage, class _TNeighborhood = Neighborhood >
213 class PT_IsBoundary : public PT_NeighborhoodConfigurations<_TImage,_TNeighborhood>
214 {
215 public: // typedefs
216 
217  typedef _TImage TImage;
218  typedef _TNeighborhood TNeighborhood;
219  typedef typename TImage::value_type value_type;
221 
222 public: // constructors & destructor
223 
224  PT_IsBoundary(const TNeighborhood &nh = _TNeighborhood())
225  : PT_NeighborhoodConfigurations<TImage,TNeighborhood>(nh) {}
226 
227 public:
228 
229  INLINE bool _compute(const ConstVolumetricIterator &iIm) const
230  {
231  if (
232  // First 6 neighbors
233  this->cond<-1, 0, 0>(iIm) ||
234  this->cond< 0,-1, 0>(iIm) ||
235  this->cond< 0, 0,-1>(iIm) ||
236  this->cond<+1, 0, 0>(iIm) ||
237  this->cond< 0,+1, 0>(iIm) ||
238  this->cond< 0, 0,+1>(iIm) ||
239 
240  // Next 12
241  this->cond<-1,-1, 0>(iIm) ||
242  this->cond<-1, 0,-1>(iIm) ||
243  this->cond< 0,-1,-1>(iIm) ||
244  this->cond<+1,+1, 0>(iIm) ||
245  this->cond<+1, 0,+1>(iIm) ||
246  this->cond< 0,+1,+1>(iIm) ||
247  this->cond<-1,+1, 0>(iIm) ||
248  this->cond<-1, 0,+1>(iIm) ||
249  this->cond< 0,-1,+1>(iIm) ||
250  this->cond<+1,-1, 0>(iIm) ||
251  this->cond<+1, 0,-1>(iIm) ||
252  this->cond< 0,+1,-1>(iIm) ||
253 
254  // Last 8
255  this->cond<-1,-1,-1>(iIm) ||
256  this->cond<+1,+1,+1>(iIm) ||
257  this->cond<+1,-1,-1>(iIm) ||
258  this->cond<-1,+1,-1>(iIm) ||
259  this->cond<-1,-1,+1>(iIm) ||
260  this->cond<-1,+1,+1>(iIm) ||
261  this->cond<+1,-1,+1>(iIm) ||
262  this->cond<+1,+1,-1>(iIm)
263  )
264  {
265  return true;
266  }
267  else
268  {
269  return false;
270  }
271  }
272 
273 
274  INLINE bool compute(const ConstVolumetricIterator &iIm) const
275  {
276  if (*iIm != this->getForeground())
277  {
278  return false;
279  }
280 
281  return _compute(iIm);
282  }
283 
284 private: // functions
285 
286  template <int i, int j, int k>
287  bool cond(const ConstVolumetricIterator &iIm) const
288  {
289  return (
290  this->m_nh.template isNeighbor<i,j,k>() && // There is a neighbor...
291  containsNeighbor<i,j,k>(iIm) && // ...and it is inside the image...
292  iIm.template getUnsafeValue<i,j,k>() != this->getForeground() // ...and it is not foreground
293  );
294  }
295 
296 };
297 
298 
299 template < class _TImage, class _TNeighborhood = Neighborhood >
300 class PT_IsIsolated : public PT_NeighborhoodConfigurations<_TImage, _TNeighborhood>
301 {
302 public: // typedefs
303 
304  typedef _TImage TImage;
305  typedef _TNeighborhood TNeighborhood;
306  typedef typename TImage::value_type value_type;
308 
309 public: // constructors & destructor
310 
311  PT_IsIsolated(const TNeighborhood &nh = _TNeighborhood())
312  : PT_NeighborhoodConfigurations<TImage,TNeighborhood>(nh) {}
313 
314 
315 public: // functions
316 
317  INLINE bool _compute(const ConstVolumetricIterator &iIm) const
318  {
319  if (
320 
321  // First 6 neighbors
322  this->cond<-1, 0, 0>(iIm) &&
323  this->cond< 0,-1, 0>(iIm) &&
324  this->cond< 0, 0,-1>(iIm) &&
325  this->cond<+1, 0, 0>(iIm) &&
326  this->cond< 0,+1, 0>(iIm) &&
327  this->cond< 0, 0,+1>(iIm) &&
328 
329  // Next 12
330  this->cond<-1,-1, 0>(iIm) &&
331  this->cond<-1, 0,-1>(iIm) &&
332  this->cond< 0,-1,-1>(iIm) &&
333  this->cond<+1,+1, 0>(iIm) &&
334  this->cond<+1, 0,+1>(iIm) &&
335  this->cond< 0,+1,+1>(iIm) &&
336  this->cond<-1,+1, 0>(iIm) &&
337  this->cond<-1, 0,+1>(iIm) &&
338  this->cond< 0,-1,+1>(iIm) &&
339  this->cond<+1,-1, 0>(iIm) &&
340  this->cond<+1, 0,-1>(iIm) &&
341  this->cond< 0,+1,-1>(iIm) &&
342 
343  // Last 8
344  this->cond<-1,-1,-1>(iIm) &&
345  this->cond<+1,+1,+1>(iIm) &&
346  this->cond<+1,-1,-1>(iIm) &&
347  this->cond<-1,+1,-1>(iIm) &&
348  this->cond<-1,-1,+1>(iIm) &&
349  this->cond<-1,+1,+1>(iIm) &&
350  this->cond<+1,-1,+1>(iIm) &&
351  this->cond<+1,+1,-1>(iIm)
352  )
353  {
354  return true;
355  }
356  else
357  {
358  return false;
359  }
360  }
361 
362 
363  INLINE bool compute(const ConstVolumetricIterator &iIm) const
364  {
365  if (*iIm != this->getForeground())
366  {
367  return false;
368  }
369 
370  return this->_compute(iIm);
371  }
372 
373 private: // functions
374 
375 
376  template <int i, int j, int k>
377  bool cond(const ConstVolumetricIterator &iIm) const
378  {
379  return (
380  !this->m_nh.template isNeighbor<i,j,k>() || // There is no neighbor
381  !containsNeighbor<i,j,k>(iIm) || // or it is not in image
382  iIm.template getUnsafeValue<i,j,k>() == this->getBackground() // or it is background
383  );
384  }
385 };
386 
387 
388 template < class TVolumetricIterator, class _TNeighborhood = Neighborhood >
389 class IsIsolated :
390  public NeighborhoodConfigurations<TVolumetricIterator, _TNeighborhood>,
391  public std::unary_function<TVolumetricIterator, bool>
392 {
393 public: // typedefs
394 
395  // The other type is empty, so we discard it as a "real" base and use
396  // simple inheritance conventions.
398  //typedef _TImage TImage;
399  typedef _TNeighborhood TNeighborhood;
400  typedef typename TVolumetricIterator::value_type value_type;
401  // This redefinition is necessary, I think because of multiple inheritance.
402  typedef bool result_type;
403  //typedef typename TImage::value_type value_type;
404  //typedef typename Iterator<TImage>::ConstVolumetric ConstVolumetricIterator;
405 
406 public: // constructors & destructor
407 
408  IsIsolated() : Base() {}
409  explicit IsIsolated(const TNeighborhood &nh) : Base(nh) {}
410  IsIsolated(value_type foreground, value_type background, const TNeighborhood &nh = _TNeighborhood())
411  : Base(foreground, background, nh) {}
412 
413 public: // functions
414 
415  INLINE
416 // typename enable_if<is_VolumetricImageIterator<VolumetricImageIterator>, bool>::type
417  bool
418  _compute(const TVolumetricIterator &iIm) const
419  {
420  if (
421  // First 6 neighbors
422  this->cond<-1, 0, 0>(iIm) &&
423  this->cond< 0,-1, 0>(iIm) &&
424  this->cond< 0, 0,-1>(iIm) &&
425  this->cond<+1, 0, 0>(iIm) &&
426  this->cond< 0,+1, 0>(iIm) &&
427  this->cond< 0, 0,+1>(iIm) &&
428 
429  // Next 12
430  this->cond<-1,-1, 0>(iIm) &&
431  this->cond<-1, 0,-1>(iIm) &&
432  this->cond< 0,-1,-1>(iIm) &&
433  this->cond<+1,+1, 0>(iIm) &&
434  this->cond<+1, 0,+1>(iIm) &&
435  this->cond< 0,+1,+1>(iIm) &&
436  this->cond<-1,+1, 0>(iIm) &&
437  this->cond<-1, 0,+1>(iIm) &&
438  this->cond< 0,-1,+1>(iIm) &&
439  this->cond<+1,-1, 0>(iIm) &&
440  this->cond<+1, 0,-1>(iIm) &&
441  this->cond< 0,+1,-1>(iIm) &&
442 
443  // Last 8
444  this->cond<-1,-1,-1>(iIm) &&
445  this->cond<+1,+1,+1>(iIm) &&
446  this->cond<+1,-1,-1>(iIm) &&
447  this->cond<-1,+1,-1>(iIm) &&
448  this->cond<-1,-1,+1>(iIm) &&
449  this->cond<-1,+1,+1>(iIm) &&
450  this->cond<+1,-1,+1>(iIm) &&
451  this->cond<+1,+1,-1>(iIm)
452  )
453  {
454  return true;
455  }
456  else
457  {
458  return false;
459  }
460  }
461 
462  INLINE
463  //typename enable_if<is_VolumetricImageIterator<VolumetricImageIterator>, bool>::type
464  bool
465  operator()(const TVolumetricIterator &iIm) const
466  {
467  if (*iIm != this->getForeground())
468  {
469  return false;
470  }
471 
472  return this->_compute(iIm);
473  }
474 
475 private: // functions
476 
477 
478  template <int i, int j, int k >
479  bool cond(const TVolumetricIterator &iIm) const
480  {
481  return (
482  !this->m_nh.template isNeighbor<i,j,k>() || // There is no neighbor
483  !containsNeighbor<i,j,k>(iIm) || // or it is not in image
484  iIm.template getUnsafeValue<i,j,k>() == this->getBackground() // or it is background
485  );
486  }
487 };
488 
489 
490 template < class _TImage, class _TNeighborhood = Neighborhood >
491 class PT_HasNBackgroundNeighbors : public PT_NeighborhoodConfigurations<_TImage,_TNeighborhood>
492 {
493 public: // typedefs
494 
495  typedef _TImage TImage;
496  typedef _TNeighborhood TNeighborhood;
497  typedef typename TImage::value_type value_type;
499 
500 public: // constuctors & destructor
501 
502  PT_HasNBackgroundNeighbors(int nNeighbors, const TNeighborhood &nh = _TNeighborhood())
503  : PT_NeighborhoodConfigurations<TImage,TNeighborhood>(nh)
504  {
505  this->setNNeighbors(nNeighbors);
506  }
507 
508 
509 public: // set & get
510 
511  void setNNeighbors(int nNeighbors) { m_nNeighbors = nNeighbors; }
512  int getNNeighbors() { return m_nNeighbors; }
513 
514 
515 public: // functions
516 
517  INLINE bool _compute(const ConstVolumetricIterator &iIm) const
518  {
519  int count = 0;
520 
521  // First 6 neighbors
522  if (this->cond<-1, 0, 0>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
523  if (this->cond< 0,-1, 0>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
524  if (this->cond< 0, 0,-1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
525 
526  if (this->cond<+1, 0, 0>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
527  if (this->cond< 0,+1, 0>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
528  if (this->cond< 0, 0,+1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
529 
530  // Next 12
531  if (this->cond<-1,-1, 0>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
532  if (this->cond<-1, 0,-1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
533  if (this->cond< 0,-1,-1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
534 
535  if (this->cond<+1,+1, 0>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
536  if (this->cond<+1, 0,+1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
537  if (this->cond< 0,+1,+1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
538 
539  if (this->cond<-1,+1, 0>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
540  if (this->cond<-1, 0,+1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
541  if (this->cond< 0,-1,+1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
542 
543  if (this->cond<+1,-1, 0>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
544  if (this->cond<+1, 0,-1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
545  if (this->cond< 0,+1,-1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
546 
547  // Last 8
548  if (this->cond<-1,-1,-1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
549  if (this->cond<+1,+1,+1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
550 
551  if (this->cond<+1,-1,-1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
552  if (this->cond<-1,+1,-1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
553  if (this->cond<-1,-1,+1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
554 
555  if (this->cond<-1,+1,+1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
556  if (this->cond<+1,-1,+1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
557  if (this->cond<+1,+1,-1>(iIm)) { ++count; if (count >= m_nNeighbors) return true; }
558 
559  return false;
560  }
561 
562 
563  INLINE bool compute(const ConstVolumetricIterator &iIm) const
564  {
565  if (*iIm != this->getForeground())
566  {
567  return false;
568  }
569 
570  return this->_compute(iIm);
571  }
572 
573 private: // functions
574 
575  template < int i, int j, int k >
576  INLINE bool cond(const ConstVolumetricIterator &iIm) const
577  {
578  return (
579  this->m_nh.template isNeighbor<i,j,k>() && // There is a neighbor
580  containsNeighbor<i,j,k>(iIm) && // This neighbor is inside
581  iIm.template getUnsafeValue<i,j,k>() == this->getBackground() // and its value is background
582  );
583  }
584 
585 private:
586 
587  int m_nNeighbors;
588 };
589 
590 
591 } // namespace
592 
593 
594 #endif
595 
Iterator< TImage >::ConstVolumetric ConstVolumetricIterator
A trait class to assign iterators to image types.
INLINE bool compute(const ConstVolumetricIterator &iIm) const
INLINE bool compute(const ConstVolumetricIterator &iIm) const
TVolumetricIterator::value_type value_type
PT_NeighborhoodConfigurations(const TNeighborhood &nh)
PT_IsBoundary(const TNeighborhood &nh=_TNeighborhood())
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
NeighborhoodConfigurations(const TNeighborhood &nh)
Iterator< TImage >::ConstVolumetric ConstVolumetricIterator
General macros, definitions and functions.
Defines empty classes that serves as labels.
Iterator< TImage >::ConstVolumetric ConstVolumetricIterator
PT_IsInterior(const TNeighborhood &nh=_TNeighborhood())
INLINE bool _compute(const ConstVolumetricIterator &iIm) const
INLINE bool _compute(const ConstVolumetricIterator &iIm) const
INLINE bool _compute(const ConstVolumetricIterator &iIm) const
INLINE bool _compute(const ConstVolumetricIterator &iIm) const
#define INLINE
Definition: til_common.h:26
INLINE bool compute(const ConstVolumetricIterator &iIm) const
IsIsolated(value_type foreground, value_type background, const TNeighborhood &nh=_TNeighborhood())
Iterator< TImage >::ConstVolumetric ConstVolumetricIterator
INLINE bool operator()(const TVolumetricIterator &iIm) const
NeighborhoodConfigurations< TVolumetricIterator, _TNeighborhood > Base
Collects template tools used for library implementation.
INLINE bool _compute(const TVolumetricIterator &iIm) const
INLINE bool compute(const ConstVolumetricIterator &iIm) const
PT_HasNBackgroundNeighbors(int nNeighbors, const TNeighborhood &nh=_TNeighborhood())
TVolumetricIterator::value_type value_type
PT_IsIsolated(const TNeighborhood &nh=_TNeighborhood())
IsIsolated(const TNeighborhood &nh)
NeighborhoodConfigurations(value_type foreground, value_type background, const TNeighborhood &nh=TNeighborhood())
Iterator< TImage >::ConstVolumetric ConstVolumetricIterator