8 #ifndef VIGRA_SPECKLEFILTER_HXX
9 #define VIGRA_SPECKLEFILTER_HXX
11 #include "basicimage.hxx"
12 #include "inspectimage.hxx"
14 #include "applywindowfunction.hxx"
29 double w_half = window_shape.
x/2.0,
30 h_half = window_shape.
y/2.0,
33 for(y=0; y != window_shape.
y; y++)
35 for(x=0; x != window_shape.
x; x++)
39 res(x,y) =
sqrt(x_diff*x_diff + y_diff*y_diff);
137 template<
typename VALUETYPE>
141 FrostFunctor(Diff2D window_shape,
float k)
142 : m_window_shape(window_shape),
144 m_dist(detail::distanceLUT(window_shape))
146 using namespace vigra;
147 vigra_precondition( k>0 && k<=1 ,
"vigra::FrostFunctor(): Damping factor k has to be: 0 < k <= 1!");
150 template <
class SrcIterator,
class SrcAccessor,
class DestIterator,
class DestAccessor>
151 void operator()(SrcIterator s, SrcAccessor s_acc, DestIterator d, DestAccessor d_acc)
153 using namespace vigra;
155 SrcIterator s_ul = s - m_window_shape/2,
156 s_lr = s_ul + m_window_shape;
163 VALUETYPE C_I2 = averageAndVariance.variance() / (averageAndVariance.average() * averageAndVariance.average()),
170 SrcIterator ys = s_ul;
179 for(y=0 ; ys.y!=s_lr.y; ys.y++, ydist.y++, y++)
181 for(xs=ys, xdist=ydist, x=0; xs.x!=s_lr.x; xs.x++, xdist.x++, x++)
186 m =
exp(-1 * m_k * C_I2 * dist_acc(xdist));
194 d_acc.set(sum_pm/sum_m, d);
197 Diff2D windowShape()
const
199 return m_window_shape;
208 template <
class SrcIterator,
class SrcAccessor,
209 class DestIterator,
class DestAccessor>
210 inline void frostFilter(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
211 DestIterator d_ul, DestAccessor d_acc,
212 Diff2D window_shape,
float k,
213 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
215 FrostFunctor<typename SrcIterator::value_type> func(window_shape, k);
219 template <
class SrcIterator,
class SrcAccessor,
220 class DestIterator,
class DestAccessor>
221 inline void frostFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
222 pair<DestIterator, DestAccessor> d,
223 Diff2D window_shape,
float k,
224 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
233 template <
class T1,
class S1,
237 Diff2D window_shape,
float k,
238 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
240 vigra_precondition(src.
shape() == dest.
shape(),
241 "vigra::frostFilter(): Shape mismatch between input and output.");
339 template<
typename VALUETYPE>
344 : m_window_shape(window_shape),
347 m_dist(detail::distanceLUT(window_shape))
350 using namespace vigra;
351 vigra_precondition( k>0 && k<=1 ,
"vigra::EnhancedFrostFunctor(): Damping factor k has to be: 0 < k <= 1!");
352 vigra_precondition( enl>0,
"vigra::EnhancedFrostFunctor(): Equivalent number of looks (enl) must be larger than zero!");
355 template <
class SrcIterator,
class SrcAccessor,
class DestIterator,
class DestAccessor>
356 void operator()(SrcIterator s, SrcAccessor s_acc, DestIterator d, DestAccessor d_acc)
358 using namespace vigra;
360 SrcIterator s_ul = s - m_window_shape/2,
361 s_lr = s_ul + m_window_shape;
369 VALUETYPE C_u = 0.523/
sqrt((
double)m_enl),
370 C_max =
sqrt(1+2.0/m_enl),
371 C_I =
sqrt(averageAndVariance.variance()) / averageAndVariance.average(),
378 SrcIterator ys = s_ul;
387 for(y=0 ; ys.y!=s_lr.y; ys.y++, ydist.y++, y++)
389 for(xs=ys, xdist=ydist, x=0; xs.x!=s_lr.x; xs.x++, xdist.x++, x++)
394 m =
exp(-m_k * func(C_I, C_max, C_u) * dist_acc(xdist));
402 d_acc.set(sum_pm/sum_m, d);
405 Diff2D windowShape()
const
407 return m_window_shape;
413 inline double func(
double C_I,
double C_max,
double C_u)
const
419 else if (C_I <= C_max)
421 return (C_I - C_u)/(C_max - C_I);
435 template <
class SrcIterator,
class SrcAccessor,
436 class DestIterator,
class DestAccessor>
437 inline void enhancedFrostFilter(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
438 DestIterator d_ul, DestAccessor d_acc,
439 Diff2D window_shape,
float k,
int enl,
440 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
446 template <
class SrcIterator,
class SrcAccessor,
447 class DestIterator,
class DestAccessor>
448 inline void enhancedFrostFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
449 pair<DestIterator, DestAccessor> d,
450 Diff2D window_shape,
float k,
int enl,
451 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
453 enhancedFrostFilter(s.first, s.second, s.third,
455 window_shape, k, enl,
460 template <
class T1,
class S1,
464 Diff2D window_shape,
float k,
int enl,
465 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
467 vigra_precondition(src.
shape() == dest.
shape(),
468 "vigra::enhancedFrostFilter(): Shape mismatch between input and output.");
469 enhancedFrostFilter(srcImageRange(src),
471 window_shape, k, enl,
565 template<
typename VALUETYPE>
570 : m_window_shape(window_shape),
573 using namespace vigra;
574 vigra_precondition( enl>0,
"vigra::GamaMAPFunctor(): Equivalent number of looks (enl) must be larger than zero!");
577 template <
class SrcIterator,
class SrcAccessor,
class DestIterator,
class DestAccessor>
578 void operator()(SrcIterator s, SrcAccessor s_acc, DestIterator d, DestAccessor d_acc)
580 using namespace vigra;
582 SrcIterator s_ul = s - m_window_shape/2,
583 s_lr = s_ul + m_window_shape;
590 VALUETYPE C_u = 0.523/
sqrt((
double)m_enl),
591 C_max =
sqrt(1+2.0/m_enl),
592 I_mean = averageAndVariance.average(),
593 C_I =
sqrt(averageAndVariance.variance()) / I_mean;
597 d_acc.set(averageAndVariance.average(), d);
601 double alpha = (1 + C_u*C_u) / (C_I*C_I - C_u*C_u),
602 aL1 = alpha - m_enl - 1,
603 result = (aL1 * I_mean +
sqrt(I_mean*I_mean * aL1*aL1 + 4*alpha*m_enl*I_mean))
605 d_acc.set(result, d);
608 d_acc.set(s_acc(s), d);
613 Diff2D windowShape()
const
615 return m_window_shape;
624 template <
class SrcIterator,
class SrcAccessor,
625 class DestIterator,
class DestAccessor>
626 inline void gammaMAPFilter(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
627 DestIterator d_ul, DestAccessor d_acc,
628 Diff2D window_shape,
int enl,
629 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
635 template <
class SrcIterator,
class SrcAccessor,
636 class DestIterator,
class DestAccessor>
637 inline void gammaMAPFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
638 pair<DestIterator, DestAccessor> d,
639 Diff2D window_shape,
int enl,
640 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
642 gammaMAPFilter(s.first, s.second, s.third,
648 template <
class T1,
class S1,
652 Diff2D window_shape,
int enl,
653 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
655 vigra_precondition(src.
shape() == dest.
shape(),
656 "vigra::gammaMAPFilter(): Shape mismatch between input and output.");
657 gammaMAPFilter(srcImageRange(src),
751 template<
typename VALUETYPE>
756 : m_window_shape(window_shape),
759 using namespace vigra;
760 vigra_precondition( enl>0,
"vigra::KuanFunctor(): Equivalent number of looks (enl) must be larger than zero!");
763 template <
class SrcIterator,
class SrcAccessor,
class DestIterator,
class DestAccessor>
764 void operator()(SrcIterator s, SrcAccessor s_acc, DestIterator d, DestAccessor d_acc)
766 using namespace vigra;
768 SrcIterator s_ul = s - m_window_shape/2,
769 s_lr = s_ul + m_window_shape;
776 C_u2 = (0.523*0.523)/m_enl,
777 C_I2 = averageAndVariance.variance() / (averageAndVariance.average()*averageAndVariance.average()),
778 W = (1 - C_u2/C_I2)/(1 + C_u2),
780 R = I * W + averageAndVariance.average() * (1 - W);
785 Diff2D windowShape()
const
787 return m_window_shape;
795 template <
class SrcIterator,
class SrcAccessor,
796 class DestIterator,
class DestAccessor>
797 inline void kuanFilter(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
798 DestIterator d_ul, DestAccessor d_acc,
799 Diff2D window_shape,
int enl,
800 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
806 template <
class SrcIterator,
class SrcAccessor,
807 class DestIterator,
class DestAccessor>
808 inline void kuanFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
809 pair<DestIterator, DestAccessor> d,
810 Diff2D window_shape,
int enl,
811 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
813 kuanFilter(s.first, s.second, s.third,
819 template <
class T1,
class S1,
823 Diff2D window_shape,
int enl,
824 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
826 vigra_precondition(src.
shape() == dest.
shape(),
827 "vigra::kuanFilter(): Shape mismatch between input and output.");
828 kuanFilter(srcImageRange(src),
921 template<
typename VALUETYPE =
float>
926 : m_window_shape(window_shape),
929 using namespace vigra;
930 vigra_precondition( enl>0,
"vigra::LeeFunctor(): Equivalent number of looks (enl) must be larger than zero!");
934 template <
class SrcIterator,
class SrcAccessor,
class DestIterator,
class DestAccessor>
935 void operator()(SrcIterator s, SrcAccessor s_acc, DestIterator d, DestAccessor d_acc)
937 using namespace vigra;
939 SrcIterator s_ul = s - m_window_shape/2,
940 s_lr = s_ul + m_window_shape;
946 VALUETYPE C_u2 = (0.523*0.523)/m_enl,
947 C_I2 = averageAndVariance.variance() / (averageAndVariance.average()*averageAndVariance.average()),
948 W = (1.0 - C_u2/C_I2),
950 R = I * W + averageAndVariance.average() * (1 - W);
955 Diff2D windowShape()
const
957 return m_window_shape;
965 template <
class SrcIterator,
class SrcAccessor,
966 class DestIterator,
class DestAccessor>
967 void leeFilter(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
968 DestIterator d_ul, DestAccessor d_acc,
969 Diff2D window_shape,
int enl,
970 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
976 template <
class SrcIterator,
class SrcAccessor,
977 class DestIterator,
class DestAccessor>
978 void leeFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
979 pair<DestIterator, DestAccessor> d,
980 Diff2D window_shape,
int enl,
981 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
983 leeFilter(s.first, s.second, s.third,
989 template <
class T1,
class S1,
993 Diff2D window_shape,
int enl,
994 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
996 vigra_precondition(src.
shape() == dest.
shape(),
997 "vigra::leeFilter(): Shape mismatch between input and output.");
998 leeFilter(srcImageRange(src),
1095 template<
typename VALUETYPE>
1100 : m_window_shape(window_shape),
1104 using namespace vigra;
1105 vigra_precondition( k>0 && k<=1 ,
"vigra::EnhancedLeeFunctor(): Damping factor k has to be: 0 < k <= 1!");
1106 vigra_precondition( enl>0,
"vigra::EnhancedLeeFunctor(): Equivalent number of looks (enl) must be larger than zero!");
1109 template <
class SrcIterator,
class SrcAccessor,
class DestIterator,
class DestAccessor>
1110 void operator()(SrcIterator s, SrcAccessor s_acc, DestIterator d, DestAccessor d_acc)
1112 using namespace vigra;
1114 SrcIterator s_ul = s - m_window_shape/2,
1115 s_lr = s_ul + m_window_shape;
1123 VALUETYPE C_u = 0.523/
sqrt((
double)m_enl),
1124 C_max =
sqrt(1+2.0/m_enl),
1125 C_A =
sqrt(averageAndVariance.variance()) / averageAndVariance.average(),
1126 W =
exp(-m_k * (C_A - C_u)/(C_max - C_A)),
1131 d_acc.set(averageAndVariance.average(), d);
1133 else if(C_A < C_max)
1135 d_acc.set(I * W + averageAndVariance.average() * (1 - W), d);
1142 Diff2D windowShape()
const
1144 return m_window_shape;
1154 template <
class SrcIterator,
class SrcAccessor,
1155 class DestIterator,
class DestAccessor>
1156 void enhancedLeeFilter(SrcIterator s_ul, SrcIterator s_lr, SrcAccessor s_acc,
1157 DestIterator d_ul, DestAccessor d_acc,
1158 Diff2D window_shape,
float k,
int enl,
1159 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
1165 template <
class SrcIterator,
class SrcAccessor,
1166 class DestIterator,
class DestAccessor>
1167 void enhancedLeeFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
1168 pair<DestIterator, DestAccessor> d,
1169 Diff2D window_shape,
float k,
int enl,
1170 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
1172 enhancedLeeFilter(s.first, s.second, s.third,
1174 window_shape, k, enl,
1178 template <
class T1,
class S1,
1182 Diff2D window_shape,
float k,
int enl,
1183 BorderTreatmentMode border = BORDER_TREATMENT_REPEAT)
1185 vigra_precondition(src.
shape() == dest.
shape(),
1186 "vigra::enhancedLeeFilter(): Shape mismatch between input and output.");
1187 enhancedLeeFilter(srcImageRange(src),
1189 window_shape, k, enl,
1197 #endif //VIGRA_SPECKLEFILTERS_HXX
This function tries to reduce the speckle noise of an image by applying the basic Lee filter...
Definition: specklefilters.hxx:922
int y
Definition: diff2d.hxx:392
const difference_type & shape() const
Definition: multi_array.hxx:1648
linalg::TemporaryMatrix< T > exp(MultiArrayView< 2, T, C > const &v)
int x
Definition: diff2d.hxx:385
Two dimensional difference vector.
Definition: diff2d.hxx:185
This function tries to reduce the speckle noise of an image by applying the Enhanced Lee filter...
Definition: specklefilters.hxx:1096
This function tries to reduce the speckle noise of an image by applying the Gamma Maximum A Posterior...
Definition: specklefilters.hxx:566
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
This function tries to reduce the speckle noise of an image by applying the Kuan filter.
Definition: specklefilters.hxx:752
Definition: basicimage.hxx:294
Base class for, and view to, vigra::MultiArray.
Definition: multi_array.hxx:704
This function tries to reduce the speckle noise of an image by applying the Enhanced Frost filter...
Definition: specklefilters.hxx:340
Encapsulate access to the values an iterator points to.
Definition: accessor.hxx:133
void inspectImage(...)
Apply read-only functor to every pixel in the image.
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616
void applyWindowFunction(...)
Apply a window function to each pixels of a given image.
Find the average pixel value and its variance in an image or ROI.
Definition: inspectimage.hxx:1401
void frostFilter(...)
This function tries to reduce the speckle noise of an image by applying the basic Frost filter...