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_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH
00028 # define MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH
00029
00033
00034 # include <mln/core/image/dmorph/image_if.hh>
00035 # include <mln/core/concept/function.hh>
00036 # include <mln/core/internal/image_identity.hh>
00037 # include <mln/core/site_set/box.hh>
00038
00039 # include <mln/accu/shape/bbox.hh>
00040
00041 # include <mln/labeling/relabel.hh>
00042
00043 # include <mln/util/array.hh>
00044 # include <mln/value/next.hh>
00045
00046 # include <mln/pw/cst.hh>
00047 # include <mln/pw/value.hh>
00048
00049 # include <mln/make/relabelfun.hh>
00050
00051
00052 namespace mln
00053 {
00054
00055
00056 template <typename I, typename E>
00057 class labeled_image_base;
00058
00059
00060 namespace internal
00061 {
00062
00064 template <typename I, typename E>
00065 struct data< labeled_image_base<I,E> >
00066 {
00067 data(const I& ima, const mln_value(I)& nlabels);
00068 data(const I& ima, const mln_value(I)& nlabels,
00069 const util::array<mln_box(I)>& bboxes);
00070
00071 I ima_;
00072 mln_value(I) nlabels_;
00073 mutable util::array< box<mln_psite(I)> > bboxes_;
00074 };
00075
00076 }
00077
00078
00079
00080 namespace trait
00081 {
00082
00083 template <typename I, typename E>
00084 struct image_< labeled_image_base<I,E> > : image_< I >
00085 {
00086
00087 typedef trait::image::category::identity_morpher category;
00088 typedef mln_internal_trait_image_speed_from(I) speed;
00089 typedef trait::image::value_access::indirect value_access;
00090
00091 typedef trait::image::value_io::read_only value_io;
00092 typedef trait::image::pw_io::read pw_io;
00093
00094
00095 typedef trait::image::ext_value::multiple ext_value;
00096 typedef trait::image::ext_io::read_only ext_io;
00097 };
00098
00099 }
00100
00101
00102
00115 template <typename I, typename E>
00116 class labeled_image_base
00117 : public internal::image_identity< const I, mln_domain(I), E >
00118 {
00119 typedef internal::image_identity< const I, mln_domain(I), E >
00120 super_;
00121
00122 public:
00124 typedef mln_result(accu::shape::bbox<mln_psite(I)>) bbox_t;
00125
00129 labeled_image_base();
00131
00134
00138
00139
00140 template <typename F>
00141 void relabel(const Function_v2v<F>& f);
00142
00145 template <typename F>
00146 void relabel(const Function_v2b<F>& f);
00148
00150 mln_value(I) nlabels() const;
00151
00153 const bbox_t& bbox(const mln_value(I)& label) const;
00154
00156 const util::array<bbox_t>& bboxes() const;
00157
00159 p_if<mln_box(I),
00160 fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
00161 subdomain(const mln_value(I)& label) const;
00162
00163 protected:
00165 void update_data(const fun::i2v::array<mln_value(I)>& relabel_fun);
00166
00167 template <typename F>
00168 void relabel_(const Function_v2v<F>& f);
00169
00170 template <typename F>
00171 void relabel_(const Function_v2b<F>& f);
00172
00175 void init_update_data_();
00176 void prepare_update_data_(const mln_value(I)& lbl,
00177 const mln_value(I)& new_lbl);
00178 void update_data_(const fun::i2v::array<mln_value(I)>& relabel_fun);
00180 };
00181
00182
00183
00184
00185 # ifndef MLN_INCLUDE_ONLY
00186
00187
00188
00189
00190 namespace internal
00191 {
00192
00193
00194
00195
00196 template <typename I, typename E>
00197 inline
00198 data< labeled_image_base<I,E> >::data(const I& ima, const mln_value(I)& nlabels)
00199 : ima_(ima), nlabels_(nlabels)
00200 {
00201 }
00202
00203 template <typename I, typename E>
00204 inline
00205 data< labeled_image_base<I,E> >::data(const I& ima, const mln_value(I)& nlabels,
00206 const util::array<mln_box(I)>& bboxes)
00207 : ima_(ima), nlabels_(nlabels), bboxes_(bboxes)
00208 {
00209 }
00210
00211
00212 }
00213
00214
00215 template <typename I, typename E>
00216 inline
00217 labeled_image_base<I,E>::labeled_image_base()
00218 {
00219 }
00220
00221
00222 template <typename I, typename E>
00223 template <typename F>
00224 inline
00225 void
00226 labeled_image_base<I,E>::relabel(const Function_v2v<F>& f_)
00227 {
00228 const F& f = exact(f_);
00229 mln_value(I) new_nlabels;
00230
00231 fun::i2v::array<mln_value(I)>
00232 packed_relabel_fun = make::relabelfun(f,
00233 this->data_->nlabels_,
00234 new_nlabels);
00235
00236 labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_,
00237 packed_relabel_fun);
00238
00239 this->data_->nlabels_ = new_nlabels;
00240
00241 exact(this)->relabel_(f);
00242
00244 update_data(packed_relabel_fun);
00245 }
00246
00247
00248 template <typename I, typename E>
00249 template <typename F>
00250 inline
00251 void
00252 labeled_image_base<I,E>::relabel(const Function_v2b<F>& f_)
00253 {
00254 const F& f = exact(f_);
00255
00256
00257 typedef fun::i2v::array<mln_value(I)> fv2v_t;
00258 fv2v_t fv2v = make::relabelfun(f,
00259 this->data_->nlabels_,
00260 this->data_->nlabels_);
00261
00262 labeling::relabel_inplace(this->data_->ima_, this->data_->nlabels_, fv2v);
00263
00264 exact(this)->relabel_(f);
00265
00266
00267 update_data(fv2v);
00268 }
00269
00270 template <typename I, typename E>
00271 inline
00272 mln_value(I)
00273 labeled_image_base<I,E>::nlabels() const
00274 {
00275 return this->data_->nlabels_;
00276 }
00277
00278
00279 template <typename I, typename E>
00280 void
00281 labeled_image_base<I,E>::update_data(const fun::i2v::array<mln_value(I)>& relabel_fun)
00282 {
00283 util::array<accu::shape::bbox<mln_psite(I)> >
00284 new_bboxes(mln::value::next(this->data_->nlabels_));
00285
00286 exact(this)->init_update_data_();
00287
00288 for (unsigned i = 1; i < this->data_->bboxes_.size(); ++i)
00289 if (relabel_fun(i) != 0)
00290 {
00291 new_bboxes[relabel_fun(i)].take(this->data_->bboxes_[i]);
00292 exact(this)->prepare_update_data_(i, relabel_fun(i));
00293 }
00294
00295 convert::from_to(new_bboxes, this->data_->bboxes_);
00296
00297 mln_assertion(new_bboxes.size() == this->data_->bboxes_.size());
00298
00299 exact(this)->update_data_(relabel_fun);
00300 }
00301
00302
00303 template <typename I, typename E>
00304 const typename labeled_image_base<I,E>::bbox_t&
00305 labeled_image_base<I,E>::bbox(const mln_value(I)& label) const
00306 {
00307 return this->data_->bboxes_[label];
00308 }
00309
00310
00311 template <typename I, typename E>
00312 const util::array<typename labeled_image_base<I,E>::bbox_t>&
00313 labeled_image_base<I,E>::bboxes() const
00314 {
00315 return this->data_->bboxes_;
00316 }
00317
00318
00319 template <typename I, typename E>
00320 p_if<mln_box(I),
00321 fun::eq_v2b_expr_<pw::value_<I>, pw::cst_<mln_value(I)> > >
00322 labeled_image_base<I,E>::subdomain(const mln_value(I)& label) const
00323 {
00324 return ((this->data_->ima_ | bbox(label))
00325 | (pw::value(this->data_->ima_) == pw::cst(label))).domain();
00326 }
00327
00328
00329
00330 template <typename I, typename E>
00331 template <typename F>
00332 void
00333 labeled_image_base<I,E>::relabel_(const Function_v2v<F>& f)
00334 {
00335 (void) f;
00336
00337 }
00338
00339 template <typename I, typename E>
00340 template <typename F>
00341 void
00342 labeled_image_base<I,E>::relabel_(const Function_v2b<F>& f)
00343 {
00344 (void) f;
00345
00346 }
00347
00348 template <typename I, typename E>
00349 void
00350 labeled_image_base<I,E>::update_data_(
00351 const fun::i2v::array<mln_value(I)>& relabel_fun)
00352 {
00353 (void) relabel_fun;
00354
00355 }
00356
00357 template <typename I, typename E>
00358 void
00359 labeled_image_base<I,E>::prepare_update_data_(const mln_value(I)& lbl,
00360 const mln_value(I)& new_lbl)
00361 {
00362 (void) lbl;
00363 (void) new_lbl;
00364
00365 }
00366
00367 template <typename I, typename E>
00368 void
00369 labeled_image_base<I,E>::init_update_data_()
00370 {
00371
00372 }
00373
00374
00375 # endif // ! MLN_INCLUDE_ONLY
00376
00377 }
00378
00379
00380 #endif // ! MLN_CORE_IMAGE_IMORPH_LABELED_IMAGE_BASE_HH