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