* mln/binarization/tmms.hh,
* mln/binarization/tmms_hysteresis.hh: Here.
---
milena/mln/binarization/tmms.hh | 139 ++++++++++++
milena/mln/binarization/tmms_hysteresis.hh | 319 ++++++++++++++++++++++++++++
2 files changed, 458 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/binarization/tmms.hh
create mode 100644 milena/mln/binarization/tmms_hysteresis.hh
diff --git a/milena/mln/binarization/tmms.hh b/milena/mln/binarization/tmms.hh
new file mode 100644
index 0000000..5d177dc
--- /dev/null
+++ b/milena/mln/binarization/tmms.hh
@@ -0,0 +1,139 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_BINARIZATION_TMMS_HH
+# define MLN_BINARIZATION_TMMS_HH
+
+# include <mln/morpho/all.hh>
+# include <mln/labeling/values.hh>
+
+
+/// \file
+///
+/// \brief Binarization using TMMS algorithm (see "Text Segmentation
+/// in Natural Scenes Using Toggle-Mapping" from icip09 for more
+/// details).
+
+
+namespace mln
+{
+
+ namespace binarization
+ {
+
+ /**
+ Binarize \p in_image by the use of TMMS algorithm (see "Text
+ Segmentation in Natural Scenes Using Toggle-Mapping" from icip09
+ for more details).
+ \tparam image_in_ the input image (not modified by the algorithm.
+
+ \tparam struct_element the structuring element used to compute
+ erosion and dilation of input image (During TMMS algorithm, input
+ image is mapped over two fuctions: an erosion and a dilation of
+ the input image).
+
+ \param c_min the min contrast allowed to extract feature.
+
+ \return an image with "foreground" marked with the highest
+ possible color (hc), the "background" marked with the lower
+ possible color (lc) and homogeneous regions of the image marked
+ with the color (hc+lc)/2. (This will fail with two colors images,
+ but it seems to be a bit stupid to try to binarize two color
+ images?)
+
+ \author J. Fabrizio
+ */
+ template<typename I, typename W>
+ mln_concrete(I)
+ tmms(const Image<I>& in_image_, const Window<W>& struct_element,
+ const mln_value(I)& c_min, const mln_value(I)& min_level,
+ const mln_value(I)& med_level, const mln_value(I)& max_level,
+ int pourcent);
+
+ template<typename I, typename W>
+ mln_concrete(I)
+ tmms(const Image<I>& in_image_, const Window<W>& struct_element,
+ const mln_value(I)& c_min);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template<typename I, typename W>
+ mln_concrete(I)
+ tmms(const Image<I>& in_image_, const Window<W>& struct_element,
+ const mln_value(I)& c_min, const mln_value(I)& min_level,
+ const mln_value(I)& med_level, const mln_value(I)& max_level,
+ int pourcent)
+ {
+ mln_trace("binarization::tmms");
+
+ const I& in_image = exact(in_image_);
+ mln_concrete(I) out_image;
+
+ mln_concrete(I) dilation = mln::morpho::dilation(in_image, struct_element);
+ mln_concrete(I) erosion = mln::morpho::erosion(in_image, struct_element);
+
+ typedef mln_value(I) V;
+ //V min_level = mln_min(V); //background
+ //V max_level = mln_max(V); //foreground
+ //V med_level = (max_level + min_level) / 2; //homogeneous
+
+ mln_piter(I) p(in_image.domain());
+
+ initialize(out_image, in_image);
+ for_all(p)
+ {
+ V dil = dilation(p); // by def : dil>=ima>=ero
+ V ero = erosion(p);
+ V ima = in_image(p);
+ out_image(p) = ( (V)(dil - ero) >= c_min)?
+ ( ((dil - ima) < pourcent*(dil - ero)/100) ? max_level : min_level ) :
med_level;
+ }
+
+ return out_image;
+ }
+
+ template<typename I, typename W>
+ mln_concrete(I)
+ tmms(const Image<I>& in_image_, const Window<W>& struct_element,
+ const mln_value(I)& c_min)
+ {
+ typedef mln_value(I) V;
+ V min_level = mln_min(V); //background
+ V max_level = mln_max(V); //foreground
+ V med_level = (max_level + min_level) / 2; //homogeneous
+ return tmms(in_image_, struct_element, c_min,
+ min_level, med_level, max_level, 50);
+ }
+
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::binarization
+
+
+} // end of namespace mln
+
+#endif // ! MLN_BINARIZATION_TMMS_HH
diff --git a/milena/mln/binarization/tmms_hysteresis.hh
b/milena/mln/binarization/tmms_hysteresis.hh
new file mode 100644
index 0000000..39bea97
--- /dev/null
+++ b/milena/mln/binarization/tmms_hysteresis.hh
@@ -0,0 +1,319 @@
+// Copyright (C) 2013 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_BINARIZATION_TMMS_HH
+# define MLN_BINARIZATION_TMMS_HH
+
+# include <mln/morpho/all.hh>
+# include <mln/labeling/values.hh>
+
+
+/// \file
+///
+/// \brief Binarization using TMMS algorithm (see "Text Segmentation
+/// in Natural Scenes Using Toggle-Mapping" from icip09 for more
+/// details) combined with hysteresis.
+
+
+namespace mln
+{
+
+ namespace binarization
+ {
+
+ /**
+ Binarize \p in_image by the use of TMMS algorithm (see "Text
+ Segmentation in Natural Scenes Using Toggle-Mapping" from icip09
+ for more details).
+ \tparam image_in_ the input image (not modified by the algorithm.
+
+ \tparam struct_element the structuring element used to compute
+ erosion and dilation of input image (During TMMS algorithm, input
+ image is mapped over two fuctions: an erosion and a dilation of
+ the input image).
+
+ \param c_min the min contrast allowed to extract feature.
+
+ \return an image with "foreground" marked with the highest
+ possible color (hc), the "background" marked with the lower
+ possible color (lc) and homogeneous regions of the image marked
+ with the color (hc+lc)/2. (This will fail with two colors images,
+ but it seems to be a bit stupid to try to binarize two color
+ images?)
+
+ \author J. Fabrizio
+ */
+
+ mln_concrete(I)
+ tmms_hysteresis(const Image<I>& in_image_, const Window<W>&
struct_element,
+ const mln_value(I)& c_min_low, const mln_value(I)& c_min_high,
+ const mln_value(I)& min_level,
+ const mln_value(I)& med_level,
+ const mln_value(I)& max_level,
+ const int pourcent);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template<typename I, typename W>
+ mln_concrete(I)
+ tmms_hysteresis(const Image<I>& in_image_, const Window<W>&
struct_element,
+ const mln_value(I)& c_min_low, const mln_value(I)& c_min_high,
+ const mln_value(I)& min_level,
+ const mln_value(I)& med_level,
+ const mln_value(I)& max_level,
+ const int pourcent)
+ {
+ mln_trace("binarization::tmms");
+
+ const I& in_image = exact(in_image_);
+
+ mln_concrete(I) low_image;
+ mln_concrete(I) high_image;
+
+ mln_concrete(I) dilation = mln::morpho::dilation(in_image, struct_element);
+ mln_concrete(I) erosion = mln::morpho::erosion(in_image, struct_element);
+
+ unsigned int nlabels;
+
+ mln_piter(I) p(in_image.domain());
+
+ initialize(low_image, in_image);
+ initialize(high_image, in_image);
+
+ typedef mln_value(I) V;
+ for_all(p)
+ {
+ V dil = dilation(p); // by def : dil>=ima>=ero
+ V ero = erosion(p);
+ V ima = in_image(p);
+
+ if ((V)(dil - ero)<c_min_low) low_image(p) = high_image(p) = med_level;
+ else if ((V)(dil - ero)<c_min_high) {
+ low_image(p) = med_level;
+ if ( (V)(dil - ima) < pourcent*((V)(dil - ero))/100 )
+ high_image(p) = max_level;
+ else
+ high_image(p) = min_level;
+ } else {
+ if ( (V)(dil - ima) < pourcent*((V)(dil - ero))/100 )
+ low_image(p) = high_image(p) = max_level;
+ else
+ low_image(p) = high_image(p) = min_level;
+ }
+
+ }
+
+ mln_ch_value(I, unsigned int) labels_high_images;
+ labels_high_images = mln::labeling::values(high_image,
+ mln::c4(), nlabels);
+ V *values = new V[nlabels];
+
+ for(unsigned int i=0;i<nlabels;i++) {
+ values[i]=med_level;
+ }
+
+ for_all(p) {
+ if (low_image(p)!=med_level) {
+ values[labels_high_images(p)]=low_image(p);
+ }
+ }
+
+ for_all(p) {
+ if (low_image(p)==med_level) {
+ low_image(p)=values[labels_high_images(p)];
+ }
+ }
+ delete(values);
+
+ return low_image;
+ }
+
+ } // end of namespace mln::binarization::impl::generic
+
+ template<typename I, typename W>
+ mln_concrete(I)
+ tmms_hysteresis(const Image<I>& in_image_, const Window<W>&
struct_element,
+ const mln_value(I)& c_min_low, const mln_value(I)& c_min_high,
+ const mln_value(I)& min_level,
+ const mln_value(I)& med_level,
+ const mln_value(I)& max_level,
+ const int pourcent)
+ {
+ mln_trace("binarization::tmms");
+
+ const I& in_image = exact(in_image_);
+
+ mln_concrete(I) low_image;
+ mln_concrete(I) high_image;
+
+ mln_concrete(I) dilation = mln::morpho::dilation(in_image, struct_element);
+ mln_concrete(I) erosion = mln::morpho::erosion(in_image, struct_element);
+
+ unsigned int nlabels;
+
+ initialize(low_image, in_image);
+ initialize(high_image, in_image);
+ border::resize(dilation, in_image.border());
+ border::resize(erosion, in_image.border());
+
+ if (in_image.border()!=dilation.border() ||
+ in_image.border()!=erosion.border())
+ {
+ std::abort();
+ }
+
+ typedef mln_value(I) V;
+
+ unsigned nrows = geom::nrows(in_image);
+ unsigned ncols = geom::ncols(in_image);
+ for (row = 0; row < nrows; row += 1)
+ {
+ V *p_in_image=&(in_image.at_(row, 0));
+ V *p_dilation=&(dilation.at_(row, 0)));
+ V *p_erosion=&(erosion.at_(row, 0));
+ V *p_low_image=&(low_image.at_(row, 0));
+ V *p_high_image=&(high_image.at_(row, 0));
+
+ for (unsigned col = 0; col < ncols; col += 1)
+
+ {
+ V dil = *p_dilation; // by def : dil>=ima>=ero
+ V ero = *p_erosion;
+ V ima = *p_in_image;
+
+ if ((V)(dil - ero)<c_min_low) (*p_low_image) = (*p_high_image) =
med_level;
+ else if ((V)(dil - ero)<c_min_high) {
+ (*p_low_image) = med_level;
+ if ( (V)(dil - ima) < pourcent*((V)(dil - ero))/100 )
+ (*p_high_image) = max_level;
+ else
+ (*p_high_image) = min_level;
+ } else {
+ if ( (V)(dil - ima) < pourcent*((V)(dil - ero))/100 )
+ (*p_low_image) = (*p_high_image) = max_level;
+ else
+ (*p_low_image) = (*p_high_image) = min_level;
+ }
+ }
+
+ mln_ch_value(I, unsigned int) labels_high_images;
+ labels_high_images = mln::labeling::values(high_image,
+ mln::c4(), nlabels);
+ V *values = new V[nlabels];
+
+ for(unsigned int i=0;i<nlabels;i++) {
+ values[i]=med_level;
+ }
+
+ mln_piter(I) p(in_image.domain());
+ for_all(p) {
+ if (low_image(p)!=med_level) {
+ values[labels_high_images(p)]=low_image(p);
+ }
+ }
+
+ for_all(p) {
+ if (low_image(p)==med_level) {
+ low_image(p)=values[labels_high_images(p)];
+ }
+ }
+ delete(values);
+
+ return low_image;
+ }
+
+ }// end of namespace mln::binarization::impl
+
+ namespace internal
+ {
+
+ template<typename I, typename W>
+ mln_concrete(I)
+ tmms_hysteresis_dispatch(const I& ima, const W& struct_element,
+ const I& c_min_low, const I& c_min_high,
+ const I& min_level, const I& med_level, const I& max_level,
+ const int pourcent, mln::trait::image::speed::any)
+ {
+ return mnl::binarization::impl::generic::tmms_hysteresis(ima,
+ struct_element, c_min_low, c_min_high,
+ min_level, med_level, max_level, pourcent);
+ }
+
+ template<typename I, typename W>
+ mln_concrete(I)
+ tmms_hysteresis_dispatch(const I& ima, const W& struct_element,
+ const I& c_min_low, const I& c_min_high,
+ const I& min_level, const I& med_level, const I& max_level,
+ const int pourcent, mln::trait::image::speed::fastest)
+ {
+ return mln::binarization::impl::tmms_hysteresis_fastest(ima,
+ struct_element, c_min_low, c_min_high,
+ min_level, med_level, max_level, pourcent);
+ }
+
+ template<typename I, typename W>
+ mln_concrete(I)
+ tmms_dispatch(const I& ima, const W& struct_element,
+ const I& c_min_low, const I& c_min_high,
+ const I& min_level, const I& med_level, const I&
max_level,
+ const int pourcent)
+ {
+ return tmms_hysteresis_dispatch(ima,
+ struct_element, c_min_low, c_min_high,
+ min_level, med_level, max_level, pourcent,
+ mln_trait_image_speed(I));
+ }
+
+ } //end of namespace internal
+
+ template<typename I, typename W>
+ mln_concrete(I)
+ tmms(const Image<I>& in_image_, const Window<W>& struct_element,
+ const mln_value(I)& c_min_low, const mln_value(I)& c_min_high,
+ const mln_value(I)& min_level,
+ const mln_value(I)& med_level,
+ const mln_value(I)& max_level,
+ const int pourcent)
+ {
+ const I& ima = exact(in_image_);
+ const W& win = exact(struct_element);
+ return mln::binarization::internal::tmms_hysteresis_displatch(ima,
+ win, min_level, med_level, max_level, pourcent);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::binarization
+
+
+} // end of namespace mln
+
+#endif // ! MLN_BINARIZATION_TMMS_HH
--
1.7.2.5