3489: Fix level::stretch and value::lut_vec.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Fix level::stretch and value::lut_vec. * mln/level/transform.spe.hh: Upgrade file doc style. * mln/fun/v2v/linear.hh (linear_sat): New. It is very useful so that we can use both the linear effect while being restricted by the destination interval. Consider int_u12 -> int_u8. When data are in [0,512[, the linear conversion function is a div 2. Yet applying this function on an image can use a LUT computed from 0 to 2^12; unfortunately a "linear-not-saturating" function yields to value overflows, e.g., for 1000. * mln/level/stretch.hh (min_, max_): Fix missing update. (f): Use linear_sat instead of linear. * mln/value/lut_vec.hh (lut_vec): Fix ctor. (operator<<): New. fun/v2v/linear.hh | 57 +++++++++++++++++++++++++++++++++++++++++++++++-- level/stretch.hh | 6 ++--- level/transform.spe.hh | 5 ++-- value/lut_vec.hh | 31 +++++++++++++++++++++----- 4 files changed, 86 insertions(+), 13 deletions(-) Index: mln/level/transform.spe.hh --- mln/level/transform.spe.hh (revision 3488) +++ mln/level/transform.spe.hh (working copy) @@ -1,5 +1,5 @@ -// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory -// (LRDE) +// Copyright (C) 2007, 2008, 2009 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -274,6 +274,7 @@ return output; } + template <typename I1, typename I2, typename F> mln_ch_value(I1, mln_result(F)) transform_fastest(const Image<I1>& input1_, const Image<I2>& input2_, Index: mln/level/stretch.hh --- mln/level/stretch.hh (revision 3488) +++ mln/level/stretch.hh (working copy) @@ -89,14 +89,14 @@ //FIXME: we would like to use float instead of double but we //can't for precision reasons. See ticket #179. double - min = float(min_), - max = float(max_), + min = double(min_), + max = double(max_), epsilon = mln_epsilon(float), M = mln_max(V) + 0.5f - epsilon, m = 0.0f - 0.5f + epsilon, a = (M - m) / (max - min), b = (m * max - M * min) / (max - min); - fun::v2v::linear<double, double, V> f(a, b); + fun::v2v::linear_sat<mln_value(I), double, V> f(a, b); output = level::transform(input, f); } else Index: mln/value/lut_vec.hh --- mln/value/lut_vec.hh (revision 3488) +++ mln/value/lut_vec.hh (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2009 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -28,10 +29,11 @@ #ifndef MLN_VALUE_LUT_VEC_HH # define MLN_VALUE_LUT_VEC_HH -/*! \file mln/value/lut_vec.hh - * - * \brief Define some basic lut_vecs of values from value types. - */ +/// \file mln/value/lut_vec.hh +/// +/// Define some basic lut_vecs of values from value types. +/// +/// \todo Use fun::saturate in lut_vec ctor. # include <vector> @@ -96,6 +98,10 @@ }; + template <typename S, typename T> + std::ostream& + operator<<(std::ostream& ostr, const lut_vec<S,T>& lut); + # ifndef MLN_INCLUDE_ONLY @@ -127,7 +133,7 @@ n_ = vset.nvalues(); vec_.reserve(n_); for (unsigned i = 0; i < n_; ++i) - vec_[i] = f_(vset[i]); + vec_.push_back(f_(vset[i])); } template <typename S, typename T> @@ -156,6 +162,19 @@ return vec_.size(); } + + template <typename S, typename T> + inline + std::ostream& + operator<<(std::ostream& ostr, const lut_vec<S,T>& lut) + { + ostr << "[ "; + for (unsigned i = 0; i < lut.nvalues(); ++i) + ostr << i << ':' << lut[i] << ' '; + ostr << ']'; + return ostr; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::value Index: mln/fun/v2v/linear.hh --- mln/fun/v2v/linear.hh (revision 3488) +++ mln/fun/v2v/linear.hh (working copy) @@ -1,5 +1,5 @@ -// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory -// (LRDE) +// Copyright (C) 2007, 2008, 2009 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -69,8 +69,26 @@ }; + template <typename V, typename T = V, typename R = T> + struct linear_sat : public Function_v2v< linear_sat<V,T,R> > + { + typedef R result; + + R operator()(const V& v) const; + + template <typename U> + R operator()(const U& u) const; + + linear_sat(T a, T b); + T a, b; + }; + + # ifndef MLN_INCLUDE_ONLY + + // linear. + template <typename V, typename T, typename R> inline linear<V,T,R>::linear(T a, T b) @@ -96,6 +114,41 @@ return this->operator()(static_cast<V>(u)); } + + // linear_sat. + + template <typename V, typename T, typename R> + inline + linear_sat<V,T,R>::linear_sat(T a, T b) + : a(a), + b(b) + { + } + + template <typename V, typename T, typename R> + inline + R + linear_sat<V,T,R>::operator()(const V& v) const + { + T res = a * static_cast<T>(v) + b; + if (res > mln_max(R)) + res = mln_max(R); + else if (res < mln_min(R)) + res = mln_min(R); + return mln::convert::to<R>(res); + } + + template <typename V, typename T, typename R> + template <typename U> + inline + R + linear_sat<V,T,R>::operator()(const U& u) const + { + mlc_converts_to(U, V)::check(); + return this->operator()(static_cast<V>(u)); + } + + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::fun::v2v
participants (1)
-
Thierry Geraud