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 #ifndef MLN_MORPHO_ATTRIBUTE_SHARPNESS_HH
00027 # define MLN_MORPHO_ATTRIBUTE_SHARPNESS_HH
00028
00033
00034 # include <mln/core/concept/accumulator.hh>
00035 # include <mln/accu/internal/base.hh>
00036 # include <mln/morpho/attribute/volume.hh>
00037 # include <mln/morpho/attribute/height.hh>
00038
00039
00040 namespace mln
00041 {
00042
00043
00044 namespace morpho {
00045 namespace attribute {
00046 template <typename I>
00047 class sharpness;
00048 }
00049 }
00050
00051
00052
00053
00054 namespace trait
00055 {
00056
00057 template <typename I>
00058 struct accumulator_< morpho::attribute::sharpness<I> >
00059 {
00060 typedef accumulator::has_untake::no has_untake;
00061 typedef accumulator::has_set_value::no has_set_value;
00062 typedef accumulator::has_stop::no has_stop;
00063 typedef accumulator::when_pix::use_v when_pix;
00064 };
00065
00066 }
00067
00068
00069 namespace morpho
00070 {
00071
00072 namespace attribute
00073 {
00074
00079 template <typename I>
00080 struct sharpness
00081 : public mln::accu::internal::base< double, sharpness<I> >
00082 {
00083 typedef mln_value(I) argument;
00084
00085 sharpness();
00086
00089 void init();
00090
00091 void take(const mln_value(I)& v);
00092 void take(const sharpness<I>& other);
00093
00094 void take_as_init_(const mln_value(I)& v);
00096
00098 double to_result() const;
00099
00102 bool is_valid() const;
00103
00105 unsigned area() const;
00106
00108 unsigned height() const;
00109
00111 unsigned volume() const;
00112
00113 protected:
00115 typename mln::morpho::attribute::height<I> height_;
00117 typename mln::morpho::attribute::volume<I> volume_;
00118 };
00119
00120
00121
00122 # ifndef MLN_INCLUDE_ONLY
00123
00124 template <typename I>
00125 inline
00126 sharpness<I>::sharpness()
00127 {
00128 init();
00129 }
00130
00131 template <typename I>
00132 inline
00133 void
00134 sharpness<I>::init()
00135 {
00136 volume_.init();
00137 }
00138
00139 template <typename I>
00140 inline
00141 void
00142 sharpness<I>::take(const mln_value(I)& v)
00143 {
00144 if (! is_valid())
00145 {
00146 take_as_init_(v);
00147 return;
00148 }
00149 volume_.take(v);
00150 height_.take(v);
00151 }
00152
00153 template <typename I>
00154 inline
00155 void
00156 sharpness<I>::take(const sharpness<I>& other)
00157 {
00158 mln_invariant(is_valid());
00159 volume_.take(other.volume_);
00160 height_.take(other.height_);
00161 }
00162
00163 template <typename I>
00164 inline
00165 void
00166 sharpness<I>::take_as_init_(const mln_value(I)& v)
00167 {
00168 volume_.take_as_init_(v);
00169 height_.take_as_init_(v);
00170 }
00171
00172 template <typename I>
00173 inline
00174 double
00175 sharpness<I>::to_result() const
00176 {
00177 double d = 0;
00178 if (height_.to_result() != 0)
00179 {
00180 d = (double) volume_.to_result() /
00181 (double)((volume_.area() - 1) * (height_.to_result() + 1) + 1);
00182 }
00183 mln_postcondition(d >= 0 && d <= 1);
00184 return d;
00185 }
00186
00187 template <typename I>
00188 inline
00189 unsigned
00190 sharpness<I>::area() const
00191 {
00192 return volume_.area();
00193 }
00194
00195 template <typename I>
00196 inline
00197 unsigned
00198 sharpness<I>::volume() const
00199 {
00200 return volume_.to_result();
00201 }
00202
00203 template <typename I>
00204 inline
00205 unsigned
00206 sharpness<I>::height() const
00207 {
00208 return height_.to_result();
00209 }
00210
00211 template <typename I>
00212 inline
00213 bool
00214 sharpness<I>::is_valid() const
00215 {
00216 return volume_.is_valid() && height_.is_valid();
00217 }
00218
00219 # endif // ! MLN_INCLUDE_ONLY
00220
00221 }
00222
00223 }
00224
00225 }
00226
00227
00228 #endif // ! MLN_MORPHO_ATTRIBUTE_SHARPNESS_HH