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