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