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 OLENA_CONVERT_STRETCH_HH
00029 # define OLENA_CONVERT_STRETCH_HH
00030
00031 # include <mlc/type.hh>
00032
00033 # include <oln/basics.hh>
00034
00035 # include <ntg/basics.hh>
00036
00037 # include <oln/convert/abstract/conversion.hh>
00038
00039 # include <set>
00040
00041 # include <vector>
00042
00043 namespace oln {
00044
00045 namespace convert {
00046
00070 template<class Output, class Exact = mlc::final>
00071 struct stretch
00072 : public abstract::conversion_to_type<Output, typename mlc::exact_vt<stretch<Output, Exact>, Exact>::ret >
00073 {
00074 template< class Input >
00075 Output doit(const Input& v) const {
00076 return Output(ntg::cast::rbound<Output, float>
00077 (
00078 double(v - ntg_min_val(Input))
00079 / double(ntg_max_val(Input) - ntg_min_val(Input))
00080 * (ntg_max_val(Output) - ntg_min_val(Output))
00081 + ntg_min_val(Output))
00082 );
00083 }
00084
00085 static std::string
00086 name()
00087 {
00088
00089 return std::string("stretch<") + ntg_name(Output) + ", "
00090 + Exact::name() + ">";
00091 }
00092 };
00093
00164 template<class DestValue, class I>
00165 typename mute<I, DestValue>::ret
00166 stretch_balance(const oln::abstract::non_vectorial_image<I> &in,
00167 const oln_value_type(I) & min_in
00168 = ntg_min_val(oln_value_type(I)),
00169 const oln_value_type(I) & max_in
00170 = ntg_max_val(oln_value_type(I)),
00171 const DestValue & min_out = ntg_min_val(DestValue),
00172 const DestValue & max_out = ntg_max_val(DestValue))
00173 {
00174 typedef typename
00175 ntg_is_a(DestValue, ntg::non_vectorial)::ensure_type ensure_type;
00176
00177 typename mute<I, DestValue>::ret out(in.size());
00178
00179
00180 std::vector<ntg_cumul_type(DestValue)>
00181 tab(static_cast<int>(max_in - min_in + 1));
00182 typedef typename std::set<oln_value_type(I)> set_type;
00183 set_type s;
00184 oln_iter_type(I) it(in);
00185
00186 for_all(it)
00187 if (in[it] <= max_in && in[it] >= min_in)
00188 s.insert(in[it]);
00189 if (s.size() == 1)
00190 {
00191 for_all(it)
00192 out[it] = ntg_zero_val(DestValue);
00193 return out;
00194 }
00195 {
00196 unsigned cpt = 0;
00197 for (typename set_type::const_iterator it(s.begin());
00198 it != s.end(); ++it, ++cpt)
00199 tab[*it - min_in] = cpt * (max_out - min_out) / (s.size() - 1);
00200 }
00201 for_all(it)
00202 if (min_in <= in[it])
00203 {
00204 if (in[it] <= max_in)
00205 out[it] = tab[in[it] - min_in] + min_out;
00206 else
00207 out[it] = max_out;
00208 }
00209 else
00210 out[it] = min_out;
00211 return out;
00212 }
00213 }
00214
00215 }
00216
00217 #endif // OLENA_CONVERT_STRETCH_HH