Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
February 2008
- 12 participants
- 70 discussions
#127: Generalize the definition of the Sobel gradient
-------------------------+--------------------------------------------------
Reporter: levill_r | Owner: Olena Team
Type: enhancement | Status: new
Priority: trivial | Milestone:
Component: Milena | Version: 1.0
Keywords: |
-------------------------+--------------------------------------------------
For the moment (rev. 1656), the Sobel gradient only works on 2-D images.
We could generalize its definition to n-D (regular) images. For instance,
a 3-D version is mentioned in
http://www.aravind.ca/cs788h_Final_Project/gradient_estimators.htm.
--
Ticket URL: <https://trac.lrde.org/olena/ticket/127>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image library.
1
1
#135: Name Confilts between util::node and util::node.
-----------------------+----------------------------------------------------
Reporter: garrigues | Owner: Olena Team
Type: defect | Status: new
Priority: major | Milestone: Olena 1.0ß
Component: Milena | Version: 1.0
Keywords: |
-----------------------+----------------------------------------------------
We have two util::node : one for the graph implementation and also one for
the tree.
see source:/trunk/milena/mln/util/tree.hh and
source:/trunk/milena/mln/util/internal/graph_base.hh
--
Ticket URL: <https://trac.lrde.org/olena/ticket/135>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
1
4
[Olena] #123: Revamp general graph-based images (aka badly named « mesh images »)
by Olena 09 Apr '08
by Olena 09 Apr '08
09 Apr '08
#123: Revamp general graph-based images (aka badly named « mesh images »)
----------------------+-----------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: task | Status: new
Priority: major | Milestone: Olena 1.0ß
Component: Milena | Version: 1.0
Keywords: |
----------------------+-----------------------------------------------------
For starters,
* Use `graph_based` prefix instead of `mesh`.
* Improve the graph structure; possibly provide a BGL-based version of
the graph-based image.
Then later:
* Create a « add_neighborhood » morpher, and adjust window-based morpho
algorithms so that they can work on images with neighborhoods.
* Rename « mesh elementary window » as « graph elementary neighborhood »
(or adjacency? Check formal definitions to choose the right term.).
* Revamp this elementary neighborhood too (currently, the graph-based
piters ignore them, and assume they always work on elementary
neighborhoods).
These latest tasks might deserve their own ticket, as their scope is
beyond graph-based images.
--
Ticket URL: <https://trac.lrde.org/olena/ticket/123>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image library.
1
7
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
sandbox:Subsampling function.
* sandbox/jardonnet/subsampling: New.
* sandbox/jardonnet/subsampling/subsampling_2d.hh: Subsamples 2d image.
* sandbox/jardonnet/subsampling/sub_sampled_image.hh: Draft morpher.
* sandbox/jardonnet/test: New temporary test directory.
* sandbox/jardonnet/test/test.cc: Base.
* sandbox/jardonnet/test/subsampling.cc: Subsampling test.
* sandbox/jardonnet/test/Makefile: New.
* tests/subsampling: New.
* tests/subsampling/type.cc: New.
mln/binarization/binarization.hh | 2
sandbox/jardonnet/subsampling/sub_sampled_image.hh | 226 +++++++++++++++++++++
sandbox/jardonnet/subsampling/subsampling_2d.hh | 117 ++++++++++
sandbox/jardonnet/test/Makefile | 8
sandbox/jardonnet/test/subsampling.cc | 22 ++
sandbox/jardonnet/test/test.cc | 12 +
tests/binarization/thresholding.cc | 2
tests/subsampling/type.cc | 15 +
8 files changed, 403 insertions(+), 1 deletion(-)
Index: tests/subsampling/type.cc
--- tests/subsampling/type.cc (revision 0)
+++ tests/subsampling/type.cc (revision 0)
@@ -0,0 +1,15 @@
+#include <mln/core/image2d.hh>
+#include <mln/core/sub_sampled_image.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ typedef image2d<int_u8> I;
+
+ I input;
+ sub_sampled_image<I> sima(input, point2d(1,1), 2);
+
+}
Index: tests/binarization/thresholding.cc
--- tests/binarization/thresholding.cc (revision 1757)
+++ tests/binarization/thresholding.cc (working copy)
@@ -30,6 +30,8 @@
* \brief Test on mln::binarization::thresholding
*/
+// FIXME for make check
+
#include <mln/core/image2d.hh>
#include <mln/binarization/thresholding.hh>
Index: mln/binarization/binarization.hh
--- mln/binarization/binarization.hh (revision 1757)
+++ mln/binarization/binarization.hh (working copy)
@@ -103,4 +103,4 @@
} // end of namespace mln
-#endif // ! MLN_BINARIZATION_THRESHOLDING_HH
+#endif // ! MLN_BINARIZATION_BINARIZATION_HH
Index: sandbox/jardonnet/test/test.cc
--- sandbox/jardonnet/test/test.cc (revision 0)
+++ sandbox/jardonnet/test/test.cc (revision 0)
@@ -0,0 +1,12 @@
+#include <mln/core/image2d.hh>
+
+# include <mln/geom/ncols.hh>
+# include <mln/geom/nrows.hh>
+
+
+int main()
+{
+ mln::image2d<int> i(5 / 3,5);
+
+ return mln::geom::nrows(i);
+}
Index: sandbox/jardonnet/test/subsampling.cc
--- sandbox/jardonnet/test/subsampling.cc (revision 0)
+++ sandbox/jardonnet/test/subsampling.cc (revision 0)
@@ -0,0 +1,22 @@
+#include <mln/core/image2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <sandbox/jardonnet/subsampling/subsampling_2d.hh>
+
+
+int main(int argc, char*)
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> img;
+
+ io::pgm::load(img, "../../../img/lena.pgm");
+
+ std::cout << geom::nrows(img) << geom::ncols(img) << std::endl;
+ image2d<int_u8> output = subsampling::subsampling_2d(img, make::dpoint2d(1,1), argc);
+
+ io::pgm::save(output, "out1.pgm");
+}
Index: sandbox/jardonnet/test/Makefile
--- sandbox/jardonnet/test/Makefile (revision 0)
+++ sandbox/jardonnet/test/Makefile (revision 0)
@@ -0,0 +1,8 @@
+SOURCE=test.cc subsampling.cc
+FLAG=-Wall -W -I../../.. -g
+
+all:
+ g++ $(SOURCE) $(FLAG) -o '+a.out'
+
+sub:
+ g++ subsampling.cc $(FLAG) -o '+a.out'
Index: sandbox/jardonnet/subsampling/subsampling_2d.hh
--- sandbox/jardonnet/subsampling/subsampling_2d.hh (revision 0)
+++ sandbox/jardonnet/subsampling/subsampling_2d.hh (revision 0)
@@ -0,0 +1,117 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_SUBSAMPLING_SUBSAMPLING_2D_HH
+# define MLN_SUBSAMPLING_SUBSAMPLING_2D_HH
+
+/*! \file mln/binarization/threshold.hh
+ *
+ * \brief Threshold the contents of an image into another binary one.
+ */
+
+# include <mln/geom/ncols.hh>
+# include <mln/geom/nrows.hh>
+
+
+namespace mln
+{
+
+ namespace subsampling
+ {
+
+ /*! Subsampling FIXME : doxy
+ *
+ *
+ */
+ template <typename I>
+ inline
+ mln_concrete(I)
+ subsampling_2d(const Image<I>& input,
+ const mln_dpoint(I)& first_p,
+ const mln_coord(I)& gap);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ subsampling_2d_(const I& input,
+ const mln_dpoint(I)& first_p,
+ const mln_coord(I)& gap)
+ {
+ trace::entering("subsampling_2d::impl::subsampling_2d_");
+ mln_concrete(I) output(geom::nrows(input) / gap,
+ geom::ncols(input) / gap);
+
+ for (unsigned j = 0; j < geom::ncols(output); ++j)
+ for (unsigned i = 0; i < geom::nrows(output); ++i)
+ {
+ point2d p1(i, j);
+ point2d p2(first_p[0] + i * gap, first_p[1] + j * gap);
+ std::cout << p1 << ' ' << p2 << std::endl;
+ output(p1) = input(p2);
+ }
+
+ trace::exiting("subsampling_2d::impl::subsampling_2d_");
+ return output;
+ }
+
+ } // end of namespace mln::subsampling_2d::impl
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ subsampling_2d(const Image<I>& input,
+ const mln_dpoint(I)& first_p,
+ const mln_coord(I)& gap)
+ {
+ trace::entering("subsampling::subsampling_2d");
+ mln_precondition(exact(input).has_data());
+
+ mln_concrete(I) output(geom::nrows(input) / gap,
+ geom::ncols(input) / gap);
+
+ std::cout << geom::nrows(output) << ' ' << geom::ncols(output) << std::endl;
+
+ output = impl::subsampling_2d_(exact(input), first_p, gap);
+
+ trace::exiting("subsampling::subsampling_2d");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::subsampling_2d
+
+} // end of namespace mln
+
+
+#endif // ! MLN_SUBSAMPLING_SUBSAMPLING_2D_HH
Index: sandbox/jardonnet/subsampling/sub_sampled_image.hh
--- sandbox/jardonnet/subsampling/sub_sampled_image.hh (revision 0)
+++ sandbox/jardonnet/subsampling/sub_sampled_image.hh (revision 0)
@@ -0,0 +1,226 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_CORE_SUB_SAMPLED_IMAGE_HH
+# define MLN_CORE_SUB_SAMPLED_IMAGE_HH
+
+/*! \file mln/core/sub_sampled_image.hh
+ *
+ */
+
+# include <mln/core/internal/image_morpher.hh>
+# include <mln/convert/to_dpoint.hh>
+# include <mln/metal/vec.hh>
+# include <mln/value/set.hh>
+
+
+namespace mln
+{
+
+ // Fwd decl.
+ template <typename I> struct sub_sampled_image;
+
+ namespace internal
+ {
+
+ /// \internal Data structure for \c mln::t_image<I>.
+ template <typename I>
+ struct data_< sub_sampled_image<I> >
+ {
+ /// \brief Build the data object held by a sub_sampled_image.
+ ///
+ /// \param ima The underlying image.
+ /// \param box The bounding box (domain) of the morphed image.
+ data_(I& ima, mln::box_<mln_point(I)>& box);
+
+ /// Underlying image.
+ I ima_;
+
+ /// The bounding box of the morphed image.
+ mln::box_<mln_point(I)> box_;
+ };
+
+ } // end of namespace mln::internal
+
+ template <typename I>
+ class sub_sampled_image
+ : public internal::image_morpher_< I, mln_pset(I), sub_sampled_image<I> >
+ {
+ public:
+ /// Super type.
+ typedef
+ internal::image_morpher_< I, mln_pset(I), sub_sampled_image<I> > super_;
+
+ /// Point_Site associated type.
+ typedef mln_psite(I) psite;
+
+ /// Value associated type.
+ typedef mln_value(I) value;
+
+ /// Type returned by the read-write pixel value operator.
+ typedef typename internal::morpher_lvalue_<I>::ret lvalue;
+
+ /// Return type of read-only access.
+ typedef mln_rvalue(I) rvalue;
+
+ /// Value set associated type.
+ typedef mln::value::set<value> vset;
+
+ /// Skeleton.
+ typedef sub_sampled_image< tag::image_<I> > skeleton;
+
+
+ /// Give the definition domain.
+ const box_<mln_point(I)>& domain() const;
+
+ /// Test if this image has been initialized.
+ bool has_data() const;
+
+ /// Test if a pixel value is accessible at \p p.
+ bool owns_(const mln_point(I)& p) const;
+
+ /// Give the set of values of the image.
+ const vset& values() const;
+
+ /// Read-only access of pixel value at point site \p p.
+ mln_rvalue(I) operator()(const mln_point(I)& p) const;
+
+ /// Read-write access of pixel value at point site \p p.
+ lvalue operator()(const mln_point(I)& p);
+ public:
+ sub_sampled_image(I& ima, const mln_point(I)& first_p, int gap);
+
+ void set_sampling(const mln_point(I)& first_p, int gap);
+
+ protected:
+
+ /// Compute physical coordinates.
+ mln_point(I) translate_coords_(const mln_point(I)& p) const;
+
+ const mln_point(I)& first_p;
+ int gap;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ // internal::data_< sub_sampled_image<I,S> >
+
+ template <typename I>
+ inline
+ data_< sub_sampled_image<I> >::data_(I& ima, mln::box_<mln_point(I)>& box)
+ : ima_(ima), box_(box)
+ {
+ }
+
+ } // end of namespace mln::internal
+
+
+ template <typename I>
+ sub_sampled_image<I>::sub_sampled_image(I& ima, const mln_point(I)& first_p, int gap)
+ : first_p(first_p), gap(gap)
+ {
+ box_<mln_point(I)> box(ima.bbox().pmin(),ima.bbox().pmax());
+ this->data_ = new internal::data_< sub_sampled_image<I> >(ima, box);
+ }
+
+
+ template <typename I>
+ inline
+ const box_<mln_point(I)>&
+ sub_sampled_image<I>::domain() const
+ {
+ mln_precondition(this->has_data());
+ return this->data_->box_;
+ }
+
+
+ template <typename I>
+ inline
+ const typename sub_sampled_image<I>::vset&
+ sub_sampled_image<I>::values() const
+ {
+ mln_precondition(this->delegatee_() != 0);
+ return this->delegatee_()->values();
+ }
+
+
+ template <typename I>
+ inline
+ bool sub_sampled_image<I>::has_data() const
+ {
+ mln_invariant(this->delegatee_()->has_data());
+ return true;
+ }
+
+
+ template <typename I>
+ inline
+ bool
+ sub_sampled_image<I>::owns_(const mln_point(I)& p) const
+ {
+ mln_precondition(this->has_data());
+ return this->delegatee_()->owns_(translate_coords_(p));
+ }
+
+ template <typename I>
+ inline
+ mln_rvalue(I)
+ sub_sampled_image<I>::operator()(const mln_point(I)& p) const
+ {
+ mln_precondition(this->owns_(p));
+ return (*this->delegatee_())(translate_coords_(p));
+ }
+
+ template <typename I>
+ inline
+ typename internal::morpher_lvalue_<I>::ret
+ sub_sampled_image<I>::operator()(const mln_point(I)& p)
+ {
+ mln_precondition(this->owns_(p));
+ return (*this->delegatee_())(translate_coords_(p));
+ }
+
+ template <typename I>
+ inline
+ mln_point(I)
+ sub_sampled_image<I>::translate_coords_(const mln_point(I)& p) const
+ {
+
+ return mln_point(I)(metal::vec<2, int>(p) * gap + metal::vec<2, int>(first_p));
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_SUB_SAMPLED_IMAGE_HH
1
0
https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
New sample code for Caroline (hsi and conversion).
* milena/sandbox/vigouroux/color/my_hsi.hh: .
* milena/sandbox/vigouroux/color/is_HSI.cc: New.
* milena/sandbox/vigouroux/color/rgb_to_hsi.hh
(fun::v2v::f_rgb_to_hsi_): New.
is_HSI.cc | 20 ++++++++++++
my_hsi.hh | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
rgb_to_hsi.hh | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 180 insertions(+), 13 deletions(-)
Index: milena/sandbox/vigouroux/color/my_hsi.hh
--- milena/sandbox/vigouroux/color/my_hsi.hh (revision 1756)
+++ milena/sandbox/vigouroux/color/my_hsi.hh (working copy)
@@ -4,13 +4,85 @@
#include <mln/value/int_u.hh>
#include <mln/metal/vec.hh>
+#include <mln/value/float01_8.hh>
+
#ifndef MLN_VALUE_HSI_HH
# define MLN_VALUE_HSI_HH
+
namespace mln
{
+
namespace value
{
+
+ template <typename E>
+ struct HSI
+ {
+ };
+
+ template <typename F>
+ class hsi_ : public HSI< hsi_<F> >
+ {
+ public:
+
+ typedef F h_type;
+ typedef F s_type;
+ typedef F i_type;
+
+ /// Constructor without argument.
+ hsi_()
+ {
+ }
+
+ /// Constructor from component values.
+ hsi_(const F& h, const F& s, const F& i)
+ : h_(h),
+ s_(s),
+ i_(i)
+ {
+ }
+
+ /// Read-only access to the h component.
+ const F& h() const
+ {
+ return this->h_;
+ }
+ const F& s() const
+ {
+ return this->s_;
+ }
+ const F& i() const
+ {
+ return this->i_;
+ }
+
+ /// Read-write access to the h component.
+ F& h()
+ {
+ return this->h_;
+ }
+ F& s()
+ {
+ return this->s_;
+ }
+ F& i()
+ {
+ return this->i_;
+ }
+
+ private:
+ F h_;
+ F s_;
+ F i_;
+ };
+
+ typedef hsi_<float01_8> hsi_3x8;
+
+ typedef hsi_<double> hsi_d;
+
+
+
template <unsigned n>
struct hsi
{
@@ -47,6 +119,9 @@
double i_;
};
+
+# ifndef MLN_INCLUDE_ONLY
+
template <unsigned n>
inline
hsi<n>::hsi()
@@ -65,7 +140,11 @@
this->s_ = s;
this->i_ = i;
}
- }
-}
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
#endif // ! MLN_VALUE_HSI_HH
Index: milena/sandbox/vigouroux/color/is_HSI.cc
--- milena/sandbox/vigouroux/color/is_HSI.cc (revision 0)
+++ milena/sandbox/vigouroux/color/is_HSI.cc (revision 0)
@@ -0,0 +1,20 @@
+#include <iostream>
+
+#include <mln/metal/is_a.hh>
+#include <mln/value/rgb8.hh>
+#include "my_hsi.hh"
+#include "rgb_to_hsi.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using namespace mln::value;
+
+ typedef hsi_d C;
+ std::cout << mlc_is_a(C, HSI)::value << std::endl;
+ std::cout << mlc_is_a(rgb8, HSI)::value << std::endl;
+
+ rgb8 c(255, 10, 1);
+ hsi_3x8 c_hsi = fun::v2v::f_rgb_to_hsi_3x8(c);
+}
Index: milena/sandbox/vigouroux/color/rgb_to_hsi.hh
--- milena/sandbox/vigouroux/color/rgb_to_hsi.hh (revision 1756)
+++ milena/sandbox/vigouroux/color/rgb_to_hsi.hh (working copy)
@@ -1,3 +1,5 @@
+#include <cmath>
+
#include <mln/core/image_if_value.hh>
#include <mln/core/inplace.hh>
#include <mln/core/w_window2d_int.hh>
@@ -8,12 +10,75 @@
#include "my_hsi.hh"
-namespace mln {
- namespace convert {
+
+
+namespace mln
+{
+
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ // NEW
+
+ template <typename T_hsi>
+ struct f_rgb_to_hsi_ : public Function_v2v< f_rgb_to_hsi_<T_hsi> >
+ {
+ typedef T_hsi result;
+
+ template <typename T_rgb>
+ T_hsi operator()(const T_rgb& rgb) const
+ {
+ // Locals.
+ static const double sqrt3_3 = std::sqrt(3) / 3;
+ static const double inv_sqrt6 = 1 / std::sqrt(6);
+ static const double inv_sqrt2 = 1 / std::sqrt(2);
+
+ T_hsi hsi;
+
+ double alpha = inv_sqrt2 * rgb.green() - inv_sqrt2 * rgb.blue();
+ double beta = 2 * inv_sqrt6 * rgb.red() - inv_sqrt6 * rgb.green() - inv_sqrt6 * rgb.blue();
+
+
+ float tmp = atan2(beta, alpha) / 3.1415 * 180.0;
+ if (tmp < 0 or tmp > 1)
+ {
+ std::cout << "FIXME: " << tmp << std::endl;
+ }
+
+ hsi.h() = atan2(beta, alpha) / 3.1415 * 180.0;
+ if (hsi.h() < 0)
+ hsi.h() = hsi.h() + 360.0;
+ mln_invariant(hsi.h() >= 0);
+ hsi.s() = std::sqrt(alpha * alpha + beta * beta);
+ hsi.i() = sqrt3_3 * rgb.red() + sqrt3_3 * rgb.green() + sqrt3_3 * rgb.blue();
+
+ return hsi;
+ }
+ };
+
+ typedef f_rgb_to_hsi_<value::hsi_3x8> f_rgb_to_hsi_3x8_t;
+
+ f_rgb_to_hsi_3x8_t f_rgb_to_hsi_3x8;
+
+ // end of NEW
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+
+
+
+ namespace convert
+ {
+
struct f_rgb_to_hsi
{
- struct value::hsi<8>
- doit(const struct value::rgb<8> rgb) const
+ value::hsi<8> operator()(const value::rgb<8>& rgb) const
{
struct value::hsi<8> hsi;
double sqrt3_3 = sqrt(3) / 3;
@@ -30,14 +95,15 @@
hsi.s(sqrt(alpha * alpha + beta * beta));
hsi.i(sqrt3_3 * rgb.red() + sqrt3_3 * rgb.green() + sqrt3_3 * rgb.blue());
- return (hsi);
+ return hsi;
}
};
+
struct f_hsi_to_rgb
{
- struct value::rgb<8>
- doit(const struct value::hsi<8> hsi) const
+
+ value::rgb<8> doit(const value::hsi<8>& hsi) const
{
int r;
int g;
@@ -55,10 +121,12 @@
g = int(sqrt3_3 * hsi.i() + inv_sqrt2 * alpha - inv_sqrt6 * beta);
b = int(sqrt3_3 * hsi.i() - inv_sqrt2 * alpha - inv_sqrt6 * beta);
- struct value::rgb<8> rgb(r, g, b);
+ value::rgb<8> rgb(r, g, b);
- return (rgb);
+ return rgb;
}
};
- }
-}
+
+ } // end of FIXME
+
+} // end of FIXME
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Add base decorator for boost graph.
* tests/util/boost_graph.cc: New.
* mln/util/internal/boost_graph.hh: New, boost graph base decorator.
* mln/util/internal/boost_graph_structure.hh,
* mln/util/internal/boost_graph_access.hh,
* mln/util/internal/boost_graph_property.hh: boost graph operations.
mln/util/internal/boost_graph.hh | 189 ++++++++++++++++++
mln/util/internal/boost_graph_access.hh | 293 +++++++++++++++++++++++++++++
mln/util/internal/boost_graph_property.hh | 171 ++++++++++++++++
mln/util/internal/boost_graph_structure.hh | 281 +++++++++++++++++++++++++++
tests/util/boost_graph.cc | 116 +++++++++++
5 files changed, 1050 insertions(+)
Index: tests/util/boost_graph.cc
--- tests/util/boost_graph.cc (revision 0)
+++ tests/util/boost_graph.cc (revision 0)
@@ -0,0 +1,116 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+/// \file tests/util/graph.cc
+/// \brief test of mln::util::graph
+/// This test is a copy of the BGL quick tours example.
+
+#include <mln/util/internal/boost_graph.hh>
+#include <iostream>
+
+using namespace mln::util::internal;
+using namespace boost;
+
+struct empty {};
+
+template <class Graph>
+struct exercise_vertex
+{
+ typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+ exercise_vertex(Graph& g_) : g(g_) {}
+
+ void operator()(const Vertex& v) const
+ {
+ typedef graph_traits<Graph> GraphTraits;
+ typename property_map<Graph, vertex_index_t>::type
+ index = get(vertex_index, g);
+
+ std::cout << "out-edges: ";
+ typename GraphTraits::out_edge_iterator out_i, out_end;
+ typename GraphTraits::edge_descriptor e;
+ for (tie(out_i, out_end) = out_edges(v, g); out_i != out_end; ++out_i)
+ {
+ e = *out_i;
+ Vertex src = source(e, g), targ = target(e, g);
+ std::cout << "(" << index[src] << "," << index[targ] << ") ";
+ }
+ std::cout << std::endl;
+
+ std::cout << "adjacent vertices: ";
+ typename graph_traits<Graph>::adjacency_iterator ai;
+ typename graph_traits<Graph>::adjacency_iterator ai_end;
+ for (tie(ai, ai_end) = adjacent_vertices(v, g); ai != ai_end; ++ai)
+ std::cout << index[*ai] << " ";
+ std::cout << std::endl;
+ }
+
+ Graph& g;
+};
+
+int main ()
+{
+
+ typedef boost_graph<empty, empty> Graph;
+
+ // Make convenient labels for the vertices
+ const int num_vertices = 5;
+
+ // writing out the edges in the graph
+ typedef std::pair<int, int> Edge;
+ Edge edge_array[] = {
+ Edge(0, 1), Edge(0, 3), Edge(2, 0), Edge(3, 2),
+ Edge(2, 4), Edge(1, 3), Edge(3, 4)
+ };
+ const int num_edges = sizeof(edge_array)/sizeof(edge_array[0]);
+
+ // declare a graph object
+ Graph g(num_vertices);
+ typedef property_map<Graph, vertex_index_t>::type IndexMap;
+ IndexMap index = get(vertex_index, g);
+
+ // add the edges to the graph object
+ for (int i = 0; i < num_edges; ++i)
+ add_edge(edge_array[i].first, edge_array[i].second, g);
+
+ std::cout << "vertices(g) = ";
+ typedef graph_traits<Graph>::vertex_iterator vertex_iter;
+ std::pair<vertex_iter, vertex_iter> vp;
+ for (vp = vertices(g); vp.first != vp.second; ++vp.first)
+ std::cout << index[*vp.first] << " ";
+ std::cout << std::endl;
+
+ std::cout << "edges(g) = ";
+ graph_traits<Graph>::edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ std::cout << "(" << index[source(*ei, g)]
+ << "," << index[target(*ei, g)] << ") ";
+ std::cout << std::endl;
+
+ std::for_each(vertices(g).first, vertices(g).second,
+ exercise_vertex<Graph>(g));
+ return 0;
+}
Index: mln/util/internal/boost_graph.hh
--- mln/util/internal/boost_graph.hh (revision 0)
+++ mln/util/internal/boost_graph.hh (revision 0)
@@ -0,0 +1,189 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_UTIL_BOOST_GRAPH_HH
+# define MLN_UTIL_BOOST_GRAPH_HH
+
+/// \file mln/util/internal/boost_graph.hh
+/// \brief Definition of the boost::adjacenly_list decorator.
+
+# include <boost/graph/adjacency_list.hpp>
+
+namespace mln
+{
+
+ namespace util
+ {
+
+ namespace internal
+ {
+
+ /// \brief Boost graph decorator base
+ /// Graph class which rests on boost::adjacency_list class.
+ template <typename VertexProperty, typename EdgeProperty>
+ class boost_graph
+ {
+ typedef boost_graph<VertexProperty, EdgeProperty> self_type;
+
+ public:
+ /// Types declartation.
+ typedef boost::adjacency_list<boost::setS, boost::vecS,
+ boost::undirectedS,
+ VertexProperty, EdgeProperty> decorated;
+
+ /// Descriptors.
+ typedef typename decorated::vertex_descriptor vertex_descriptor;
+ typedef typename decorated::edge_descriptor edge_descriptor;
+
+ /// Iterators.
+ typedef typename decorated::vertex_iterator vertex_iterator;
+ typedef typename decorated::edge_iterator edge_iterator;
+ typedef typename decorated::out_edge_iterator out_edge_iterator;
+ typedef typename decorated::in_edge_iterator in_edge_iterator;
+ typedef typename decorated::adjacency_iterator adjacency_iterator;
+ typedef typename decorated::inv_adjacency_iterator
+ inv_adjacency_iterator;
+
+ /// Categories.
+ typedef typename decorated::directed_category directed_category;
+ typedef typename decorated::traversal_category traversal_category;
+ typedef typename decorated::edge_parallel_category
+ edge_parallel_category;
+ typedef typename decorated::vertex_property_type vertex_property_type;
+ typedef typename decorated::graph_tag graph_tag;
+
+ /// Sizes.
+ typedef typename decorated::vertices_size_type vertices_size_type;
+ typedef typename decorated::edges_size_type edges_size_type;
+ typedef typename decorated::degree_size_type degree_size_type;
+
+
+ /// Constructor(s).
+ boost_graph();
+ boost_graph(const boost_graph& lhs);
+ boost_graph(vertices_size_type n);
+
+ /// Assignment operator.
+ boost_graph&
+ operator=(const boost_graph& lhs);
+
+ /// Remove all of the edges and vertices from the graph.
+ void clear();
+
+ /// Swap the vertices, edges, and properties of this graph with
+ /// the vertices, edges, and properties of graph x.
+ void swap(boost_graph& rhs);
+
+ /// Internal methods:
+
+ /// Return the boost decorated graph.
+ decorated&
+ graph();
+
+ /// Return the boost decorated graph (const version).
+ const decorated&
+ graph() const;
+
+
+ protected:
+ decorated graph_;
+ /// add index on need
+ };
+
+ /// Graph method declaration
+
+ /// Implementation
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename VertexProp, typename EdgeProp>
+ boost_graph<VertexProp, EdgeProp>::boost_graph()
+ {
+ }
+
+ template <typename VertexProp, typename EdgeProp>
+ boost_graph<VertexProp, EdgeProp>::boost_graph(const boost_graph& lhs) :
+ graph_(lhs.graph_)
+ {
+ }
+
+ template <typename VertexProp, typename EdgeProp>
+ boost_graph<VertexProp, EdgeProp>::boost_graph(vertices_size_type n) :
+ graph_(n)
+ {
+ }
+
+ template <typename VertexProp, typename EdgeProp>
+ boost_graph<VertexProp, EdgeProp>&
+ boost_graph<VertexProp, EdgeProp>::operator=(const boost_graph& lhs)
+ {
+ if (&lhs == this)
+ return *this;
+ this->graph_ = lhs.graph_;
+ }
+
+ template <typename VertexProp, typename EdgeProp>
+ void
+ boost_graph<VertexProp, EdgeProp>::clear()
+ {
+ this->graph_.clear();
+ }
+
+ template <typename VertexProp, typename EdgeProp>
+ void
+ boost_graph<VertexProp, EdgeProp>::swap(boost_graph& rhs)
+ {
+ this->graph_.swap(rhs.graph_);
+ }
+
+ template <typename VertexProp, typename EdgeProp>
+ inline typename boost_graph<VertexProp, EdgeProp>::decorated&
+ boost_graph<VertexProp, EdgeProp>::graph()
+ {
+ return this->graph_;
+ }
+
+ template <typename VertexProp, typename EdgeProp>
+ inline const typename boost_graph<VertexProp, EdgeProp>::decorated&
+ boost_graph<VertexProp, EdgeProp>::graph() const
+ {
+ return this->graph_;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::util::internal
+
+ } // end of namespace mln::util
+
+} // end of namespace mln
+
+# include "boost_graph_access.hh"
+# include "boost_graph_structure.hh"
+# include "boost_graph_property.hh"
+
+#endif // ! MLN_UTIL_BOOST_GRAPH_HH
Index: mln/util/internal/boost_graph_structure.hh
--- mln/util/internal/boost_graph_structure.hh (revision 0)
+++ mln/util/internal/boost_graph_structure.hh (revision 0)
@@ -0,0 +1,281 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+
+/// \file mln/util/internal/boost_graph_struture.hh
+/// \brief Operations that interract with the boost_graph structure.
+
+#ifndef MLN_UTIL_INTERNAL_BOOST_GRAPH_STRUCTURE_HH_
+# define MLN_UTIL_INTERNAL_BOOST_GRAPH_STRUCTURE_HH_
+
+/// fwd declaration
+namespace mln
+{
+ namespace util
+ {
+ namespace internal
+ {
+ template <typename VertexProperty, typename EdgeProperty>
+ class boost_graph;
+ }
+ }
+}
+
+namespace boost
+{
+ namespace mlnu = mln::util::internal;
+
+ /// \brief Adds edge (u,v) to the graph and returns the edge descriptor for
+ /// the new edge.
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::edge_descriptor, bool>
+ add_edge(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Adds edge (u,v) to the graph and attaches p as the value of the
+ /// edge's internal property storage.
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::edge_descriptor, bool>
+ add_edge(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ const typename mlnu::boost_graph<VProp, EProp>::EdgeProperties& p,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Removes the edge (u,v) from the graph.
+ template <typename VProp, typename EProp>
+ void
+ remove_edge(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Removes the edge e from the graph.
+ /// This differs from the remove_edge(u, v, g) function in the case of
+ /// a multigraph. This remove_edge(e, g) function removes a single edge,
+ /// whereas the remove_edge(u, v, g) function removes all edges (u,v).
+ template <typename VProp, typename EProp>
+ void
+ remove_edge(typename mlnu::boost_graph<VProp, EProp>::edge_descriptor e,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Same as remove_edge(*iter, g)
+ template <typename VProp, typename EProp>
+ void
+ remove_edge(typename mlnu::boost_graph<VProp, EProp>::out_edge_iterator iter,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Removes all out-edges of vertex u from the graph that
+ /// satisfy the predicate.
+ template <typename VProp, typename EProp, class Predicate>
+ void
+ remove_out_edge_if(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ Predicate predicate,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+ /// FIXME only available on directed graph
+ template <typename VProp, typename EProp, class Predicate>
+ void
+ remove_in_edge_if(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ Predicate predicate,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Removes all edges of vertex u from the graph that
+ /// satisfy the predicate.
+ template <typename VProp, typename EProp, class Predicate>
+ void remove_edge_if(Predicate predicate,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Adds a vertex to the graph.
+ /// Returns the vertex descriptor for the new vertex.
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor
+ add_vertex(typename mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Adds a vertex to the graph with the specified properties.
+ /// Returns the vertex descriptor for the new vertex.
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor
+ add_vertex(const typename mlnu::boost_graph<VProp, EProp>::VertexProperties& p,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Removes all edges to and from vertex u.
+ template <typename VProp, typename EProp>
+ void
+ clear_vertex(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Removes all out-edges to and from vertex u.
+ template <typename VProp, typename EProp>
+ void
+ clear_out_edges(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+ /// FIXME: only define for the directed graphs.
+ template <typename VProp, typename EProp>
+ void
+ clear_in_edges(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Remove vertex u from the vertex set of the graph.
+ /// It is assumed that there are no edges to or from vertex u
+ /// when it is removed
+ template <typename VProp, typename EProp>
+ void
+ remove_vertex(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>& g);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::edge_descriptor,
+ bool>
+ add_edge(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return add_edge(u, v, g.graph());
+ }
+
+
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::edge_descriptor,
+ bool>
+ add_edge(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ const typename mlnu::boost_graph<VProp, EProp>::EdgeProperties& p,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return add_edge(u, v, p, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ void
+ remove_edge(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return remove_edge(u, v, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ void
+ remove_edge(typename mlnu::boost_graph<VProp, EProp>::edge_descriptor e,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return remove_edge(e, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ void
+ remove_edge(typename mlnu::boost_graph<VProp, EProp>::out_edge_iterator iter,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return remove_edge(iter, g.graph());
+ }
+
+ template <typename VProp, typename EProp, class Predicate>
+ void
+ remove_out_edge_if(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ Predicate predicate,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return remove_out_edge_if(u, predicate, g.graph());
+ }
+
+ template <typename VProp, typename EProp, class Predicate>
+ void
+ remove_in_edge_if(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ Predicate predicate,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return remove_in_edge_if(v, predicate, g.graph());
+ }
+
+ template <typename VProp, typename EProp, class Predicate>
+ void remove_edge_if(Predicate predicate,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return remove_edge_if(predicate, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor
+ add_vertex(typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return add_vertex(g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor
+ add_vertex(const typename mlnu::boost_graph<VProp, EProp>::VertexProperties& p,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return add_vertex(p, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ void
+ clear_vertex(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return clear_vertex(u, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ void
+ clear_out_edges(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return clear_out_edges(u, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ void
+ clear_in_edges(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return clear_in_edges(u, g.graph());
+ }
+
+
+ template <typename VProp, typename EProp>
+ void
+ remove_vertex(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return remove_vertex(u, g);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace boost
+
+#endif // ! MLN_UTIL_INTERNAL_BOOST_GRAPH_STRUCTURE_HH_
Index: mln/util/internal/boost_graph_access.hh
--- mln/util/internal/boost_graph_access.hh (revision 0)
+++ mln/util/internal/boost_graph_access.hh (revision 0)
@@ -0,0 +1,293 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file mln/util/internal/boost_graph_access.hh
+/// \brief boost_graph access operations.
+
+#ifndef MLN_UTIL_INTERNAL_BOOST_GRAPH_ACCESS_HH_
+# define MLN_UTIL_INTERNAL_BOOST_GRAPH_ACCESS_HH_
+
+
+# include <utility>
+
+/// fwd declaration
+namespace mln
+{
+ namespace util
+ {
+ namespace internal
+ {
+ template <typename VertexProperty, typename EdgeProperty>
+ class boost_graph;
+ }
+ }
+}
+
+namespace boost
+{
+ namespace mlnu = mln::util::internal;
+
+ /// \brief Returns an iterator-range providing access to the vertex
+ /// set of graph g.
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::vertex_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_iterator>
+ vertices(const mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Returns an iterator-range providing access to
+ /// the edge set of graph g.
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::edge_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::edge_iterator>
+ edges(const mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Returns an iterator-range providing access to the vertices
+ /// adjacent to vertex u in graph g.
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::adjacency_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::adjacency_iterator>
+ adjacent_vertices(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ const mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Returns an iterator-range providing access to the vertices in
+ /// graph g to which u is adjacent. (inv is for inverse.)
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::inv_adjacency_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::inv_adjacency_iterator>
+ inv_adjacent_vertices(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ const mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Returns an iterator-range providing access access to
+ /// all edges incident on vertex u.
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::out_edge_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::out_edge_iterator>
+ out_edges(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ const mlnu::boost_graph<VProp, EProp>& g);
+
+ /// FIXME: this operation is undefined for undirected graph
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::in_edge_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::in_edge_iterator>
+ in_edges(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ const mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Returns the source vertex of edge e.
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor
+ source(typename mlnu::boost_graph<VProp, EProp>::edge_descriptor e,
+ const mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Returns the target vertex of edge e.
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor
+ target(typename mlnu::boost_graph<VProp, EProp>::edge_descriptor e,
+ const mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Returns the number of edges leaving vertex u.
+ template <typename V, typename E>
+ typename mlnu::boost_graph<V, E>::degree_size_type
+ out_degree(typename mlnu::boost_graph<V, E>::vertex_descriptor u,
+ const mlnu::boost_graph<V, E>& g);
+
+ /// FIXME this operation is unavalaible for undirected graph.
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::degree_size_type
+ in_degree(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ const mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Returns the number of vertices in the graph g.
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertices_size_type
+ num_vertices(const mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Returns the number of edges in the graph g.
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::edges_size_type
+ num_edges(const mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Returns the nth vertex in the graph's vertex list.
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor
+ vertex(typename mlnu::boost_graph<VProp, EProp>::vertices_size_type n,
+ const typename mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Returns an edge connecting vertex u to vertex v in graph g.
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::edge_descriptor, bool>
+ edge(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ const mlnu::boost_graph<VProp, EProp>& g);
+
+ /// \brief Returns a pair of out-edge iterators that give the range for all
+ /// the parallel edges from u to v.
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::out_edge_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::out_edge_iterator>
+ edge_range(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ const mlnu::boost_graph<VProp, EProp>& g);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::vertex_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_iterator>
+ vertices(const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return vertices(g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::edge_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::edge_iterator>
+ edges(const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return edges(g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::adjacency_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::adjacency_iterator>
+ adjacent_vertices(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return adjacent_vertices(u, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::inv_adjacency_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::inv_adjacency_iterator>
+ inv_adjacent_vertices(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return inv_adjacent_vertices(u, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::out_edge_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::out_edge_iterator>
+ out_edges(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return out_edges(u, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::in_edge_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::in_edge_iterator>
+ in_edges(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return in_edges(v, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor
+ source(typename mlnu::boost_graph<VProp, EProp>::edge_descriptor e,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return source(e, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor
+ target(typename mlnu::boost_graph<VProp, EProp>::edge_descriptor e,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return target(e, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::degree_size_type
+ out_degree(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return out_degree(u, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::degree_size_type
+ in_degree(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return in_degree(u, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertices_size_type
+ num_vertices(const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return num_vertices(g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::edges_size_type
+ num_edges(const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return num_edges(g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor
+ vertex(typename mlnu::boost_graph<VProp, EProp>::vertices_size_type n,
+ const typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return vertex(n, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::edge_descriptor,
+ bool>
+ edge(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return edge(u, v, g.graph());
+ }
+
+ template <typename VProp, typename EProp>
+ std::pair<typename mlnu::boost_graph<VProp, EProp>::out_edge_iterator,
+ typename mlnu::boost_graph<VProp, EProp>::out_edge_iterator>
+ edge_range(typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor u,
+ typename mlnu::boost_graph<VProp, EProp>::vertex_descriptor v,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return edge_range(u, v, g.graph());
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace boost
+
+#endif // ! MLN_UTIL_INTERNAL_BOOST_GRAPH_ACCESS_HH_
Index: mln/util/internal/boost_graph_property.hh
--- mln/util/internal/boost_graph_property.hh (revision 0)
+++ mln/util/internal/boost_graph_property.hh (revision 0)
@@ -0,0 +1,171 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file mln/util/internal/boost_graph_property.hh
+/// \brief boost_graph properties access operations.
+
+#ifndef MLN_UTIL_INTERNAL_BOOST_GRAPH_PROPERTY_HH_
+# define MLN_UTIL_INTERNAL_BOOST_GRAPH_PROPERTY_HH_
+
+# include <utility>
+# include <boost/graph/adjacency_list.hpp>
+
+/// fwd declaration
+namespace mln
+{
+ namespace util
+ {
+ namespace internal
+ {
+ template <typename VertexProperty, typename EdgeProperty>
+ class boost_graph;
+ }
+ }
+}
+
+namespace boost
+{
+ namespace mlnu = mln::util::internal;
+
+
+ /// \brief Returns the property map object for the vertex property
+ /// specified by PropertyTag.
+ template <typename VProp, typename EProp, typename PropertyTag>
+ typename property_map<typename mlnu::boost_graph<EProp, VProp>::decorated,
+ PropertyTag>::type
+ get(PropertyTag, typename mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief Returns the property map object for the vertex property
+ /// specified by PropertyTag (const version).
+ template <typename VProp, typename EProp, typename PropertyTag>
+ typename property_map<typename mlnu::boost_graph<EProp, VProp>::decorated,
+ PropertyTag>::const_type
+ get(PropertyTag, const mlnu::boost_graph<VProp, EProp>& g);
+
+
+ /// \brief This returns the property value for x.
+ /// x is either a vertex or edge descriptor.
+ template <typename VProp, typename EProp, typename PropertyTag, typename X>
+ typename property_traits<
+ typename property_map<typename mlnu::boost_graph<EProp, VProp>::decorated,
+ PropertyTag>::const_type >::value_type
+ get(PropertyTag, const mlnu::boost_graph<VProp, EProp>& g, X x);
+
+
+ /// \brief This sets the property value for x to value.
+ /// x is either a vertex or edge descriptor.
+ template <typename VProp, typename EProp,
+ typename PropertyTag, typename X, typename Value>
+ void
+ put(PropertyTag, const mlnu::boost_graph<VProp, EProp>& g,
+ X x, const Value& value);
+
+
+ /// \brief Return the property specified by GraphPropertyTag.
+ template <typename EProp, typename VProp, typename GraphProperties,
+ typename GraphPropertyTag>
+ typename graph_property<typename mlnu::boost_graph<EProp, VProp>::decorated,
+ GraphPropertyTag>::type&
+ get_property(mlnu::boost_graph<VProp, EProp>& g, GraphPropertyTag);
+
+
+ /// \brief Return the property specified by GraphPropertyTag.
+ template <typename VProp, typename EProp,
+ typename GraphProperties, typename GraphPropertyTag>
+ const typename graph_property<
+ typename mlnu::boost_graph<EProp, VProp>::decorated,
+ GraphPropertyTag>::type&
+ get_property(const mlnu::boost_graph<VProp, EProp>& g,
+ GraphPropertyTag);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename VProp, typename EProp, typename PropertyTag>
+ typename property_map<typename mlnu::boost_graph<EProp, VProp>::decorated,
+ PropertyTag>::type
+ get(PropertyTag property_tag,
+ typename mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return get(property_tag, g.graph());
+ }
+
+ template <typename VProp, typename EProp, typename PropertyTag>
+ typename property_map<typename mlnu::boost_graph<EProp, VProp>::decorated,
+ PropertyTag>::const_type
+ get(PropertyTag property_tag,
+ const mlnu::boost_graph<VProp, EProp>& g)
+ {
+ return get(property_tag, g.graph());
+ }
+
+ template <typename VProp, typename EProp,
+ typename PropertyTag, typename X>
+ typename property_traits<
+ typename property_map<
+ typename mlnu::boost_graph<EProp, VProp>::decorated,
+ PropertyTag>::const_type>::value_type
+ get(PropertyTag property_tag, const mlnu::boost_graph<VProp, EProp>& g, X x)
+ {
+ return get(property_tag, g.graph(), x);
+ }
+
+ template <typename VProp, typename EProp,
+ typename PropertyTag, typename X, typename Value>
+ void
+ put(PropertyTag property_tag, const mlnu::boost_graph<VProp, EProp>& g,
+ X x, const Value& value)
+ {
+ put(property_tag, g.graph(), x, value);
+ }
+
+ template <typename EProp, typename VProp,
+ typename GraphProperties, typename GraphPropertyTag>
+ typename graph_property<typename mlnu::boost_graph<EProp, VProp>::decorated,
+ GraphPropertyTag>::type&
+ get_property(mlnu::boost_graph<VProp, EProp>& g,
+ GraphPropertyTag property_tag)
+ {
+ return get_property(g.graph(), property_tag);
+ }
+
+ template <typename VProp, typename EProp,
+ typename GraphProperties, typename GraphPropertyTag>
+ const typename graph_property<
+ typename mlnu::boost_graph<EProp, VProp>::decorated,
+ GraphPropertyTag>::type&
+ get_property(const mlnu::boost_graph<VProp, EProp>& g,
+ GraphPropertyTag property_tag)
+ {
+ return get_property(g.graph(), property_tag);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+}
+
+#endif // ! MLN_UTIL_INTERNAL_BOOST_GRAPH_PROPERTY_HH_
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Sample code for IRM segmentation.
* sandbox/geraud/irm.cc: New.
irm.cc | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 178 insertions(+)
Index: sandbox/geraud/irm.cc
--- sandbox/geraud/irm.cc (revision 0)
+++ sandbox/geraud/irm.cc (revision 0)
@@ -0,0 +1,178 @@
+
+#include <iterator>
+#include <iostream>
+#include <algorithm>
+
+#include <mln/core/image2d.hh>
+
+#include <mln/core/neighb2d.hh>
+#include <mln/core/window2d.hh>
+#include <mln/core/image_if.hh>
+#include <mln/win/rectangle2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/level/transform.hh>
+
+#include <mln/convert/to_window.hh>
+#include <mln/convert/to_image.hh>
+#include <mln/convert/to_fun.hh>
+
+#include <mln/morpho/gradient.hh>
+#include <mln/morpho/closing_area.hh>
+#include <mln/morpho/meyer_wst.hh>
+
+#include <mln/accu/mean.hh>
+#include <mln/level/take.hh>
+
+#include <mln/util/graph.hh>
+
+#include <mln/debug/println.hh>
+
+
+mln::value::int_u8 foo(unsigned u)
+{
+ return u = 0 ?
+ 0 : // wshed line
+ 1 + (u - 1) % 255; // basin
+}
+
+
+namespace mln
+{
+
+ template <typename I>
+ void doit(const I& irm,
+ const image2d<unsigned>& lbl,
+ unsigned nlabels)
+ {
+ {
+// accu::mean_<unsigned> m;
+
+// mln_piter(I) p(irm.domain());
+// for_all(p)
+// if (lbl(p) = 82)
+// m.take(irm(p));
+
+// level::take(irm | (pw::value(lbl) = pw::cst(82)), m);
+
+// std::cout << "reg 82 has mean = " << m << std::endl;
+ }
+
+ std::vector< accu::mean_<unsigned> > m(nlabels + 1);
+ mln_piter(I) p(irm.domain());
+ for_all(p)
+ m[lbl(p)].take(irm(p));
+
+// for (unsigned l = 1; l <= nlabels; ++l)
+// std::cout << l << ":" << m[l] << " ";
+// std::cout << std::endl;
+
+ accu::mean_<unsigned> mm;
+ mm.take(m[70]);
+ mm.take(m[77]);
+ mm.take(m[80]);
+ mm.take(m[82]);
+ mm.take(m[99]);
+ std::cout << mm.to_result() << std::endl;
+ }
+
+
+ template <typename I, typename N>
+ void mk_graph(const I& lbl,
+ N nbh,
+ unsigned nlabels)
+ {
+ std::vector< std::vector<bool> > adja(nlabels + 1);
+ for (unsigned l = 1; l <= nlabels; ++l)
+ adja[l].resize(l, false);
+
+ mln_piter(I) p(lbl.domain());
+ mln_niter(N) n(nbh, p);
+
+ // We compute the adjacency matrix of the RAG.
+ for_all(p)
+ if (lbl(p) = 0) // wshed
+ {
+ std::set<unsigned> s;
+ for_all(n) if (lbl.has(n))
+ {
+ if (lbl(n) = 0)
+ continue;
+ s.insert(lbl(n));
+ }
+ if (s.size() < 2)
+ {
+ std::cout << "#" << std::endl;
+ continue;
+ }
+ std::set<unsigned>::const_iterator l1, l2;
+ for (l1 = s.begin(); l1 != s.end(); ++l1)
+ {
+ l2 = l1;
+ for (++l2; l2 != s.end(); ++l2)
+ adja[*l2][*l1] = true;
+ }
+ }
+
+ unsigned count = 0;
+ for (unsigned l1 = 2; l1 <= nlabels; ++l1)
+ for (unsigned l2 = 1; l2 < l1; ++l2)
+ if (adja[l1][l2])
+ ++count;
+ std::cout << "link count = " << count << std::endl;
+
+ // Graph.
+ util::graph<> g;
+ // Nodes.
+ for (unsigned i = 0; i <= nlabels; ++i)
+ g.add_node();
+ // Edges.
+ for (unsigned l1 = 1; l1 <= nlabels; ++l1)
+ for (unsigned l2 = l1 + 1; l2 <= nlabels; ++l2)
+ if (adja[l1][l2])
+ g.add_edge(l1, l2);
+ g.print_debug (std::cout);
+
+ }
+
+} // end of namespace mln
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> irm;
+ io::pgm::load(irm, "./+irm6cut.pgm");
+
+// io::pgm::save( morpho::gradient(irm, win::rectangle2d(3,3)),
+// "tmp_grad_3x3.pgm" );
+
+ window2d c4p = convert::to_window(c4());
+ c4p.insert(0,0);
+// debug::println(convert::to_image(c4p));
+ image2d<int_u8> grad = morpho::gradient(irm, c4p);
+ io::pgm::save( grad, "tmp_grad_c4p.pgm" );
+
+ image2d<int_u8> clo;
+ initialize(clo, irm);
+
+ morpho::closing_area(grad, c4(), 100, clo);
+ io::pgm::save( clo, "tmp_clo_a100.pgm" );
+
+ unsigned nbasins;
+ image2d<unsigned> wshed = morpho::meyer_wst(clo, c4(), nbasins);
+ std::cout << "nbasins = " << nbasins << std::endl;
+ io::pgm::save( level::transform(wshed, convert::to_fun(foo)),
+ "tmp_wshed.pgm" );
+
+// doit(irm, wshed, nbasins);
+ mk_graph(wshed, c4(), nbasins);
+
+// std::vector< accu::mean_<unsigned> >
+
+}
1
0
27 Feb '08
https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Fix the pretty-printer of util::internal::graph_base.
* milena/mln/util/internal/graph_base.hh (node<void>::edges):
Use a std::vector (as in node<T>), not a std::list.
(util::internal::graph_base<N, E>::print_debug): Fix the iteration
on the edges adjacent to a vertex.
* milena/tests/core/graph_image.cc: Exercise
util::internal::graph_base<N, E>::print_debug
mln/util/internal/graph_base.hh | 7 +++++--
tests/core/graph_image.cc | 1 +
2 files changed, 6 insertions(+), 2 deletions(-)
Index: milena/tests/core/graph_image.cc
--- milena/tests/core/graph_image.cc (revision 1753)
+++ milena/tests/core/graph_image.cc (working copy)
@@ -75,6 +75,7 @@
`-------*/
p_graph<point2d> pg(g);
+ g.print_debug(std::cout);
/*-------------.
| Graph image. |
Index: milena/mln/util/internal/graph_base.hh
--- milena/mln/util/internal/graph_base.hh (revision 1753)
+++ milena/mln/util/internal/graph_base.hh (working copy)
@@ -82,7 +82,7 @@
template<>
struct node<void>
{
- std::list<edge_id> edges;
+ std::vector<edge_id> edges;
};
@@ -386,7 +386,10 @@
n != nodes_.end (); ++n, ++i)
{
ostr << "node: " << i << std::endl << " -- adjacent nodes: ";
- for (typename edges_t::const_iterator e = (*n)->edges.begin();
+ /* FIXME: We shouldn't manipulate std::vector<edge_id>
+ directly, but use a typedef instead. */
+ for (typename std::vector<util::edge_id>::const_iterator e =
+ (*n)->edges.begin();
e != (*n)->edges.end(); ++e)
ostr << *e << " ";
ostr << std::endl;
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-02-26 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Split fllt.hh in my sanbox.
* sandbox/garrigues/fllt/compute_level_set.hh: New, compute the level sets.
* sandbox/garrigues/fllt/debug.hh: New, debug routines for FLLT.
* sandbox/garrigues/fllt/doc.hh: New, some comments from the monasse's paper.
* sandbox/garrigues/fllt/lower.hh: New, the struct used to compute the
lower level set.
* sandbox/garrigues/fllt/upper.hh: New, the struct used to compute the
upper level set.
* sandbox/garrigues/fllt/types.hh: New, type defined for FLLT.
* sandbox/garrigues/fllt/merge.hh: New, routines to merge the lower
level set and the upper level set.
* sandbox/garrigues/fllt/fllt.hh: Split this file.
* sandbox/garrigues/fllt/test_fllt10.cc: Update includes.
---
compute_level_set.hh | 410 ++++++++++++++++++++++++++++
debug.hh | 122 ++++++++
doc.hh | 90 ++++++
fllt.hh | 724 ---------------------------------------------------
lower.hh | 86 ++++++
merge.hh | 216 +++++++++++++++
test_fllt10.cc | 2
types.hh | 71 +++++
upper.hh | 85 +++++
9 files changed, 1090 insertions(+), 716 deletions(-)
Index: trunk/milena/sandbox/garrigues/fllt/test_fllt10.cc
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/test_fllt10.cc (revision 1752)
+++ trunk/milena/sandbox/garrigues/fllt/test_fllt10.cc (revision 1753)
@@ -1,4 +1,4 @@
-# include "fllt2.hh"
+# include "fllt.hh"
# include <mln/core/image2d.hh>
# include <mln/core/clone.hh>
# include <mln/value/int_u8.hh>
Index: trunk/milena/sandbox/garrigues/fllt/lower.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/lower.hh (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/lower.hh (revision 1753)
@@ -0,0 +1,86 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_FIXME_FLLT_LOWER_HH
+# define MLN_FIXME_FLLT_LOWER_HH
+
+/*! \file lower.hh
+ *
+ * \brief Lower level set for Fast level line transform.
+ *
+ */
+
+# include <mln/core/neighb2d.hh>
+# include <mln/labeling/regional_minima.hh>
+# include <mln/accu/min.hh>
+
+# include "upper.hh"
+
+namespace mln
+{
+ namespace fllt
+ {
+
+ //Fwd declarations.
+ template <typename V> struct lower;
+ template <typename V> struct upper;
+
+ // LOWER LEVEL SET : region = c4, border = c8
+ template <typename V>
+ struct lower
+ {
+ typedef upper<V> opposite;
+ static bool
+ compare(const V& u, const V& v)
+ {
+ return u < v;
+ }
+
+ template <typename I, typename N, typename L>
+ static mln_ch_value(I, L)
+ regional_extremum(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels)
+ {
+ return labeling::regional_minima(input, nbh, nlabels);
+ }
+
+ static const int inc = 1;
+ static const bool parent_is_brighter = true;
+ typedef accu::min accu_for_gn;
+
+ static const neighb2d& bdr_nbh() { return c8(); }
+ static const neighb2d& reg_nbh() { return c4(); }
+
+ };
+
+ } // end of namespace mln::fllt
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_FIXME_FLLT_LOWER_HH
Index: trunk/milena/sandbox/garrigues/fllt/upper.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/upper.hh (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/upper.hh (revision 1753)
@@ -0,0 +1,85 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_FIXME_FLLT_UPPER_HH
+# define MLN_FIXME_FLLT_UPPER_HH
+
+/*! \file upper.hh
+ *
+ * \brief Upper level set for Fast level line transform.
+ *
+ */
+
+# include <mln/core/neighb2d.hh>
+# include <mln/labeling/regional_maxima.hh>
+# include <mln/accu/max.hh>
+
+# include "lower.hh"
+
+namespace mln
+{
+ namespace fllt
+ {
+
+ //Fwd declarations.
+ template <typename V> struct lower;
+
+ // UPPER LEVEL SET : region = c8, border = c4
+ template <typename V>
+ struct upper
+ {
+ typedef lower<V> opposite;
+
+ static bool
+ compare(const V& u, const V& v)
+ {
+ return u > v;
+ }
+
+ template <typename I, typename N, typename L>
+ static mln_ch_value(I, L)
+ regional_extremum(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels)
+ {
+ return labeling::regional_maxima(input, nbh, nlabels);
+ }
+
+ static const int inc = -1;
+ static const bool parent_is_brighter = false;
+ typedef accu::max accu_for_gn;
+
+ static const neighb2d& bdr_nbh() { return c4(); }
+ static const neighb2d& reg_nbh() { return c8(); }
+ };
+
+ } // end of namespace mln::fllt
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_FIXME_FLLT_UPPER_HH
Index: trunk/milena/sandbox/garrigues/fllt/merge.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/merge.hh (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/merge.hh (revision 1753)
@@ -0,0 +1,216 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_FIXME_FLLT_MERGE_HH
+# define MLN_FIXME_FLLT_MERGE_HH
+
+/*! \file merge.hh
+ *
+ * \brief Merge for Fast level line transform.
+ *
+ */
+
+namespace mln
+{
+ namespace fllt
+ {
+
+
+ // Fwd declarations.
+ template <typename P, typename V, typename F>
+ void
+ fill_a_shape(fllt_node(P, V)& node,
+ fllt_tree(P, V)& tree,
+ const image2d<fllt_node(P, V)*>& node_reg,
+ const image2d<fllt_node(P, V)*>& hole_reg);
+
+ template <typename P, typename V, typename F>
+ void
+ move_shape(fllt_node(P, V)& node,
+ fllt_node(P, V)& hole,
+ fllt_tree(P, V)& tree,
+ const image2d<fllt_node(P, V)*>& hole_reg,
+ const image2d<fllt_node(P, V)*>& other_reg)
+ {
+ // FIXME : debug to remove.
+ // std::cout << " [move_shape] "<< &hole << " as son of "<< &node << std::endl;
+ //node.elt().points = set::uni(hole.elt().points, node.elt().points);
+ node.add_child(&hole);
+ fill_a_shape<P,V,typename F::opposite>(hole, tree, hole_reg, other_reg);
+ }
+
+ template <typename P, typename V, typename F>
+ fllt_node(P, V)*
+ find_the_hole(fllt_node(P, V)& node,
+ const P p,
+ const image2d<fllt_node(P, V)*>& other_reg)
+ {
+ fllt_node(P, V)* s = other_reg(p);
+ mln_assertion(s);
+ while (s->parent() && F::opposite::compare(s->parent()->elt().value, node.elt().value))
+ //FIXME : Was while (s->parent() && (s->parent()->elt().value < node.elt().value))
+ {
+ mln_assertion(s);
+ s = s->parent();
+ mln_assertion(s);
+ }
+// std::cout << " [Find the hole] of " << p
+// << " from " << &node
+// << " return " << s
+// << std::endl;
+ return s;
+ }
+
+ template <typename P, typename V, typename F>
+ void
+ fill_a_shape(fllt_node(P, V)& node,
+ fllt_tree(P, V)& tree,
+ const image2d<fllt_node(P, V)*>& node_reg,
+ const image2d<fllt_node(P, V)*>& hole_reg)
+ {
+// std::cout << "[Start fill_a_shape] " << &node << " "
+// << node.elt().holes.npoints()
+// << " holes." << std::endl;
+
+ if (node.elt().holes.npoints() == 0)
+ {
+ // std::cout << "[End fill_a_shape]" << std::endl;
+ return;
+ }
+ mln_piter(p_set<P>) p(node.elt().holes);
+ for_all(p)
+ {
+ bool h = true;
+
+ fllt_node(P, V)* hole;
+ if (node.elt().brighter == F::parent_is_brighter)
+ hole = find_the_hole<P,V,F>(node, point2d(p), hole_reg);
+ else
+ hole = find_the_hole<P,V,typename F::opposite>(node, point2d(p), node_reg);
+
+ mln_assertion(hole);
+
+ typename fllt_node(P, V)::children_t::iterator it;
+ for (it = node.children().begin();
+ it != node.children().end();
+ it++)
+ {
+ // Browse the hole of each child.
+ mln_piter(p_set<P>) q((*it)->elt().holes);
+ for_all(q)
+ {
+ fllt_node(P, V)* child_hole = find_the_hole<P,V,F>((**it), point2d(q), hole_reg);
+ if (set::is_subset_of(hole->elt().points,
+ child_hole->elt().points))
+
+// if (hole->elt().points < child_hole->elt().points)
+ {
+ h = false;
+ break;
+ }
+
+ }
+ if (!h)
+ break;
+ }
+ if (h)
+ move_shape<P,V,F>(node, *hole, tree, hole_reg, node_reg);
+ }
+
+ node.elt().holes.clear();
+ // std::cout << "[end fill_a_shape]" << std::endl;
+ }
+
+ template <typename P, typename V>
+ fllt_tree(P, V)
+ merge_trees(fllt_tree(P, V)& lower_tree,
+ fllt_tree(P, V)& upper_tree,
+ const image2d<fllt_node(P, V)*>& low_reg,
+ const image2d<fllt_node(P, V)*>& upp_reg,
+ const image2d<V>& ima)
+ {
+
+ // In order to merge the trees, we only have to find for each shape S
+ // with a hole H in it whether one of its children has a hole HŽ
+ // containing H. If it is the case, we do nothing. Otherwise, we
+ // put the shape of the hole H (and all its descendants) as child of
+ // the shape .
+ {
+ std::cout << "[Merge first tree]------------" << std::endl;
+
+ fllt_branch_iter_ind(P, V) p(lower_tree.main_branch());
+ for_all(p)
+ {
+ fllt_node(P, V)& n(p);
+ fill_a_shape< P, V, lower<V> >(n, lower_tree, low_reg, upp_reg);
+ mln_assertion(lower_tree.check_consistency());
+ mln_assertion(upper_tree.check_consistency());
+ }
+
+ }
+
+ {
+ std::cout << "[Merge second tree]------------" << std::endl;
+
+ fllt_branch_iter_ind(P, V) p(upper_tree.main_branch());
+ for_all(p)
+ {
+ fllt_node(P, V)& n(p);
+ fill_a_shape< P, V, upper<V> >(n, upper_tree, upp_reg, low_reg);
+ mln_assertion(lower_tree.check_consistency());
+ mln_assertion(upper_tree.check_consistency());
+ }
+ }
+
+ fllt_tree(P, V)* main_tree = &lower_tree;
+ fllt_tree(P, V)* other_tree = &upper_tree;
+
+ if (lower_tree.root()->elt().points.npoints() >= ima.domain().npoints())
+ {
+ main_tree = &upper_tree;
+ other_tree = &lower_tree;
+ }
+
+ typename fllt_node(P, V)::children_t::iterator it;
+ for (it = other_tree->root()->children().begin();
+ it != other_tree->root()->children().end(); )
+ {
+ main_tree->root()->add_child(*it);
+ }
+ mln_assertion(main_tree->check_consistency());
+ return *main_tree;
+ }
+
+
+ } // end of namespace mln::fllt
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_FIXME_FLLT_MERGE_HH
Index: trunk/milena/sandbox/garrigues/fllt/types.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/types.hh (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/types.hh (revision 1753)
@@ -0,0 +1,71 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_FIXME_FLLT_TYPES_HH
+# define MLN_FIXME_FLLT_TYPES_HH
+
+/*! \file types.hh
+ *
+ * \brief Types for Fast level line transform.
+ *
+ */
+
+# include <mln/core/p_set.hh>
+# include <mln/util/tree.hh>
+# include <mln/util/branch_iter_ind.hh>
+
+namespace mln
+{
+ namespace fllt
+ {
+
+ template <typename P, typename V>
+ struct fllt_node_elt
+ {
+ V value;
+ p_set<P> points;
+ p_set<P> holes;
+ /// Tell if his parent if brighter or not. Nb : if the parent
+ /// if brighter, the node come from the lower level set
+ bool brighter;
+ };
+
+# define fllt_tree(P, V) util::tree< fllt_node_elt<P, V> >
+# define fllt_node(P, V) util::tree_node< fllt_node_elt<P, V> >
+# define fllt_branch(P, V) util::branch< fllt_node_elt<P, V> >
+# define fllt_branch_iter_ind(P, V) util::branch_iter_ind< fllt_node_elt<P, V> >
+
+ // # define fllt_node(P, V) typename fllt_tree(P, V)::node_t
+
+ } // end of namespace mln::fllt
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_FIXME_FLLT_TYPES_HH
Index: trunk/milena/sandbox/garrigues/fllt/doc.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/doc.hh (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/doc.hh (revision 1753)
@@ -0,0 +1,90 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_FIXME_FLLT_DOC_HH
+# define MLN_FIXME_FLLT_DOC_HH
+
+/*! \file doc.hh
+ *
+ * \brief Compute Level Set for Fast level line transform.
+ *
+ */
+
+namespace mln
+{
+ namespace fllt
+ {
+
+
+ // LOWER LEVEL SET : region = c4, border = c8
+ // UPPER LEVEL SET : region = c8, border = c4
+
+ // 1)
+ // x0 <- a not tagged local mininum of ima.
+ // g <- u(x0)
+
+ // 2)
+ // A <- {x0}
+ // R <- {}
+ // N <- {}
+
+ // 3)
+ // N <- N union {x neighbor of a pixel in a}
+ // gn <- min u(x) x belongs to N.
+ // R <- R union A
+ // tag the pixels of A.
+
+ // 4)
+ // IF g < gn
+ // IF number of conected components of the border > 1
+ // follow each border to find which is the exterior border
+ // and which are the holes. Keep one pixel of each holes.
+ //
+ // Remove from N border of holes.
+ // Recompute gn <- min u(x) x belongs to A
+ //
+ // g <- gn
+ // A <- {x belongs to N / u(x) == g}
+ // N <- N\{x belongs to N / u(x) == g}
+ // GO TO 3)
+ // IF g == gn
+ // A <- {x belongs to N / u(x) == g}
+ // N <- N\{x belongs to N / u(x) == g}
+ // GO TO 3)
+ // IF g > gn
+ // set the gray-level of the pixels of R to g.
+ // GO TO 1)
+
+
+ } // end of namespace mln::fllt
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_FIXME_FLLT_DOC_HH
Index: trunk/milena/sandbox/garrigues/fllt/debug.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/debug.hh (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/debug.hh (revision 1753)
@@ -0,0 +1,122 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_FIXME_FLLT_DEBUG_HH
+# define MLN_FIXME_FLLT_DEBUG_HH
+
+/*! \file debug.hh
+ *
+ * \brief Debug for Fast level line transform.
+ *
+ */
+
+# include "types.hh"
+
+namespace mln
+{
+ namespace fllt
+ {
+
+
+ template <typename P, typename V>
+ void
+ visualize_deepness(image2d<value::int_u8>& output,
+ fllt_tree(P, V)& tree)
+ {
+ fllt_branch_iter_ind(P, V) p(tree.main_branch());
+ level::fill(output, 0);
+ for_all(p)
+ {
+ //std::cout << (&*p) << ":" << p.deepness() << std::endl;
+ mln_piter(p_set<point2d>) q((*p).elt().points);
+ for_all(q)
+ {
+ if (output(q) < p.deepness())
+ output(q) = p.deepness();
+ }
+ }
+ }
+
+
+ template <typename P, typename V>
+ void
+ visualize_bounds(image2d<value::int_u8>& output,
+ fllt_tree(P, V)& tree,
+ unsigned limit)
+ {
+ fllt_branch_iter_ind(P, V) p(tree.main_branch());
+ level::fill(output, 255);
+ for_all(p)
+ {
+ if ((*p).elt().points.npoints() > limit)
+ {
+ mln_piter(p_set<point2d>) q((*p).elt().points);
+ for_all(q)
+ {
+ mln_niter(neighb2d) n(c4(), q);
+ bool is_border = false;
+ for_all (n)
+ if (!((*p).elt().points).has (n))
+ is_border = true;
+ if (is_border)
+ output(q) = 0;
+ }
+ }
+ }
+ }
+
+ template <typename P, typename V>
+ void
+ draw_tree(const image2d<V>& ima,
+ fllt_tree(P, V)& tree)
+ {
+ fllt_branch_iter_ind(P, V) p(tree.main_branch());
+ for_all(p)
+ {
+ std::cout << "region mere : " << (*p).parent() << std::endl;
+ std::cout << " ^" << std::endl;
+ std::cout << " |" << std::endl;
+ std::cout << "region : " << &*p
+ << " value = " << (*p).elt().value << std::endl
+ << " holes : "
+ << (*p).elt().holes.npoints()
+ << (*p).elt().holes
+ << std::endl;
+
+ debug::println(ima | (*p).elt().points);
+ std::cout << std::endl;
+ }
+ }
+
+ } // end of namespace mln::fllt
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_FIXME_FLLT_DEBUG_HH
Index: trunk/milena/sandbox/garrigues/fllt/fllt.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/fllt.hh (revision 1752)
+++ trunk/milena/sandbox/garrigues/fllt/fllt.hh (revision 1753)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -78,725 +78,19 @@
# include <mln/level/compare.hh>
# include <mln/io/pgm/save.hh>
-namespace mln
-{
- namespace fllt
- {
-
- template <typename P, typename V>
- struct fllt_node_elt
- {
- V value;
- p_set<P> points;
- p_set<P> holes;
- /// Tell if his parent if brighter or not. Nb : if the parent
- /// if brighter, the node come from the lower level set
- bool brighter;
- };
-
-# define fllt_tree(P, V) util::tree< fllt_node_elt<P, V> >
-# define fllt_node(P, V) util::tree_node< fllt_node_elt<P, V> >
-# define fllt_branch(P, V) util::branch< fllt_node_elt<P, V> >
-# define fllt_branch_iter_ind(P, V) util::branch_iter_ind< fllt_node_elt<P, V> >
-
- // # define fllt_node(P, V) typename fllt_tree(P, V)::node_t
-
-
-
- // LOWER LEVEL SET : region = c4, border = c8
- // UPPER LEVEL SET : region = c8, border = c4
-
- // 1)
- // x0 <- a not tagged local mininum of ima.
- // g <- u(x0)
-
- // 2)
- // A <- {x0}
- // R <- {}
- // N <- {}
-
- // 3)
- // N <- N union {x neighbor of a pixel in a}
- // gn <- min u(x) x belongs to N.
- // R <- R union A
- // tag the pixels of A.
-
- // 4)
- // IF g < gn
- // IF number of conected components of the border > 1
- // follow each border to find which is the exterior border
- // and which are the holes. Keep one pixel of each holes.
- //
- // Remove from N border of holes.
- // Recompute gn <- min u(x) x belongs to A
- //
- // g <- gn
- // A <- {x belongs to N / u(x) == g}
- // N <- N\{x belongs to N / u(x) == g}
- // GO TO 3)
- // IF g == gn
- // A <- {x belongs to N / u(x) == g}
- // N <- N\{x belongs to N / u(x) == g}
- // GO TO 3)
- // IF g > gn
- // set the gray-level of the pixels of R to g.
- // GO TO 1)
-
- template <typename V>
- void step1 (const image2d<V>& ima,
- point2d p,
- V& g,
- point2d& x0)
- {
- //std::cout << "entering step 1" << std::endl;
- // x0 <- a not tagged local mininum of ima.
- //std::cout << std::endl << "x0 = " << p << std::endl;
- x0 = p;
- // g <- u(x0)
- g = ima(x0);
- //std::cout << "g = " << g << std::endl;
- //std::cout << "exiting step 1" << std::endl;
- }
-
- template <typename P>
- void step2 (p_set<P>& A,
- p_set<P>& R,
- p_set<P>& N,
- point2d& x0)
- {
- //std::cout << "entering step 2" << std::endl;
- // A <- {x0}
- A.clear();
- A.insert(x0);
- // R <- {}
- R.clear();
- // N <- {}
- N.clear();
- //std::cout << "exiting step 2" << std::endl;
- }
-
-
- template <typename V, typename P, typename F>
- void step3 (const image2d<V>& u,
- image2d<bool>& tagged,
- p_set<P>& A,
- p_set<P>& R,
- p_set<P>& N,
- V& gn)
- {
- static bool finished = false;
- //std::cout << "entering step 3" << std::endl;
-
- // Stop the algorithm.
- if (finished)
- { finished = false; gn -= 2 * F::inc; return; }
-
- // N <- N union {x neighbor of a pixel in a\R}
- mln_piter(p_set<P>) qa(A);
- for_all(qa)
- {
- mln_niter(neighb2d) n(F::reg_nbh(), qa);
- for_all (n)
- if (!R.has (n))
- N.insert (n);
- }
-
- // debug::println(u);
-
- // //std::cout << "A :" << std::endl;
- // if (A.npoints())
- // //debug::println(u | A);
- // //std::cout << "N :" << std::endl;
- // if (N.npoints())
- // //debug::println(u | N);
- // //std::cout << "R :" << std::endl;
- // if (R.npoints())
- // //debug::println(u | R);
-
- // gn <- min u(x) x belongs to N.
- if ((u | set::inter(N, u.domain())).npoints() > 0)
- gn = level::compute< typename F::accu_for_gn >(u | set::inter(N, u.domain()));
- else
- {
- finished = true;
- gn += F::inc;
- }
- //std::cout << std::endl << "gN = " << gn << std::endl;
- // R <- R union A
- // tag the pixels of A.
-
- for_all(qa)
- {
- R.insert(qa);
- tagged(qa) = true;
- }
- //std::cout << "exiting step 3" << std::endl;
- }
-
-
- /// IF g < gn.
- template <typename V, typename P, typename F>
- void step4_1 (image2d<V>& u,
- p_set<P>& A,
- p_set<P>& R,
- p_set<P>& N,
- V& g,
- V& gn,
- fllt_node(P, V)*& current_region,
- image2d<fllt_node(P, V)*>& regions
- )
- {
- //std::cout << "entering step 4_1" << std::endl;
-
- // If the region is bounded
- // Create a new conected component.
- // FIXME : we can make it faster.
-
- if ((R.bbox() < u.domain()) || (R.npoints() == u.domain().npoints()))
- {
- mln_piter(p_set<P>) p(R);
- current_region = new fllt_node(P, V)();
- current_region->elt().brighter = F::parent_is_brighter;
- current_region->elt().value = g;
- for_all(p)
- {
- current_region->elt().points.insert(p);
-
- if (regions(p) == 0)
- {
- //current_region->elt().points.insert(p);
- regions(p) = current_region;
- }
- else
- {
- if (regions(p)->parent() == 0)
- regions(p)->set_parent(current_region);
- }
- }
-
-
- // Count the number of conected components of the border of R.
- static image2d<unsigned> tmp(u.domain().to_larger(1));
- static image2d<bool> border_ima(tmp.domain());
- level::fill(border_ima, false);
-
- // level::fill(inplace(border_ima | N), true);
- // std::cout << "tmp border = " << tmp.border () << std::endl;
- // std::cout << "ima border = " << border_ima.border () << std::endl;
- mln_piter(p_set<P>) z(N);
- for_all(z)
- {
- mln_assertion(border_ima.owns_(z));
- border_ima(z) = true;
- }
- unsigned n;
- tmp = labeling::level(border_ima, true, F::bdr_nbh(), n);
-
- // debug::println(border_ima);
- //std::cout << "nb composantes :" << n << std::endl;
- // debug::println(tmp);
- if (n > 1)
- {
-
- // IF number of conected components of the border > 1
- for (int i = 2; i <= n; i++)
- {
- // follow each border to find which is the exterior border
- // and which are the holes. Keep one pixel of each holes.
-
- // WARNING : We trust labeling::level to label the exterior border with 1.
- current_region->elt().holes.insert(a_point_of(tmp | pw::value(tmp) == pw::cst(i)));
-
- // FIXME : [optimisation] Remove from N border of holes???.
- // Recompute gn <- min u(x) x belongs to A
- }
- }
-
- }
- g = gn;
- // A <- {x belongs to N / u(x) == g}
- A.clear();
- A = set::uni(A, set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
- // N <- N\{x belongs to N / u(x) == g}
- N = set::diff(N, set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
-
- // std::cout << "A :" << std::endl;
- // if (A.npoints())
- // debug::println(u | A);
- // std::cout << "N :" << std::endl;
- // if (N.npoints())
- // debug::println(u | N);
-
- //std::cout << "exiting step 4_1" << std::endl;
- }
-
-
- /// IF g == gn.
- template <typename V, typename P>
- void step4_2 (const image2d<V>& u,
- p_set<P>& A,
- p_set<P>& N,
- V& g,
- fllt_node(P, V)* current_region,
- image2d<fllt_node(P, V)*>& regions
- )
- {
- //std::cout << "entering step 4_2" << std::endl;
-
- // A <- {x belongs to N / u(x) == g}
- A = set::uni(A, set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
- // N <- N\{x belongs to N / u(x) == g}
- N = set::diff(N, set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
-
- // std::cout << "A :" << std::endl;
- // if (A.npoints())
- // debug::println(u | A);
- // std::cout << "N :" << std::endl;
- // if (N.npoints())
- // debug::println(u | N);
-
- //std::cout << "exiting step 4_2" << std::endl;
- }
-
- /// IF g > gn.
- template <typename V, typename P>
- void step4_3 (image2d<V>& u,
- const image2d<bool>& tagged,
- const p_set<P>& R,
- const V& g)
- {
- //std::cout << "entering step 4_3" << std::endl;
-
- // set the gray-level of the pixels of R to g.
- mln_piter(p_set<P>) p(R);
- for_all(p)
- {
- mln_assertion (tagged(p));
- u (p) = g;
- }
-
- //std::cout << "exiting step 4_3" << std::endl;
-
- }
-
-
- template <typename V, typename F>
- fllt_tree(point2d, V)&
- compute_level_set(const image2d<V>& ima,
- image2d< fllt_node(point2d, V)* >& regions)
- {
- typedef point2d P;
- typedef image2d<V> I;
-
- // FIXME: not nice.
- typedef mln::image_if<
- mln::image2d<unsigned>,
- mln::fun::greater_p2b_expr_<mln::pw::value_<mln::image2d<unsigned> >,
- mln::pw::cst_<int> >
- > I_IF;
-
- // Check
- mln_assertion(ima.domain() == regions.domain());
-
- // Declarations.
- p_set<P> R, N, A;
- V g, gn;
- point2d x0;
- image2d<unsigned> min_locals(ima.domain());
- image2d<V> u = clone(ima);
- border::fill(u, 0);
-
- //std::cout << "image U:" << std::endl;
- // debug::println_with_border(u);
- image2d<bool> tagged(ima.domain());
- fllt_node(P, V)* current_region;
-
- // INIT
- R.clear();
- N.clear();
- A.clear();
- g= 0;
- gn = 0;
- current_region = 0;
-
- level::fill(regions, 0);
- level::fill(tagged, false);
-
- // Get the locals extremums
- unsigned nlabels;
- min_locals = F::regional_extremum(ima, F::reg_nbh(), nlabels);
-
- // debug::println(min_locals);
- // debug::println(min_locals | (pw::value(min_locals) > pw::cst(0)));
-
- /// Algorithm.
- {
- // For all locals extremums
- //void* x = min_locals | (pw::value(min_locals) > pw::cst(0));
- I_IF min_locals_list(min_locals | (pw::value(min_locals) > pw::cst(0)));
- mln_piter(I_IF) p(min_locals_list.domain());
- for_all(p)
- {
- if (tagged(p))
- continue;
-
- step1(ima, p, g, x0);
- step2(A, R, N, x0);
- while (1)
- {
- //std::cout << "g = " << g << std::endl;
- step3<V, P, F>(u, tagged, A, R, N, gn);
- /// step4.
- if (F::compare(g, gn))
- {
- step4_1<V, P, F>(u, A, R, N, g, gn, current_region, regions);
- // GO TO 3)
- continue;
- }
-
-
- if (g == gn)
- {
- step4_2(u, A, N, g, current_region, regions);
- // GO TO 3)
- continue;
- }
-
-
- if (!F::compare(g, gn))
- {
- step4_3(u, tagged, R, g);
- // GO TO 1)
- break;
- }
- }
- //std::cout << "current_region = " << current_region << std::endl;
- }
- } // end of Algorithm
-
- image2d<value::int_u8> output (ima.domain ());
- fllt_tree(P, V)& tree = *new fllt_tree(P, V)(current_region);
- util::tree_to_image (tree, output);
-
- // util::display_tree(ima, tree);
-
- // debug::println(output);
- // std::cout << std::endl;
- // debug::println(ima);
-
- // if (output != ima)
- // {
- // std::cerr << "BUG!!!" << std::endl;
- // abort();
- // }
-
- // io::pgm::save(output, "out.pgm");
- // std::cout << "out.pgm generate"
- // << std::endl;
-
-
- // debug::println(regions);
- //debug::println(ima | regions(make:defined reference to `mln::fllt::lower<mln::value::int_u<8u> >::inc':point2d(-4,-1))->elt().points);
-
- return (tree);
-
- } // end of compute_level_set
-
- //Fwd declarations.
- template <typename V> struct lower;
- template <typename V> struct upper;
-
- // LOWER LEVEL SET : region = c4, border = c8
- template <typename V>
- struct lower
- {
- typedef upper<V> opposite;
- static bool
- compare(const V& u, const V& v)
- {
- return u < v;
- }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels)
- {
- return labeling::regional_minima(input, nbh, nlabels);
- }
-
- static const int inc = 1;
- static const bool parent_is_brighter = true;
- typedef accu::min accu_for_gn;
-
- static const neighb2d& bdr_nbh() { return c8(); }
- static const neighb2d& reg_nbh() { return c4(); }
-
- };
-
-
+# include "types.hh"
+# include "debug.hh"
- // UPPER LEVEL SET : region = c8, border = c4
- template <typename V>
- struct upper
- {
- typedef lower<V> opposite;
+# include "lower.hh"
+# include "upper.hh"
- static bool
- compare(const V& u, const V& v)
- {
- return u > v;
- }
-
- template <typename I, typename N, typename L>
- static mln_ch_value(I, L)
- regional_extremum(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels)
- {
- return labeling::regional_maxima(input, nbh, nlabels);
- }
+# include "compute_level_set.hh"
+# include "merge.hh"
- static const int inc = -1;
- static const bool parent_is_brighter = false;
- typedef accu::max accu_for_gn;
-
- static const neighb2d& bdr_nbh() { return c4(); }
- static const neighb2d& reg_nbh() { return c8(); }
- };
-
- // Fwd declarations.
- template <typename P, typename V, typename F>
- void
- fill_a_shape(fllt_node(P, V)& node,
- fllt_tree(P, V)& tree,
- const image2d<fllt_node(P, V)*>& node_reg,
- const image2d<fllt_node(P, V)*>& hole_reg);
-
- template <typename P, typename V, typename F>
- void
- move_shape(fllt_node(P, V)& node,
- fllt_node(P, V)& hole,
- fllt_tree(P, V)& tree,
- const image2d<fllt_node(P, V)*>& hole_reg,
- const image2d<fllt_node(P, V)*>& other_reg)
- {
- // FIXME : debug to remove.
- // std::cout << " [move_shape] "<< &hole << " as son of "<< &node << std::endl;
- //node.elt().points = set::uni(hole.elt().points, node.elt().points);
- node.add_child(&hole);
- fill_a_shape<P,V,typename F::opposite>(hole, tree, hole_reg, other_reg);
- }
-
- template <typename P, typename V, typename F>
- fllt_node(P, V)*
- find_the_hole(fllt_node(P, V)& node,
- const P p,
- const image2d<fllt_node(P, V)*>& other_reg)
- {
- fllt_node(P, V)* s = other_reg(p);
- mln_assertion(s);
- while (s->parent() && F::opposite::compare(s->parent()->elt().value, node.elt().value))
- //FIXME : Was while (s->parent() && (s->parent()->elt().value < node.elt().value))
- {
- mln_assertion(s);
- s = s->parent();
- mln_assertion(s);
- }
-// std::cout << " [Find the hole] of " << p
-// << " from " << &node
-// << " return " << s
-// << std::endl;
- return s;
- }
-
- template <typename P, typename V, typename F>
- void
- fill_a_shape(fllt_node(P, V)& node,
- fllt_tree(P, V)& tree,
- const image2d<fllt_node(P, V)*>& node_reg,
- const image2d<fllt_node(P, V)*>& hole_reg)
- {
-// std::cout << "[Start fill_a_shape] " << &node << " "
-// << node.elt().holes.npoints()
-// << " holes." << std::endl;
-
- if (node.elt().holes.npoints() == 0)
- {
- // std::cout << "[End fill_a_shape]" << std::endl;
- return;
- }
- mln_piter(p_set<P>) p(node.elt().holes);
- for_all(p)
- {
- bool h = true;
-
- fllt_node(P, V)* hole;
- if (node.elt().brighter == F::parent_is_brighter)
- hole = find_the_hole<P,V,F>(node, point2d(p), hole_reg);
- else
- hole = find_the_hole<P,V,typename F::opposite>(node, point2d(p), node_reg);
-
- mln_assertion(hole);
-
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = node.children().begin();
- it != node.children().end();
- it++)
- {
- // Browse the hole of each child.
- mln_piter(p_set<P>) q((*it)->elt().holes);
- for_all(q)
- {
- fllt_node(P, V)* child_hole = find_the_hole<P,V,F>((**it), point2d(q), hole_reg);
- if (set::is_subset_of(hole->elt().points,
- child_hole->elt().points))
-
-// if (hole->elt().points < child_hole->elt().points)
- {
- h = false;
- break;
- }
-
- }
- if (!h)
- break;
- }
- if (h)
- move_shape<P,V,F>(node, *hole, tree, hole_reg, node_reg);
- }
-
- node.elt().holes.clear();
- // std::cout << "[end fill_a_shape]" << std::endl;
- }
-
- template <typename P, typename V>
- fllt_tree(P, V)
- merge_trees(fllt_tree(P, V)& lower_tree,
- fllt_tree(P, V)& upper_tree,
- const image2d<fllt_node(P, V)*>& low_reg,
- const image2d<fllt_node(P, V)*>& upp_reg,
- const image2d<V>& ima)
- {
-
- // In order to merge the trees, we only have to find for each shape S
- // with a hole H in it whether one of its children has a hole HŽ
- // containing H. If it is the case, we do nothing. Otherwise, we
- // put the shape of the hole H (and all its descendants) as child of
- // the shape .
- {
- std::cout << "[Merge first tree]------------" << std::endl;
-
- fllt_branch_iter_ind(P, V) p(lower_tree.main_branch());
- for_all(p)
- {
- fllt_node(P, V)& n(p);
- fill_a_shape< P, V, lower<V> >(n, lower_tree, low_reg, upp_reg);
- mln_assertion(lower_tree.check_consistency());
- mln_assertion(upper_tree.check_consistency());
- }
-
- }
-
- {
- std::cout << "[Merge second tree]------------" << std::endl;
-
- fllt_branch_iter_ind(P, V) p(upper_tree.main_branch());
- for_all(p)
- {
- fllt_node(P, V)& n(p);
- fill_a_shape< P, V, upper<V> >(n, upper_tree, upp_reg, low_reg);
- mln_assertion(lower_tree.check_consistency());
- mln_assertion(upper_tree.check_consistency());
- }
- }
-
- fllt_tree(P, V)* main_tree = &lower_tree;
- fllt_tree(P, V)* other_tree = &upper_tree;
-
- if (lower_tree.root()->elt().points.npoints() >= ima.domain().npoints())
- {
- main_tree = &upper_tree;
- other_tree = &lower_tree;
- }
-
- typename fllt_node(P, V)::children_t::iterator it;
- for (it = other_tree->root()->children().begin();
- it != other_tree->root()->children().end(); )
- {
- main_tree->root()->add_child(*it);
- }
- mln_assertion(main_tree->check_consistency());
- return *main_tree;
- }
-
-
- template <typename P, typename V>
- void
- visualize_deepness(image2d<value::int_u8>& output,
- fllt_tree(P, V)& tree)
- {
- fllt_branch_iter_ind(P, V) p(tree.main_branch());
- level::fill(output, 0);
- for_all(p)
- {
- //std::cout << (&*p) << ":" << p.deepness() << std::endl;
- mln_piter(p_set<point2d>) q((*p).elt().points);
- for_all(q)
- {
- if (output(q) < p.deepness())
- output(q) = p.deepness();
- }
- }
- }
-
-
- template <typename P, typename V>
- void
- visualize_bounds(image2d<value::int_u8>& output,
- fllt_tree(P, V)& tree,
- unsigned limit)
- {
- fllt_branch_iter_ind(P, V) p(tree.main_branch());
- level::fill(output, 255);
- for_all(p)
- {
- if ((*p).elt().points.npoints() > limit)
- {
- mln_piter(p_set<point2d>) q((*p).elt().points);
- for_all(q)
- {
- mln_niter(neighb2d) n(c4(), q);
- bool is_border = false;
- for_all (n)
- if (!((*p).elt().points).has (n))
- is_border = true;
- if (is_border)
- output(q) = 0;
- }
- }
- }
- }
-
- template <typename P, typename V>
- void
- draw_tree(const image2d<V>& ima,
- fllt_tree(P, V)& tree)
+namespace mln
{
- fllt_branch_iter_ind(P, V) p(tree.main_branch());
- for_all(p)
+ namespace fllt
{
- std::cout << "region mere : " << (*p).parent() << std::endl;
- std::cout << " ^" << std::endl;
- std::cout << " |" << std::endl;
- std::cout << "region : " << &*p
- << " value = " << (*p).elt().value << std::endl
- << " holes : "
- << (*p).elt().holes.npoints()
- << (*p).elt().holes
- << std::endl;
-
- debug::println(ima | (*p).elt().points);
- std::cout << std::endl;
- }
- }
template <typename V>
// Fixme : return type
Index: trunk/milena/sandbox/garrigues/fllt/compute_level_set.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/compute_level_set.hh (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/compute_level_set.hh (revision 1753)
@@ -0,0 +1,410 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_FIXME_FLLT_COMPUTE_LEVEL_SET_HH
+# define MLN_FIXME_FLLT_COMPUTE_LEVEL_SET_HH
+
+/*! \file compute_level_set.hh
+ *
+ * \brief Compute Level Set for Fast level line transform.
+ *
+ */
+
+namespace mln
+{
+ namespace fllt
+ {
+
+
+ template <typename V>
+ void step1 (const image2d<V>& ima,
+ point2d p,
+ V& g,
+ point2d& x0)
+ {
+ //std::cout << "entering step 1" << std::endl;
+ // x0 <- a not tagged local mininum of ima.
+ //std::cout << std::endl << "x0 = " << p << std::endl;
+ x0 = p;
+ // g <- u(x0)
+ g = ima(x0);
+ //std::cout << "g = " << g << std::endl;
+ //std::cout << "exiting step 1" << std::endl;
+ }
+
+ template <typename P>
+ void step2 (p_set<P>& A,
+ p_set<P>& R,
+ p_set<P>& N,
+ point2d& x0)
+ {
+ //std::cout << "entering step 2" << std::endl;
+ // A <- {x0}
+ A.clear();
+ A.insert(x0);
+ // R <- {}
+ R.clear();
+ // N <- {}
+ N.clear();
+ //std::cout << "exiting step 2" << std::endl;
+ }
+
+
+ template <typename V, typename P, typename F>
+ void step3 (const image2d<V>& u,
+ image2d<bool>& tagged,
+ p_set<P>& A,
+ p_set<P>& R,
+ p_set<P>& N,
+ V& gn)
+ {
+ static bool finished = false;
+ //std::cout << "entering step 3" << std::endl;
+
+ // Stop the algorithm.
+ if (finished)
+ { finished = false; gn -= 2 * F::inc; return; }
+
+ // N <- N union {x neighbor of a pixel in a\R}
+ mln_piter(p_set<P>) qa(A);
+ for_all(qa)
+ {
+ mln_niter(neighb2d) n(F::reg_nbh(), qa);
+ for_all (n)
+ if (!R.has (n))
+ N.insert (n);
+ }
+
+ // debug::println(u);
+
+ // //std::cout << "A :" << std::endl;
+ // if (A.npoints())
+ // //debug::println(u | A);
+ // //std::cout << "N :" << std::endl;
+ // if (N.npoints())
+ // //debug::println(u | N);
+ // //std::cout << "R :" << std::endl;
+ // if (R.npoints())
+ // //debug::println(u | R);
+
+ // gn <- min u(x) x belongs to N.
+ if ((u | set::inter(N, u.domain())).npoints() > 0)
+ gn = level::compute< typename F::accu_for_gn >(u | set::inter(N, u.domain()));
+ else
+ {
+ finished = true;
+ gn += F::inc;
+ }
+ //std::cout << std::endl << "gN = " << gn << std::endl;
+ // R <- R union A
+ // tag the pixels of A.
+
+ for_all(qa)
+ {
+ R.insert(qa);
+ tagged(qa) = true;
+ }
+ //std::cout << "exiting step 3" << std::endl;
+ }
+
+
+ /// IF g < gn.
+ template <typename V, typename P, typename F>
+ void step4_1 (image2d<V>& u,
+ p_set<P>& A,
+ p_set<P>& R,
+ p_set<P>& N,
+ V& g,
+ V& gn,
+ fllt_node(P, V)*& current_region,
+ image2d<fllt_node(P, V)*>& regions
+ )
+ {
+ //std::cout << "entering step 4_1" << std::endl;
+
+ // If the region is bounded
+ // Create a new conected component.
+ // FIXME : we can make it faster.
+
+ if ((R.bbox() < u.domain()) || (R.npoints() == u.domain().npoints()))
+ {
+ mln_piter(p_set<P>) p(R);
+ current_region = new fllt_node(P, V)();
+ current_region->elt().brighter = F::parent_is_brighter;
+ current_region->elt().value = g;
+ for_all(p)
+ {
+ current_region->elt().points.insert(p);
+
+ if (regions(p) == 0)
+ {
+ //current_region->elt().points.insert(p);
+ regions(p) = current_region;
+ }
+ else
+ {
+ if (regions(p)->parent() == 0)
+ regions(p)->set_parent(current_region);
+ }
+ }
+
+
+ // Count the number of conected components of the border of R.
+ static image2d<unsigned> tmp(u.domain().to_larger(1));
+ static image2d<bool> border_ima(tmp.domain());
+ level::fill(border_ima, false);
+
+ // level::fill(inplace(border_ima | N), true);
+ // std::cout << "tmp border = " << tmp.border () << std::endl;
+ // std::cout << "ima border = " << border_ima.border () << std::endl;
+ mln_piter(p_set<P>) z(N);
+ for_all(z)
+ {
+ mln_assertion(border_ima.owns_(z));
+ border_ima(z) = true;
+ }
+ unsigned n;
+ tmp = labeling::level(border_ima, true, F::bdr_nbh(), n);
+
+ // debug::println(border_ima);
+ //std::cout << "nb composantes :" << n << std::endl;
+ // debug::println(tmp);
+ if (n > 1)
+ {
+
+ // IF number of conected components of the border > 1
+ for (int i = 2; i <= n; i++)
+ {
+ // follow each border to find which is the exterior border
+ // and which are the holes. Keep one pixel of each holes.
+
+ // WARNING : We trust labeling::level to label the exterior border with 1.
+ current_region->elt().holes.insert(a_point_of(tmp | pw::value(tmp) == pw::cst(i)));
+
+ // FIXME : [optimisation] Remove from N border of holes???.
+ // Recompute gn <- min u(x) x belongs to A
+ }
+ }
+
+ }
+ g = gn;
+ // A <- {x belongs to N / u(x) == g}
+ A.clear();
+ A = set::uni(A, set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
+ // N <- N\{x belongs to N / u(x) == g}
+ N = set::diff(N, set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
+
+ // std::cout << "A :" << std::endl;
+ // if (A.npoints())
+ // debug::println(u | A);
+ // std::cout << "N :" << std::endl;
+ // if (N.npoints())
+ // debug::println(u | N);
+
+ //std::cout << "exiting step 4_1" << std::endl;
+ }
+
+
+ /// IF g == gn.
+ template <typename V, typename P>
+ void step4_2 (const image2d<V>& u,
+ p_set<P>& A,
+ p_set<P>& N,
+ V& g,
+ fllt_node(P, V)* current_region,
+ image2d<fllt_node(P, V)*>& regions
+ )
+ {
+ //std::cout << "entering step 4_2" << std::endl;
+
+ // A <- {x belongs to N / u(x) == g}
+ A = set::uni(A, set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
+ // N <- N\{x belongs to N / u(x) == g}
+ N = set::diff(N, set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
+
+ // std::cout << "A :" << std::endl;
+ // if (A.npoints())
+ // debug::println(u | A);
+ // std::cout << "N :" << std::endl;
+ // if (N.npoints())
+ // debug::println(u | N);
+
+ //std::cout << "exiting step 4_2" << std::endl;
+ }
+
+ /// IF g > gn.
+ template <typename V, typename P>
+ void step4_3 (image2d<V>& u,
+ const image2d<bool>& tagged,
+ const p_set<P>& R,
+ const V& g)
+ {
+ //std::cout << "entering step 4_3" << std::endl;
+
+ // set the gray-level of the pixels of R to g.
+ mln_piter(p_set<P>) p(R);
+ for_all(p)
+ {
+ mln_assertion (tagged(p));
+ u (p) = g;
+ }
+
+ //std::cout << "exiting step 4_3" << std::endl;
+
+ }
+
+
+ template <typename V, typename F>
+ fllt_tree(point2d, V)&
+ compute_level_set(const image2d<V>& ima,
+ image2d< fllt_node(point2d, V)* >& regions)
+ {
+ typedef point2d P;
+ typedef image2d<V> I;
+
+ // FIXME: not nice.
+ typedef mln::image_if<
+ mln::image2d<unsigned>,
+ mln::fun::greater_p2b_expr_<mln::pw::value_<mln::image2d<unsigned> >,
+ mln::pw::cst_<int> >
+ > I_IF;
+
+ // Check
+ mln_assertion(ima.domain() == regions.domain());
+
+ // Declarations.
+ p_set<P> R, N, A;
+ V g, gn;
+ point2d x0;
+ image2d<unsigned> min_locals(ima.domain());
+ image2d<V> u = clone(ima);
+ border::fill(u, 0);
+
+ //std::cout << "image U:" << std::endl;
+ // debug::println_with_border(u);
+ image2d<bool> tagged(ima.domain());
+ fllt_node(P, V)* current_region;
+
+ // INIT
+ R.clear();
+ N.clear();
+ A.clear();
+ g= 0;
+ gn = 0;
+ current_region = 0;
+
+ level::fill(regions, 0);
+ level::fill(tagged, false);
+
+ // Get the locals extremums
+ unsigned nlabels;
+ min_locals = F::regional_extremum(ima, F::reg_nbh(), nlabels);
+
+ // debug::println(min_locals);
+ // debug::println(min_locals | (pw::value(min_locals) > pw::cst(0)));
+
+ /// Algorithm.
+ {
+ // For all locals extremums
+ //void* x = min_locals | (pw::value(min_locals) > pw::cst(0));
+ I_IF min_locals_list(min_locals | (pw::value(min_locals) > pw::cst(0)));
+ mln_piter(I_IF) p(min_locals_list.domain());
+ for_all(p)
+ {
+ if (tagged(p))
+ continue;
+
+ step1(ima, p, g, x0);
+ step2(A, R, N, x0);
+ while (1)
+ {
+ //std::cout << "g = " << g << std::endl;
+ step3<V, P, F>(u, tagged, A, R, N, gn);
+ /// step4.
+ if (F::compare(g, gn))
+ {
+ step4_1<V, P, F>(u, A, R, N, g, gn, current_region, regions);
+ // GO TO 3)
+ continue;
+ }
+
+
+ if (g == gn)
+ {
+ step4_2(u, A, N, g, current_region, regions);
+ // GO TO 3)
+ continue;
+ }
+
+
+ if (!F::compare(g, gn))
+ {
+ step4_3(u, tagged, R, g);
+ // GO TO 1)
+ break;
+ }
+ }
+ //std::cout << "current_region = " << current_region << std::endl;
+ }
+ } // end of Algorithm
+
+ image2d<value::int_u8> output (ima.domain ());
+ fllt_tree(P, V)& tree = *new fllt_tree(P, V)(current_region);
+ util::tree_to_image (tree, output);
+
+ // util::display_tree(ima, tree);
+
+ // debug::println(output);
+ // std::cout << std::endl;
+ // debug::println(ima);
+
+ // if (output != ima)
+ // {
+ // std::cerr << "BUG!!!" << std::endl;
+ // abort();
+ // }
+
+ // io::pgm::save(output, "out.pgm");
+ // std::cout << "out.pgm generate"
+ // << std::endl;
+
+
+ // debug::println(regions);
+ //debug::println(ima | regions(make:defined reference to `mln::fllt::lower<mln::value::int_u<8u> >::inc':point2d(-4,-1))->elt().points);
+
+ return (tree);
+
+ } // end of compute_level_set
+
+ } // end of namespace mln::fllt
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_FIXME_FLLT_COMPUTE_LEVEL_SET_HH
1
0
26 Feb '08
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-02-26 Etienne FOLIO <folio(a)lrde.epita.fr>
Chamfer DT visual tests (beautiful images inside !).
* sandbox/folio/chamfer_dt.cc: New visual tests inside
(Beware! There's a picasso painting here !).
---
chamfer_dt.cc | 36 +++++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
Index: trunk/milena/sandbox/folio/chamfer_dt.cc
===================================================================
--- trunk/milena/sandbox/folio/chamfer_dt.cc (revision 1751)
+++ trunk/milena/sandbox/folio/chamfer_dt.cc (revision 1752)
@@ -29,7 +29,6 @@
#include <mln/core/image2d.hh>
#include <mln/level/fill.hh>
-#include <mln/debug/println.hh>
#include <mln/make/win_chamfer.hh>
#include <mln/accu/min.hh>
@@ -40,13 +39,13 @@
{
template<typename I>
inline
- mln_ch_value(I, float)
+ mln_ch_value(I, int)
chamfer_dt(const Image<I>& input_)
{
const I& input = exact(input_);
mln_precondition(input.has_data());
- mln_ch_value(I, float) output;
+ mln_ch_value(I, int) output;
initialize(output, input);
accu::min_<int> min;
@@ -98,10 +97,18 @@
#endif /* ! CHAMFER_DT_HH */
+#include <mln/debug/println.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/pgm/load.hh>
+#include <tests/data.hh>
+
int main()
{
using namespace mln;
+ {
image2d<bool> ima(5,5);
bool vals[] = { 1, 1, 1, 0, 0,
0, 0, 1, 0, 0,
@@ -110,7 +117,26 @@
0, 0, 0, 0, 0 };
level::fill(ima, vals);
-
debug::println(ima);
- debug::println(chamfer_dt(ima));
+
+ image2d<int> out = chamfer_dt(ima);
+ debug::println(out);
+
+ image2d<value::int_u8> out2;
+ initialize(out2, out);
+ level::stretch(out, out2);
+ io::pgm::save(out2, "./out.pgm");
+ }
+
+ {
+ image2d<value::int_u8> ima;
+ io::pgm::load(ima, MLN_IMG_DIR "/picasso.pgm");
+
+ image2d<int> out = chamfer_dt(ima);
+
+ image2d<value::int_u8> out2;
+ initialize(out2, out);
+ level::stretch(out, out2);
+ io::pgm::save(out2, "./out2.pgm");
+ }
}
1
0