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_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH
00027 # define MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH
00028
00032
00033 # include <mln/core/image/dmorph/image_if.hh>
00034 # include <mln/core/concept/function.hh>
00035 # include <mln/core/internal/image_identity.hh>
00036 # include <mln/core/site_set/box.hh>
00037
00038 # include <mln/accu/pair.hh>
00039 # include <mln/accu/nil.hh>
00040 # include <mln/accu/center.hh>
00041
00042 # include <mln/labeling/compute.hh>
00043 # include <mln/labeling/pack.hh>
00044 # include <mln/labeling/relabel.hh>
00045
00046 # include <mln/util/array.hh>
00047
00048 # include <mln/pw/cst.hh>
00049 # include <mln/pw/value.hh>
00050
00051 # ifndef NDEBUG
00052 # include <mln/accu/stat/max.hh>
00053 # include <mln/data/compute.hh>
00054 # endif // ! NDEBUG
00055
00056
00057 namespace mln
00058 {
00059
00060
00061 template <typename I> struct labeled_image;
00062 namespace accu
00063 {
00064 template <typename T> struct nil;
00065 template <typename T> struct bbox;
00066 }
00067
00068
00069 namespace internal
00070 {
00071
00073 template <typename I>
00074 struct data< labeled_image<I> >
00075 {
00076 data(const I& ima, const mln_value(I)& nlabels);
00077
00078 I ima_;
00079 mln_value(I) nlabels_;
00080 mutable util::array< box<mln_psite(I)> > bboxes_;
00081 };
00082
00083 }
00084
00085
00086 namespace trait
00087 {
00088
00089 template <typename I>
00090 struct image_< labeled_image<I> > : image_< I >
00091 {
00092
00093 typedef trait::image::category::identity_morpher category;
00094 typedef mln_internal_trait_image_speed_from(I) speed;
00095 typedef trait::image::value_access::indirect value_access;
00096
00097 typedef trait::image::value_io::read_only value_io;
00098 typedef trait::image::pw_io::read pw_io;
00099
00100
00101 typedef trait::image::ext_value::multiple ext_value;
00102 typedef trait::image::ext_io::read_only ext_io;
00103 };
00104
00105 }
00106
00107
00108
00120
00121 template <typename I>
00122 class labeled_image
00123 : public internal::image_identity< const I, mln_domain(I), labeled_image<I> >
00124 {
00125 typedef internal::image_identity< const I, mln_domain(I), labeled_image<I> >
00126 super_;
00127
00128 public:
00129
00131 typedef labeled_image< tag::image_<I> > skeleton;
00132
00134 typedef mln_result(accu::shape::bbox<mln_psite(I)>) bbox_t;
00135
00139 labeled_image();
00140
00142 labeled_image(const I& ima, const mln_value(I)& nlabels);
00144
00147 void init_(const I& ima, const mln_value(I)& nlabels);
00148
00150 void init_from_(const labeled_image<I>& model);
00151
00154
00160 template <typename F>
00161 void relabel(const Function_v2v<F>& f);
00162
00165 template <typename F>
00166 void relabel(const Function_v2b<F>& f);
00168
00170 void pack_();
00171
00173 mln_value(I) nlabels() const;
00174
00176 void update_();
00177
00179 const bbox_t& bbox(const mln_value(I)& label) const;
00180
00182 const util::array<bbox_t>& bboxes() const;
00183
00185 p_if<mln_box(I),
00186 fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
00187 subdomain(const mln_value(I)& label) const;
00188 };
00189
00190
00191
00192
00193
00194
00195 template <typename I, typename J>
00196 void init_(tag::image_t, labeled_image<I>& target,
00197 const labeled_image<J>& model);
00198
00199
00200
00201 namespace make
00202 {
00203
00204 template <typename I>
00205 mln::labeled_image<I>
00206 labeled_image(const Image<I>& ima, const mln_value(I)& nlabels);
00207
00208 }
00209
00210
00211
00212
00213 # ifndef MLN_INCLUDE_ONLY
00214
00215
00216
00217
00218 namespace internal
00219 {
00220
00221
00222
00223
00224 template <typename I>
00225 inline
00226 data< labeled_image<I> >::data(const I& ima, const mln_value(I)& nlabels)
00227 : ima_(ima), nlabels_(nlabels)
00228 {
00229 }
00230
00231 }
00232
00233
00234 template <typename I>
00235 inline
00236 labeled_image<I>::labeled_image()
00237 {
00238 }
00239
00240 template <typename I>
00241 inline
00242 labeled_image<I>::labeled_image(const I& ima, const mln_value(I)& nlabels)
00243 {
00244 init_(ima, nlabels);
00245 }
00246
00247 template <typename I>
00248 inline
00249 void
00250 labeled_image<I>::init_(const I& ima, const mln_value(I)& nlabels)
00251 {
00252 mln_precondition(data::compute(accu::meta::stat::max(), ima) == nlabels);
00253 this->data_ = new internal::data< labeled_image<I> >(ima, nlabels);
00254 this->update_();
00255 }
00256
00257 template <typename I>
00258 inline
00259 void
00260 labeled_image<I>::init_from_(const labeled_image<I>& model)
00261 {
00262 this->data_
00263 = new internal::data< labeled_image<I> >(duplicate(model.hook_data_()->ima_),
00264 model.nlabels());
00265 this->data_->bboxes_ = model.hook_data_()->bboxes_;
00266 }
00267
00268 template <typename I>
00269 template <typename F>
00270 inline
00271 void
00272 labeled_image<I>::relabel(const Function_v2v<F>& f_)
00273 {
00274 const F& f = exact(f_);
00275 labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_, f);
00276
00280 pack_();
00281
00284 this->update_();
00285 }
00286
00287 template <typename I>
00288 template <typename F>
00289 inline
00290 void
00291 labeled_image<I>::relabel(const Function_v2b<F>& f_)
00292 {
00293 const F& f = exact(f_);
00294 labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_, f);
00295
00298 this->update_();
00299 }
00300
00301 template <typename I>
00302 inline
00303 void
00304 labeled_image<I>::pack_()
00305 {
00306 labeling::pack_inplace(this->data_->ima_, this->data_->nlabels_);
00307
00310 this->update_();
00311 }
00312
00313
00314 template <typename I>
00315 inline
00316 mln_value(I)
00317 labeled_image<I>::nlabels() const
00318 {
00319 return this->data_->nlabels_;
00320 }
00321
00322
00323
00324
00325 template <typename I, typename J>
00326 void init_(tag::image_t, labeled_image<I>& target,
00327 const labeled_image<J>& model)
00328 {
00329 I ima;
00330 init_(tag::image, ima, model);
00331 target.init_(ima, model.nlabels());
00332 }
00333
00334
00335 template <typename I>
00336 void
00337 labeled_image<I>::update_()
00338 {
00339 this->data_->bboxes_ = labeling::compute(accu::meta::shape::bbox(),
00340 this->data_->ima_,
00341 this->data_->nlabels_);
00342 }
00343
00344
00345 template <typename I>
00346 const typename labeled_image<I>::bbox_t&
00347 labeled_image<I>::bbox(const mln_value(I)& label) const
00348 {
00349 return this->data_->bboxes_[label];
00350 }
00351
00352
00353 template <typename I>
00354 const util::array<typename labeled_image<I>::bbox_t>&
00355 labeled_image<I>::bboxes() const
00356 {
00357 return this->data_->bboxes_;
00358 }
00359
00360
00361 template <typename I>
00362 p_if<mln_box(I),
00363 fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
00364 labeled_image<I>::subdomain(const mln_value(I)& label) const
00365 {
00366 return ((this->data_->ima_ | bbox(label))
00367 | (pw::value(this->data_->ima_) == pw::cst(label))).domain();
00368 }
00369
00370
00371
00372
00373 namespace make
00374 {
00375
00376 template <typename I>
00377 mln::labeled_image<I>
00378 labeled_image(const Image<I>& ima, const mln_value(I)& nlabels)
00379 {
00380 mln_precondition(exact(ima).is_valid());
00381 mln::labeled_image<I> tmp(exact(ima), nlabels);
00382 return tmp;
00383 }
00384
00385 }
00386
00387
00388 # endif // ! MLN_INCLUDE_ONLY
00389
00390 }
00391
00392
00393 #endif // ! MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_HH