[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

medianfilter.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2007-2014 by Benjamin Seppke */
4 /* Cognitive Systems Group, University of Hamburg, Germany */
5 /* */
6 /************************************************************************/
7 
8 #ifndef VIGRA_MEDIANFILTER_HXX
9 #define VIGRA_MEDIANFILTER_HXX
10 
11 #include <vector>
12 #include <algorithm>
13 
14 #include "applywindowfunction.hxx"
15 
16 namespace vigra
17 {
18 
19 /********************************************************/
20 /* */
21 /* Generic median filter */
22 /* */
23 /********************************************************/
24 /**
25  This function calculates the median of a window of given size for the complete image.
26  It also allows a correct border handling, since it uses the \ref applyWindowFunction
27  environment for computation!
28 */
29 //@{
30 
31 /** \brief This function calculates the median of a window of given size for the complete image.
32 
33  All \ref BorderTreatmentMode "border treatment modes" (except BORDER_TREATMENT_CLIP) are supported.
34 
35  The input pixel type <tt>T1</tt> must be a \ref LinearSpace "linear space" over
36  the window functions' value_type <tt>T</tt>. Especially, the values must be sortable by
37  std::sort, to derive the mean values aka the median.
38 
39  <b> Declarations:</b>
40 
41  pass 2D array views:
42  \code
43  namespace vigra {
44  template <class T1, class S1,
45  class T2, class S2>
46  void
47  medianFilter(MultiArrayView<2, T1, S1> const & src,
48  MultiArrayView<2, T2, S2> dest,
49  Diff2D window_shape,
50  BorderTreatmentMode border = BORDER_TREATMENT_REPEAT);
51 
52  }
53  \endcode
54 
55  \deprecatedAPI{medianFilter}
56  pass \ref ImageIterators and \ref DataAccessors :
57  \code
58  namespace vigra {
59  template <class SrcIterator, class SrcAccessor,
60  class DestIterator, class DestAccessor>
61  void medianFilter(SrcIterator supperleft,
62  SrcIterator slowerright, SrcAccessor sa,
63  DestIterator dupperleft, DestAccessor da,
64  Diff2D window_shape,
65  BorderTreatmentMode border = BORDER_TREATMENT_REPEAT);
66  }
67  \endcode
68  use argument objects in conjunction with \ref ArgumentObjectFactories :
69  \code
70  namespace vigra {
71  template <class SrcIterator, class SrcAccessor,
72  class DestIterator, class DestAccessor>
73  void
74  medianFilter(triple<SrcIterator, SrcIterator, SrcAccessor> src,
75  pair<DestIterator, DestAccessor> dest,
76  Diff2D window_shape,
77  BorderTreatmentMode border = BORDER_TREATMENT_REPEAT);
78  }
79  \endcode
80  \deprecatedEnd
81 
82  <b> Usage:</b>
83 
84  <b>\#include</b> <vigra/medianfilter.hxx><br/>
85  Namespace: vigra
86 
87  \code
88  unsigned int w=1000, h=1000;
89  MultiArray<2, float> src(w,h), dest(w,h);
90  ...
91 
92  // apply a median filter with a window size of 5x5
93  medianFilter(src, dest, Diff2D(5,5));
94  \endcode
95 
96  <b> Preconditions:</b>
97 
98  The image must be larger than the window size of the filter.
99 */
100 
101 doxygen_overloaded_function(template <...> void medianFilter)
102 
103 template<class VALUETYPE>
104 class MedianFunctor
105 {
106 public:
107  MedianFunctor(Diff2D window_shape)
108  : m_window_shape(window_shape),
109  m_buffer(window_shape.x*window_shape.y)
110  {
111  }
112 
113  template <class SrcIterator, class SrcAccessor, class DestIterator, class DestAccessor>
114  void operator()(SrcIterator s, SrcAccessor s_acc, DestIterator d, DestAccessor d_acc)
115  {
116  SrcIterator s_ul = s - m_window_shape/2,
117  s_lr = s_ul + m_window_shape;
118 
119  std::fill(m_buffer.begin(), m_buffer.end(), VALUETYPE());
120 
121  SrcIterator ys = s_ul;
122  SrcIterator xs = ys;
123 
124  typename std::vector<VALUETYPE>::iterator iter = m_buffer.begin(),
125  median_iter = m_buffer.begin()+m_buffer.size()/2;
126 
127  for( ; ys.y != s_lr.y; ys.y++)
128  {
129  for(xs = ys; xs.x != s_lr.x; xs.x++, iter++)
130  {
131  *iter = s_acc(xs);
132  }
133  }
134 
135  std::nth_element(m_buffer.begin(), median_iter, m_buffer.end());
136  d_acc.set(*median_iter,d);
137  }
138 
139  Diff2D windowShape() const
140  {
141  return m_window_shape;
142  }
143 
144 private:
145  Diff2D m_window_shape;
146  std::vector<VALUETYPE> m_buffer;
147 };
148 
149 
150 template <class SrcIterator, class SrcAccessor,
151  class DestIterator, class DestAccessor>
152 inline void medianFilter(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
153  DestIterator d_ul, DestAccessor d_acc,
154  Diff2D window_shape,
155  BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
156 {
157  MedianFunctor<typename SrcIterator::value_type> func(window_shape);
158  applyWindowFunction(s_ul, s_lr, s_acc, d_ul, d_acc, func, border);
159 }
160 
161 template <class SrcIterator, class SrcAccessor,
162  class DestIterator, class DestAccessor>
163 inline void medianFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
164  pair<DestIterator, DestAccessor> d,
165  Diff2D window_shape,
166  BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
167 {
168  medianFilter(s.first, s.second, s.third,
169  d.first, d.second,
170  window_shape,
171  border);
172 }
173 
174 template <class T1, class S1,
175  class T2, class S2>
176 inline void medianFilter(MultiArrayView<2, T1, S1> const & src,
177  MultiArrayView<2, T2, S2> dest,
178  Diff2D window_shape,
179  BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
180 {
181  vigra_precondition(src.shape() == dest.shape(),
182  "vigra::medianFilter(): shape mismatch between input and output.");
183  medianFilter(srcImageRange(src),
184  destImage(dest),
185  window_shape,
186  border);
187 }
188 
189 //@}
190 
191 } //end of namespace vigra
192 
193 #endif //VIGRA_MEDIANFILTER_HXX
void medianFilter(...)
This function calculates the median of a window of given size for the complete image.
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
void applyWindowFunction(...)
Apply a window function to each pixels of a given image.

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)