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

medianfilter.hxx
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
101doxygen_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
vigra::Diff2D
Two dimensional difference vector.
Definition diff2d.hxx:186
vigra::Diff2D::y
int y
Definition diff2d.hxx:392
vigra::Diff2D::x
int x
Definition diff2d.hxx:385
vigra::MultiArrayView
Base class for, and view to, MultiArray.
Definition multi_array.hxx:705
vigra
vigra::medianFilter
void medianFilter(...)
This function calculates the median of a window of given size for the complete image.
vigra::applyWindowFunction
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.12.4