00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef OLN_CONVOL_NAGAO_HXX
00029 # define OLN_CONVOL_NAGAO_HXX
00030 # include <oln/core/window2d.hh>
00031
00032 namespace oln {
00033 namespace convol {
00034 namespace internal {
00035
00036 template<class I, class SE, unsigned Size, typename Sum>
00037 inline Sum
00038 mean_of_smaller_variance(const oln::abstract::image<I> &im,
00039 const oln_point_type(I) &p,
00040 const internal::se_array<Size, SE> &w)
00041 {
00042 ntg_compare_nb_comp(Sum, oln_value_type(I))::ensure();
00043
00044 precondition(Size > 0);
00045 precondition(im.border() >= w.delta());
00046
00047 typedef typename oln::utils::se_stat<Sum, ntg::float_s> se_stat_type;
00048 typedef typename se_stat_type::sum_type sum_type;
00049 typedef typename se_stat_type::variance_type variance_type;
00050
00051 se_stat_type s(im, p, w[0]);
00052 variance_type min_variance = s.variance();
00053 sum_type mean = s.mean();
00054 for (unsigned i = 1; i < Size; ++i)
00055 {
00056 variance_type tmp = s.compute(im, p, w[i]).variance();
00057 if (tmp < min_variance)
00058 {
00059 min_variance = tmp;
00060 mean = s.mean();
00061 }
00062 }
00063 return mean;
00064 }
00065
00069 static
00070 se_array<9, window2d>
00071 mk_nagao_windows_5x5()
00072 {
00073 se_array<9, window2d> out;
00074
00075 out[0].add(-1, -1).add(-1, 0).add(-1, 1)
00076 .add(0, -1).add(0, 0).add(0, 1)
00077 .add(1, -1).add(1, 0).add(1, 1);
00078
00079
00080
00081 out[1].add(-2, -1).add(-2, 0).add(-2, 1)
00082 .add(-1, -1).add(-1, 0).add(-1, 1)
00083 .add(0, 0);
00084
00085
00086
00087 out[2].add(-1, 1).add(-1, 2)
00088 .add(0, 0).add(0, 1).add(0, 2)
00089 .add(1, 1).add(1, 2);
00090
00091
00092 out[3].add(2, -1).add(2, 0).add(2, 1)
00093 .add(1, -1).add(1, 0).add(1, 1)
00094 .add(0, 0);
00095
00096
00097
00098 out[4].add(-1, -1).add(-1, -2)
00099 .add(0, 0).add(0, -1).add(0, -2)
00100 .add(1, -1).add(1, -2);
00101
00102
00103
00104 out[5].add(-2, -2).add(-2, -1)
00105 .add(-1, -2).add(-1, -1).add(-1, 0)
00106 .add(0, -1).add(0, 0);
00107
00108
00109
00110 out[6].add(-2, 2).add(-2, 1)
00111 .add(-1, 2).add(-1, 1).add(-1, 0)
00112 .add(0, 1).add(0, 0);
00113
00114
00115
00116 out[7].add(2, 2).add(2, 1)
00117 .add(1, 2).add(1, 1).add(1, 0)
00118 .add(0, 1).add(0, 0);
00119
00120
00121
00122 out[8].add(2, -2).add(2, -1)
00123 .add(1, -2).add(1, -1).add(1, 0)
00124 .add(0, -1).add(0, 0);
00125
00126 return out;
00127 }
00128 }
00129
00130
00131 template <class I, unsigned Size, typename SE, typename Sum>
00132 inline oln_concrete_type(I)
00133 nagao_generalized(const oln::abstract::image<I>& in,
00134 const internal::se_array<Size, SE> &sa)
00135 {
00136 ntg_compare_nb_comp(Sum, oln_value_type(I))::ensure();
00137 in.border_adapt_width(sa.delta());
00138 oln_concrete_type(I) out(in.size());
00139 oln_iter_type(I) it(out);
00140 for_all(it)
00141 out[it] = internal::mean_of_smaller_variance<I, SE, Size, Sum>
00142 (in, it, sa);
00143 return out;
00144 }
00145
00166 template <class I>
00167 inline oln_concrete_type(I)
00168 nagao(const oln::abstract::non_vectorial_image_with_dim<2, I>& in)
00169 {
00170 return nagao_generalized<I, 9, window2d, ntg::float_s>
00171 (in, internal::mk_nagao_windows_5x5());
00172 }
00173
00194 template <class I>
00195 inline oln_concrete_type(I)
00196 nagao(const oln::abstract::vectorial_image_with_dim<2, I>& in)
00197 {
00198 typedef ntg::rgb_8::float_vec_type float_vec_type;
00199 return nagao_generalized<I, 9, window2d, float_vec_type>
00200 (in, internal::mk_nagao_windows_5x5());
00201 }
00202 }
00203 }
00204
00205 #endif