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
- 9625 discussions
* lazzara/icdar/binarization.cc: Use graphes and gradient for
binarization.
---
milena/sandbox/ChangeLog | 7 +
milena/sandbox/lazzara/icdar/binarization.cc | 273 ++++++++++++++++++++++++++
2 files changed, 280 insertions(+), 0 deletions(-)
create mode 100644 milena/sandbox/lazzara/icdar/binarization.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 2f10d6b..70acc5a 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,10 @@
+2009-04-01 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add some code for ICDAR.
+
+ * lazzara/icdar/binarization.cc: Use graphes and gradient for
+ binarization.
+
2009-04-01 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add a 1st threshold code.
diff --git a/milena/sandbox/lazzara/icdar/binarization.cc b/milena/sandbox/lazzara/icdar/binarization.cc
new file mode 100644
index 0000000..ade1695
--- /dev/null
+++ b/milena/sandbox/lazzara/icdar/binarization.cc
@@ -0,0 +1,273 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/site_set/box.hh>
+#include <mln/data/fill.hh>
+#include <mln/core/alias/dpoint2d.hh>
+#include <mln/core/macros.hh>
+#include <mln/core/concept/function.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/site_set/p_edges.hh>
+#include <mln/core/site_set/p_vertices.hh>
+#include <mln/io/essential.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u16.hh>
+#include <mln/value/label_16.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/morpho/elementary/gradient_internal.hh>
+#include <mln/morpho/closing/volume.hh>
+#include <mln/morpho/watershed/flooding.hh>
+#include <mln/make/rag_and_labeled_wsl.hh>
+#include <mln/util/graph.hh>
+#include <mln/util/couple.hh>
+#include <mln/debug/colorize.hh>
+#include <mln/fun/i2v/array.hh>
+#include <mln/labeling/compute.hh>
+#include <mln/accu/center.hh>
+#include <mln/accu/median_h.hh>
+#include <mln/accu/mean.hh>
+#include <mln/pw/cst.hh>
+#include <mln/math/abs.hh>
+#include <mln/literal/colors.hh>
+#include <mln/debug/draw_graph.hh>
+
+namespace mln
+{
+
+ struct edge_values : Function_vv2v<edge_values>
+ {
+ typedef value::int_u8 result;
+ typedef void mutable_result;
+
+ value::int_u8 operator()(const value::int_u8& v1,
+ const value::int_u8& v2) const
+ { return math::abs(v1 - v2); }
+
+ };
+
+
+ template <typename I, typename V>
+ class edge_to_color : public Function_p2v< edge_to_color<I,V> >
+ {
+ public:
+ typedef V result;
+
+ edge_to_color(const I& ima_e) : ima_e_(ima_e)
+ {}
+
+ V
+ operator()(const unsigned& e) const
+ { return convert::to<V>(ima_e_.function()(e)); }
+
+ private:
+ const I& ima_e_;
+ };
+
+
+ namespace make
+ {
+
+ template <typename G, typename P>
+ p_edges<G,pw::cst_<P> >
+ dummy_pedges(const Graph<G>& g_, const P& dummy_value)
+ {
+ trace::entering("dummy_pedges");
+
+ const G& g = exact(g_);
+ mln_precondition(g.is_valid());
+ p_edges<G,pw::cst_<P> > pe(g, pw::cst(dummy_value));
+
+ trace::exiting("dummy_pedges");
+ return pe;
+ }
+
+ template <typename FVV, typename G, typename V2P, typename E2P, typename FVE>
+ pw::image<fun::i2v::array<mln_result(FVE)>,p_edges<G,E2P> >
+ edge_image(const pw::image<FVV,p_vertices<G,V2P> >& vertex_image,
+ const p_edges<G,E2P>& pe,
+ const Function_vv2v<FVE>& edge_value_)
+ {
+ trace::entering("edge_image");
+
+ const FVE& edge_value = exact(edge_value_);
+ mln_precondition(vertex_image.is_valid());
+ mln_precondition(pe.is_valid());
+
+ typedef fun::i2v::array<mln_result(FVE)> edge_values_t;
+ edge_values_t edge_values(pe.nsites());
+
+ // image on graph edges
+ typedef pw::image<edge_values_t, p_edges<G,E2P> > ima_e_t;
+ ima_e_t ima_e = (edge_values | pe);
+
+ mln_piter(ima_e_t) e(ima_e.domain());
+ for_all(e)
+ ima_e(e) = edge_value(vertex_image.function()(e.element().v1()),
+ vertex_image.function()(e.element().v2()));
+
+ trace::exiting("edge_image");
+ return ima_e;
+ }
+
+
+ template <typename W, typename G>
+ inline
+ p_vertices<util::graph, fun::i2v::array<mln_site(W)> >
+ common_pvertices(const Image<W>& wst, const mln_value(W)& nbasins,
+ const Graph<G>& g_)
+ {
+ trace::entering("common_pvertices");
+
+ const G& g = exact(g_);
+ mln_precondition(g.is_valid());
+
+ typedef fun::i2v::array<mln_site(W)> vertex_sites_t;
+ vertex_sites_t vertex_sites;
+ convert::from_to(labeling::compute(accu::center<mln_site(W)>(), wst, nbasins),
+ vertex_sites);
+
+ p_vertices<util::graph, vertex_sites_t> pv(g, vertex_sites);
+
+ trace::exiting("common_pvertices");
+ return pv;
+ }
+
+
+ template <typename A, typename G, typename F, typename I, typename W>
+ pw::image<fun::i2v::array<mln_value(I)>, p_vertices<G,F> >
+ vertex_image(const Accumulator<A>& accu,
+ const p_vertices<G,F>& pv,
+ const Image<I>& input_,
+ const Image<W>& wst_,
+ const mln_value(W)& nbasins)
+ {
+ trace::entering("vertex_image");
+
+ const I& input = exact(input_);
+ const W& wst = exact(wst_);
+ mln_precondition(input.is_valid());
+ mln_precondition(wst.is_valid());
+ mln_precondition(pv.is_valid());
+
+ typedef fun::i2v::array<mln_value(I)> vertex_values_t;
+ vertex_values_t vertex_values;
+ convert::from_to(labeling::compute(accu, input, wst, nbasins),
+ vertex_values);
+
+ pw::image<fun::i2v::array<mln_value(I)>,
+ p_vertices<util::graph, fun::i2v::array<mln_site(I)> > >
+ ima_vertex = vertex_values | pv;
+
+ trace::exiting("vertex_image");
+ return ima_vertex;
+ }
+
+
+ template <typename I, typename V, typename E>
+ inline
+ mln_concrete(I)
+ debug_graph_image(const Image<I>& input_,
+ const Image<V>& ima_v_, const Image<E>& ima_e_,
+ unsigned box_size, const mln_value(I)& bg)
+ {
+ trace::entering("debug_graph_image");
+
+ const I& input = exact(input_);
+ const V& ima_v = exact(ima_v_);
+ const E& ima_e = exact(ima_e_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(ima_v.is_valid());
+ mln_precondition(ima_e.is_valid());
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ data::fill(output, bg);
+ debug::draw_graph(output, ima_v.domain(),
+ pw::cst(150u),
+ edge_to_color<E, mln_value(I)>(ima_e));
+
+ dpoint2d tl(-box_size,-box_size);
+ dpoint2d br(box_size,box_size);
+ mln_piter(V) p(ima_v.domain());
+ for_all(p)
+ {
+ box<mln_site(I)> b(p + tl, p + br);
+ b.crop_wrt(output.domain());
+ data::fill((output | b).rw(), convert::to<mln_value(I)>(ima_v(p)));
+ }
+
+ trace::exiting("debug_graph_image");
+ return output;
+ }
+
+ } // end of namespace mln::make
+
+} // end of namespace mln
+
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+ using namespace value;
+
+ if (argc < 2)
+ {
+ std::cout << argv[0] << " <input.pgm> " << std::endl;
+ return 1;
+ }
+
+ image2d<int_u8> input;
+ io::pgm::load(input, argv[1]);
+
+ image2d<int_u8> grad = morpho::elementary::gradient_internal(input, c4());
+ io::pgm::save(grad, "binarization_grad.pgm");
+
+ image2d<int_u8> clo_vol = morpho::closing::volume(grad, c4(), 500);
+ io::pgm::save(clo_vol, "binarization_clo.pgm");
+
+ label_16 nbasins;
+ image2d<label_16> wst = morpho::watershed::flooding(clo_vol, c4(), nbasins);
+ io::ppm::save(debug::colorize(rgb8(), wst, nbasins), "binarization_wst.ppm");
+
+
+ util::couple<util::graph, image2d<label_16> >
+ rag_data = make::rag_and_labeled_wsl(wst, c4(), nbasins);
+
+ io::pgm::save(rag_data.second(), "binarization_lwsl.pgm");
+ io::ppm::save(debug::colorize(rgb8(), rag_data.second(), nbasins), "binarization_lwsl.ppm");
+
+ p_vertices<util::graph, fun::i2v::array<point2d> >
+ pv = make::common_pvertices(wst, nbasins, rag_data.first());
+
+ pw::image<fun::i2v::array<int_u8>,
+ p_vertices<util::graph, fun::i2v::array<point2d> > >
+ ima_v = make::vertex_image(accu::mean<int_u8>(), pv, input, wst, nbasins);
+
+ pw::image<fun::i2v::array<int_u8>,
+ p_edges<util::graph,pw::cst_<literal::origin_t> > >
+ ima_e = make::edge_image(ima_v,
+ make::dummy_pedges(rag_data.first(),literal::origin),
+ edge_values());
+
+
+ io::pgm::save(make::debug_graph_image(input,ima_v, ima_e, 4, 0), "binarization_graph.ppm");
+
+ // FIXME: we should use the following line instead. We cannot since currently
+ // graph edges are numbered from 0 and we must use mln_max() - 1 as
+ // background id.
+ //
+ //label_16 nelts = rag.first().e_nmax();
+ label_16 nelts = mln_max(label_16).prev();
+
+ util::array<int_u8> median_grad = labeling::compute(accu::meta::median_h(),
+ grad,
+ rag_data.second(),
+ nelts);
+ fun::i2v::array<int_u8> f;
+ convert::from_to(median_grad, f);
+
+ image2d<int_u8> med = level::transform(rag_data.second(), f);
+
+ io::pgm::save(med, "binarization_median_grad.pgm");
+}
--
1.5.6.5
1
0
* mln/labeling/wrap.hh: new routine.
* tests/labeling/Makefile.am,
* tests/labeling/wrap.cc: new test.
---
milena/ChangeLog | 9 ++++
milena/mln/labeling/wrap.hh | 86 +++++++++++++++++++++++++++++++++++++
milena/tests/labeling/Makefile.am | 4 +-
milena/tests/labeling/wrap.cc | 64 +++++++++++++++++++++++++++
4 files changed, 162 insertions(+), 1 deletions(-)
create mode 100644 milena/mln/labeling/wrap.hh
create mode 100644 milena/tests/labeling/wrap.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 7334d37..76e8920 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2009-04-01 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Add labeling::wrap routine.
+
+ * mln/labeling/wrap.hh: new routine.
+
+ * tests/labeling/Makefile.am,
+ * tests/labeling/wrap.cc: new test.
+
+2009-04-01 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Add a new routine to create a region adjacency graph.
* mln/make/rag_and_labeled_wsl.hh: new routine.
diff --git a/milena/mln/labeling/wrap.hh b/milena/mln/labeling/wrap.hh
new file mode 100644
index 0000000..aa6478f
--- /dev/null
+++ b/milena/mln/labeling/wrap.hh
@@ -0,0 +1,86 @@
+// Copyright (C) 2009 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. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_LABELING_WRAP_HH
+# define MLN_LABELING_WRAP_HH
+
+/// \file mln/labeling/wrap.hh
+///
+/// Wrap labels such as 0 -> 0 and [1, lmax] maps to [1,
+/// Lmax] (using modulus).
+
+# include <mln/core/concept/image.hh>
+# include <mln/level/transform.hh>
+# include <mln/fun/l2l/wrap.hh>
+# include <mln/metal/converts_to.hh>
+# include <mln/metal/is_a.hh>
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /// Wrap labels such as 0 -> 0 and [1, lmax] maps to [1,
+ /// Lmax] (using modulus).
+ ///
+ /// \param[in] value_type The type used to wrap the label type.
+ /// \param[in] input The label image.
+ ///
+ /// \return A new image with values wrapped with type V.
+ template <typename V, typename I>
+ mln_ch_value(I,V)
+ wrap(const V& value_type, const Image<I>& input);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V, typename I>
+ inline
+ mln_ch_value(I,V)
+ wrap(const V& value_type, const Image<I>& input)
+ {
+ trace::entering("labeling::wrap");
+
+// mlc_is_a(mln_value(I), value::Symbolic)::check();
+ mln_precondition(exact(input).is_valid());
+
+ mln_ch_value(I,V) output = level::transform(input, fun::l2l::wrap<V>());
+
+ trace::exiting("labeling::wrap");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+#endif // ! MLN_LABELING_WRAP_HH
diff --git a/milena/tests/labeling/Makefile.am b/milena/tests/labeling/Makefile.am
index 6b3231f..f436f63 100644
--- a/milena/tests/labeling/Makefile.am
+++ b/milena/tests/labeling/Makefile.am
@@ -14,7 +14,8 @@ check_PROGRAMS = \
n_max \
regional_maxima \
regional_minima \
- relabel
+ relabel \
+ wrap
background_SOURCES = background.cc
blobs_SOURCES = blobs.cc
@@ -28,5 +29,6 @@ n_max_SOURCES = n_max.cc
regional_maxima_SOURCES = regional_maxima.cc
regional_minima_SOURCES = regional_minima.cc
relabel_SOURCES = relabel.cc
+wrap_SOURCES = wrap.cc
TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/labeling/wrap.cc b/milena/tests/labeling/wrap.cc
new file mode 100644
index 0000000..b5e8a71
--- /dev/null
+++ b/milena/tests/labeling/wrap.cc
@@ -0,0 +1,64 @@
+// Copyright (C) 2009 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. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file tests/labeling/wrap.cc
+///
+/// Test on mln::labeling::wrap.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u16.hh>
+#include <mln/make/image2d.hh>
+#include <mln/labeling/wrap.hh>
+#include <mln/level/compare.hh>
+
+#include <mln/debug/println.hh>
+
+#include "tests/data.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+ using value::int_u16;
+
+ int_u16 values[] = { 1, 1000,
+ 0, 65534 };
+
+ int_u8 ref_values[] = { 1, 235,
+ 0, 254 };
+
+ image2d<int_u16> ima = make::image2d(values);
+ image2d<int_u8> ima_ref = make::image2d(ref_values);
+
+ image2d<int_u8> ima_wrapped = labeling::wrap(int_u8(), ima);
+
+ mln_assertion(ima_ref == ima_wrapped);
+}
--
1.5.6.5
1
0
02 Apr '09
* mln/make/rag_and_labeled_wsl.hh: new routine.
* tests/make/Makefile.am,
* tests/make/rag_and_labeled_wsl.cc: new test.
---
milena/ChangeLog | 9 ++
milena/mln/make/rag_and_labeled_wsl.hh | 230 ++++++++++++++++++++++++++++++
milena/tests/make/Makefile.am | 2 +
milena/tests/make/rag_and_labeled_wsl.cc | 90 ++++++++++++
4 files changed, 331 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/make/rag_and_labeled_wsl.hh
create mode 100644 milena/tests/make/rag_and_labeled_wsl.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index e7cf8d9..7334d37 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,12 @@
+2009-04-01 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
+ Add a new routine to create a region adjacency graph.
+
+ * mln/make/rag_and_labeled_wsl.hh: new routine.
+
+ * tests/make/Makefile.am,
+ * tests/make/rag_and_labeled_wsl.cc: new test.
+
2009-04-01 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Several fixes.
diff --git a/milena/mln/make/rag_and_labeled_wsl.hh b/milena/mln/make/rag_and_labeled_wsl.hh
new file mode 100644
index 0000000..d80b954
--- /dev/null
+++ b/milena/mln/make/rag_and_labeled_wsl.hh
@@ -0,0 +1,230 @@
+// Copyright (C) 2009 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_MAKE_RAG_AND_ALBL_HH
+# define MLN_MAKE_RAG_AND_ALBL_HH
+
+/// \file mln/make/rag_and_labeled_wsl.hh
+///
+/// Create a region adjacency graph and a label image of the watershed line
+/// from a watershed image.
+///
+/// \sa morpho::watershed::flooding.
+///
+/// \todo Do not use mln_max() as background label!
+
+# include <map>
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/box2d.hh>
+# include <mln/extension/adjust_fill.hh>
+# include <mln/util/graph.hh>
+# include <mln/util/couple.hh>
+
+
+namespace mln
+{
+
+ namespace make
+ {
+
+ /// Create a region adjacency graph and a label image of the watershed line
+ /// from a watershed image.
+ ///
+ /// \param[in] wshd Watershed image.
+ /// \param[in] nbh Neighborhood
+ /// \param[in] nbasins Number of influence zone in \p wshd.
+ ///
+ /// \return A couple. First element is the graph, second element is an
+ /// image with a labeled watershed line.
+ template <typename I, typename N>
+ util::couple<util::graph,mln_concrete(I)>
+ rag_and_labeled_wsl(const Image<I>& wshd_,
+ const Neighborhood<N>& nbh_,
+ const mln_value(I)& nbasins);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+ template <typename I, typename N>
+ inline
+ void
+ rag_and_labeled_wsl_tests(const Image<I>& wshd,
+ const Neighborhood<N>& nbh,
+ const mln_value(I)&)
+ {
+ mln_precondition(exact(wshd).is_valid());
+ mln_precondition(exact(nbh).is_valid());
+ (void) wshd;
+ (void) nbh;
+ }
+
+ } // end of namespace mln::make::internal
+
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I, typename N>
+ inline
+ util::couple<util::graph,mln_concrete(I)>
+ rag_and_labeled_wsl(const Image<I>& wshd_,
+ const Neighborhood<N>& nbh_,
+ const mln_value(I)& nbasins)
+ {
+ trace::entering("make::impl::generic::rag_and_labeled_wsl");
+
+ internal::rag_and_labeled_wsl_tests(wshd_, nbh_, nbasins);
+ const I& wshd = exact(wshd_);
+ const N& nbh = exact(nbh_);
+ typedef mln_value(I) L;
+
+ mln::image2d<bool> adj(mln::box2d(nbasins.next(), nbasins.next()));
+ data::fill(adj, false);
+ extension::adjust_fill(wshd, nbh, 0u);
+
+ mln_concrete(I) output(wshd.domain());
+
+ // FIXME: we would like to not use mln_value() but 0 instead.
+ // We can't do that because graph edges are numbered from 0.
+ data::fill(output, mln_max(mln_value(I)).prev());
+
+ std::map<util::couple<L,L>, mln_value(I)> c2la;
+ util::array<util::couple<L,L> > la2c;
+ mln_value(I) nlabels = literal::zero;
+
+ L l1, l2;
+ mln_piter(I) p(wshd.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ if (wshd(p) != 0u)
+ continue;
+ // p is in the watershed line.
+ l1 = l2 = 0;
+ for_all(n)
+ if (wshd.has(n) && wshd(n) != 0u)
+ {
+ if (l1 == 0u) // First label to be stored.
+ l1 = wshd(n);
+ else
+ if (wshd(n) != l1) // Useless: && l2 == 0)
+ { // Second label to be stored.
+ mln_invariant(l2 == 0u);
+ l2 = wshd(n);
+ break;
+ }
+ }
+ if (l2 == 0u || l1 == 0u)
+ continue;
+ if (l2 < l1)
+ std::swap(l1, l2);
+
+ // adjacency l1 l2
+ util::couple<L,L> c = make::couple(l2,l1);
+ if (c2la.find(c) == c2la.end())
+ {
+ c2la[c] = nlabels++;
+ la2c.append(c);
+ }
+ output(p) = c2la[c];
+
+ }
+
+ // Construct graph.
+ util::graph g;
+ g.add_vertices(nbasins.next());
+ for (unsigned i = 0; i < la2c.nelements(); ++i)
+ g.add_edge(la2c[i].first(), la2c[i].second());
+
+ trace::exiting("make::impl::generic::rag_and_labeled_wsl");
+ return make::couple(g, output);
+ }
+
+ } // end of namespace mln::make::impl::generic
+
+ } // end of namespace mln::make::impl
+
+
+
+ namespace internal
+ {
+
+ template <typename I, typename N>
+ inline
+ util::couple<util::graph,mln_concrete(I)>
+ rag_and_labeled_wsl_dispatch(const Image<I>& wshd,
+ const Neighborhood<N>& nbh,
+ const mln_value(I)& nbasins)
+ {
+ return make::impl::generic::rag_and_labeled_wsl(wshd, nbh, nbasins);
+ }
+
+ } // end of namespace mln::make::internal
+
+
+
+ // Facade
+
+ template <typename I, typename N>
+ inline
+ util::couple<util::graph,mln_concrete(I)>
+ rag_and_labeled_wsl(const Image<I>& wshd,
+ const Neighborhood<N>& nbh,
+ const mln_value(I)& nbasins)
+ {
+ trace::entering("make::rag_and_labeled_wsl");
+
+ internal::rag_and_labeled_wsl_tests(wshd, nbh, nbasins);
+
+ util::couple<util::graph,mln_concrete(I)>
+ result = internal::rag_and_labeled_wsl_dispatch(wshd, nbh, nbasins);
+
+ trace::exiting("make::rag_and_labeled_wsl");
+ return result;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace mln::make
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MAKE_RAG_AND_ALBL_HH
diff --git a/milena/tests/make/Makefile.am b/milena/tests/make/Makefile.am
index bf96093..7e4c12b 100644
--- a/milena/tests/make/Makefile.am
+++ b/milena/tests/make/Makefile.am
@@ -10,6 +10,7 @@ check_PROGRAMS = \
image3d \
mat \
region_adjacency_graph \
+ rag_and_labeled_wsl \
w_window \
w_window_directional
@@ -20,6 +21,7 @@ image2d_SOURCES = image2d.cc
image3d_SOURCES = image3d.cc
mat_SOURCES = mat.cc
region_adjacency_graph_SOURCES = region_adjacency_graph.cc
+rag_and_labeled_wsl_SOURCES = rag_and_labeled_wsl.cc
w_window_SOURCES = w_window.cc
w_window_directional_SOURCES = w_window_directional.cc
diff --git a/milena/tests/make/rag_and_labeled_wsl.cc b/milena/tests/make/rag_and_labeled_wsl.cc
new file mode 100644
index 0000000..5abb031
--- /dev/null
+++ b/milena/tests/make/rag_and_labeled_wsl.cc
@@ -0,0 +1,90 @@
+// Copyright (C) 2009 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. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file tests/make/rag_and_labeled_wsl.cc
+///
+/// Tests on mln::make::rag_and_labeled_wsl
+
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/util/graph.hh>
+
+#include <mln/value/label_8.hh>
+
+#include <mln/make/image2d.hh>
+#include <mln/make/rag_and_labeled_wsl.hh>
+
+# include <mln/debug/println.hh>
+
+int main()
+{
+ using namespace mln;
+
+ value::label_8 vals[16] = { 1, 0, 3, 3,
+ 1, 0, 0, 0,
+ 0, 0, 4, 4,
+ 2, 2, 0, 4 };
+
+ typedef image2d<value::label_8> wst_t;
+ wst_t ima = make::image2d(vals);
+
+ util::couple<util::graph, wst_t>
+ res = make::rag_and_labeled_wsl(ima, c4(), 4u);
+
+ // check that adjacency labels map edge labels.
+ mln_piter_(wst_t) p(res.second().domain());
+ mln_niter_(neighb2d) n(c4(),p);
+ for_all(p)
+ if (res.second()(p) != mln_max(value::label_8))
+ {
+ value::label_8 l1 = 0, l2 = 0;
+ for_all(n)
+ if (ima.has(n) && ima(n) != 0u)
+ {
+ if (l1 == 0u) // First label to be stored.
+ l1 = ima(n);
+ else
+ if (ima(n) != l1) // Useless: && l2 == 0)
+ { // Second label to be stored.
+ mln_invariant(l2 == 0u);
+ l2 = ima(n);
+ break;
+ }
+ }
+ if (l2 < l1)
+ std::swap(l1, l2);
+ mln_assertion(res.first().v1(res.second()(p)) == l1);
+ mln_assertion(res.first().v2(res.second()(p)) == l2);
+ }
+
+ mln_assertion(res.first().e_nmax() == 4u);
+ mln_assertion(res.first().v_nmax() == 5u);
+ mln_assertion(res.first().v_nmax_nbh_edges(0) == 0);
+ for (unsigned i = 1; i < 4; ++i)
+ mln_assertion(res.first().v_nmax_nbh_edges(i) == 2);
+}
+
--
1.5.6.5
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Several fixes.
* mln/morpho/leveling_filter.hh: Layout.
(leveling_filter): Fix trace naming.
Call facade instead of dispatch.
* mln/canvas/morpho/attribute_filter.hh: Layout.
(attribute_filter_fastest): Fix deja_vu border value.
canvas/morpho/attribute_filter.hh | 7 ++++++-
morpho/leveling_filter.hh | 30 ++++++++++++++++++++----------
2 files changed, 26 insertions(+), 11 deletions(-)
Index: mln/morpho/leveling_filter.hh
--- mln/morpho/leveling_filter.hh (revision 3598)
+++ mln/morpho/leveling_filter.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -26,8 +26,8 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_MORPHO_LEVELING_FILTER_HH_
-# define MLN_MORPHO_LEVELING_FILTER_HH_
+#ifndef MLN_MORPHO_LEVELING_FILTER_HH
+# define MLN_MORPHO_LEVELING_FILTER_HH
/// \file mln/morpho/leveling_filter.hh
///
@@ -44,8 +44,13 @@
# include <mln/canvas/morpho/attribute_filter.hh>
-namespace mln {
- namespace morpho {
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
template <typename I, typename N, typename A>
mln_concrete(I)
@@ -56,8 +61,10 @@
bool increasing);
+
# ifndef MLN_INCLUDE_ONLY
+
template <typename I, typename N, typename A>
mln_concrete(I)
leveling_filter(const Image<I>& input,
@@ -66,7 +73,7 @@
const typename A::result& lambda,
bool increasing)
{
- trace::entering("morpho::opening::leveling_filter");
+ trace::entering("morpho::leveling_filter");
mln_precondition(exact(input).is_valid());
@@ -76,16 +83,19 @@
trait::accumulator::when_pix::use_v))::check();
mln_concrete(I) output;
- output = canvas::morpho::internal::attribute_filter_dispatch(input, nbh, a, lambda, increasing);
+ output = canvas::morpho::attribute_filter(input, nbh, a, lambda, increasing);
- trace::exiting("morpho::opening::leveling_filter");
+ trace::exiting("morpho::leveling_filter");
return output;
}
+
# endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace mln::morpho
+
} // end of namespace mln
-#endif /* !MLN_MORPHO_LEVELING_FILTER_HH_ */
+#endif // ! MLN_MORPHO_LEVELING_FILTER_HH
Index: mln/canvas/morpho/attribute_filter.hh
--- mln/canvas/morpho/attribute_filter.hh (revision 3598)
+++ mln/canvas/morpho/attribute_filter.hh (working copy)
@@ -313,7 +313,7 @@
{
initialize(deja_vu, input);
data::fill(deja_vu, false);
- extension::fill(deja_vu, true); // So the border is neutral.
+ extension::fill(deja_vu, false); // So the border is neutral.
initialize(activity, input);
data::fill(activity, true);
@@ -381,6 +381,7 @@
trace::exiting("canvas::morpho::impl::attribute_filter_fastest");
return output;
}
+
} // end of namespace mln::canvas::morpho::impl
@@ -391,7 +392,9 @@
namespace internal
{
+
// Dispatch to generic.
+
template <typename I, typename N, typename A>
inline
mln_concrete(I)
@@ -409,7 +412,9 @@
return impl::generic::attribute_filter(input, nbh, s, a, lambda);
}
+
// Dispatch to fastest.
+
template <typename I, typename N, typename A>
inline
mln_concrete(I)
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add a 1st threshold code.
* theo/icdar/dibco/main.cc: New.
First threshold attempt.
* theo/icdar/hsc/boxes.cc (param): Set to a reasonable value.
(tmp_pgm): Save this temp image.
* theo/exec/subsample.cc: New.
exec/subsample.cc | 43 ++++++++++++
icdar/dibco/main.cc | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++
icdar/hsc/boxes.cc | 11 ++-
3 files changed, 236 insertions(+), 2 deletions(-)
Index: theo/icdar/dibco/main.cc
--- theo/icdar/dibco/main.cc (revision 0)
+++ theo/icdar/dibco/main.cc (revision 0)
@@ -0,0 +1,184 @@
+// Copyright (C) 2009 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. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file theo/icdar/dibco/main.cc
+///
+/// Simple thresholding of a gray-level document.
+
+# include <mln/io/pgm/load.hh>
+# include <mln/io/pgm/save.hh>
+# include <mln/io/pbm/save.hh>
+
+# include <mln/debug/println.hh>
+# include <mln/fun/l2l/wrap.hh>
+# include <mln/level/transform.hh>
+
+# include <mln/core/image/image1d.hh>
+# include <mln/core/alias/neighb1d.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+
+# include <mln/core/routine/duplicate.hh>
+# include <mln/core/image/image_if.hh>
+# include <mln/pw/all.hh>
+
+# include <mln/histo/compute.hh>
+# include <mln/debug/histo.hh>
+# include <mln/convert/from_to.hh>
+
+# include <mln/morpho/elementary/gradient_internal.hh>
+# include <mln/morpho/elementary/gradient_external.hh>
+# include <mln/morpho/closing/height.hh>
+# include <mln/morpho/closing/volume.hh>
+# include <mln/morpho/watershed/flooding.hh>
+
+# include <mln/linear/gaussian_1d.hh>
+# include <mln/labeling/regional_minima.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/value/label_8.hh>
+# include <mln/accu/center.hh>
+
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pgm output.pbm" << std::endl
+ << " ICDAR'2009: DIBCO." << std::endl;
+ std::abort();
+}
+
+
+namespace mln
+{
+
+ int
+ find_threshold(const histo::array<value::int_u8>& h)
+ {
+
+ const float sigma = 5; // FIXME: hard-coded!
+
+ util::array<point1d> c;
+ value::label_8 n;
+
+ {
+ image1d<unsigned> h_, hs_;
+ image1d<value::label_8> l;
+
+ convert::from_to(h, h_);
+ hs_ = linear::gaussian_1d(h_, sigma, 0);
+ l = labeling::regional_minima(hs_, c2(), n);
+
+ {
+// debug::println("l", l);
+// debug::histo(h, "tmp_h.txt");
+
+// std::ofstream file("tmp_hs.txt");
+// mln_piter_(box1d) p(h_.domain());
+// for_all(p)
+// file << p.ind() << ' ' << hs_(p) << std::endl;
+// file.close();
+ }
+
+ accu::center<point1d, point1d> a;
+ c = labeling::compute(a, l, n);
+
+ c[0] = point1d(0); // Force a neutral value for the non-label value (0).
+
+ // std::cout << "c = " << c << std::endl;
+ }
+
+
+ int threshold;
+
+ {
+ std::vector<int> v;
+ for (unsigned i = 0; i <= n; ++i)
+ v.push_back(c[i].ind());
+ std::sort(v.begin(), v.end());
+
+ for (unsigned i = 0; i <= n; ++i)
+ if (v[i] != 0)
+ {
+ threshold = v[i];
+ break;
+ }
+
+ std::cout << "threshold = " << threshold << std::endl;
+ }
+
+ return threshold;
+ }
+
+
+} // ! mln
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+
+ if (argc != 3)
+ usage(argv);
+
+ image2d<int_u8> input;
+ io::pgm::load(input, argv[1]);
+
+ typedef int_u8 V;
+ histo::array<V> h;
+
+ image2d<int_u8> g;
+ g = morpho::elementary::gradient_internal(input, c4());
+ io::pgm::save(g, "tmp_g.pgm");
+
+ g = morpho::closing::height(g, c4(), 3); // FIXME: hard-coded!
+
+ unsigned nbasins;
+ image2d<unsigned> w = morpho::watershed::flooding(g, c4(), nbasins);
+
+ io::pgm::save(level::transform(w,
+ fun::l2l::wrap<int_u8>()),
+ "tmp_w.pgm");
+
+ h = histo::compute(g | (pw::value(w) == pw::cst(0)));
+
+ unsigned threshold = find_threshold(h);
+
+// output = duplicate((pw::value(g) > pw::cst(threshold)) | input.domain());
+
+ io::pbm::save((pw::value(g) > pw::cst(threshold)) | input.domain(),
+ "tmp_g.pbm");
+
+ image2d<bool> output;
+ output = duplicate((pw::value(g) > pw::cst(threshold)
+ && pw::value(w) == pw::cst(0)) | input.domain());
+
+ io::pbm::save(output, argv[2]);
+}
Index: theo/icdar/hsc/boxes.cc
--- theo/icdar/hsc/boxes.cc (revision 3597)
+++ theo/icdar/hsc/boxes.cc (working copy)
@@ -44,6 +44,9 @@
#include <mln/logical/not.hh>
#include <mln/io/dump/save.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/fun/l2l/wrap.hh>
+
int usage(const char *name)
{
@@ -74,8 +77,8 @@
text = filter::small_components(text,4);
mln::util::array<unsigned>
- left_link = text::grouping::group_with_single_left_link(text, 100),
- right_link = text::grouping::group_with_single_right_link(text, 100);
+ left_link = text::grouping::group_with_single_left_link(text, 30),
+ right_link = text::grouping::group_with_single_right_link(text, 30);
std::cout << "BEFORE - nbboxes = " << nbboxes << std::endl;
@@ -94,6 +97,10 @@
io::dump::save(grouped_text.label_image(), argv[2]);
+ io::pgm::save(level::transform(grouped_text.label_image(),
+ fun::l2l::wrap<value::int_u8>()),
+ "tmp.pgm");
+
scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(),
literal::red,
scribo::make::debug_filename("boxes.ppm"));
Index: theo/exec/subsample.cc
--- theo/exec/subsample.cc (revision 0)
+++ theo/exec/subsample.cc (revision 0)
@@ -0,0 +1,43 @@
+#include "filetype.hh"
+
+#include <mln/world/binary_2d/subsample.hh>
+
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pbm n output.pgm" << std::endl
+ << " Subsampling." << std::endl
+ << " n >= 2." << std::endl;
+ std::abort();
+}
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+
+ if (argc != 4)
+ usage(argv);
+
+
+ trace::entering("main");
+
+ int n = std::atoi(argv[2]);
+ if (n < 2)
+ {
+ std::cerr << "bad n!" << std::endl;
+ usage(argv);
+ }
+
+
+ image2d<bool> ima;
+ io::pbm::load(ima, argv[1]);
+ io::pgm::save(world::binary_2d::subsample(ima,
+ n),
+ argv[3]);
+
+ trace::exiting("main");
+}
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-31 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Update spatial smoothing.
* fabien/igr/Makefile: Update.
* fabien/igr/space_smooth/linear.cc: Fix spatial smoothing.
* fabien/igr/space_smooth/median.cc: Implement spatial smoothing.
* fabien/igr/space_smooth/morpho.cc: Draft.
* fabien/igr/time_smooth/linear.cc: Small fix.
---
Makefile | 5 +-
space_smooth/linear.cc | 8 +--
space_smooth/median.cc | 111 +++++++++++++++++++++++++++++++------------------
space_smooth/morpho.cc | 12 +----
time_smooth/linear.cc | 2
5 files changed, 83 insertions(+), 55 deletions(-)
Index: trunk/milena/sandbox/fabien/igr/space_smooth/median.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/space_smooth/median.cc (revision 3596)
+++ trunk/milena/sandbox/fabien/igr/space_smooth/median.cc (revision 3597)
@@ -11,6 +11,7 @@
#include <mln/io/plot/save.hh>
#include <mln/accu/median_h.hh>
+#include <mln/core/alias/window2d.hh>
#include <mln/util/array.hh>
@@ -33,15 +34,11 @@
///////////////////
image3d<int_u12> input;
io::dicom::load(input, argv[1]);
- image2d<util::array<int_u12> > ima_arr(input.nrows(), input.ncols());
+ util::array<image2d<int_u12> > arr_ima;
for (int i = 0; i < input.nslices(); ++i)
{
image2d<int_u12> tmp_slice = duplicate(slice(input, i));
- mln_piter_(image2d<int_u12>) p(tmp_slice.domain());
- for_all(p)
- {
- ima_arr(p).append(tmp_slice(p));
- }
+ arr_ima.append(tmp_slice);
}
////////////
@@ -49,41 +46,52 @@
// Median //
// //
////////////
- image2d<util::array<int_u12> > ima_median3;
- image2d<util::array<int_u12> > ima_median5;
- initialize(ima_median3, ima_arr);
- initialize(ima_median5, ima_arr);
- mln_piter_(image2d<int_u12>) p(ima_median3.domain());
- accu::median_h<int_u12> accu_med;
+ window2d win_c12p;
+ win_c12p
+ .insert(-1, -1)
+ .insert( 0, -1)
+ .insert(+1, -1)
+ .insert(-1, 0)
+ .insert( 0, 0)
+ .insert(+1, 0)
+ .insert(-1, +1)
+ .insert( 0, +1)
+ .insert(+1, +1)
+ .insert(+2, +2)
+ .insert(-2, -2)
+ .insert(+2, -2)
+ .insert(-2, +2);
+ window2d win_c4 = win_c4p();
+ util::array<image2d<int_u12> > ima_median3;
+ util::array<image2d<int_u12> > ima_median5;
+ accu::median_h<int_u12> accu_med3;
+ accu::median_h<int_u12> accu_med5;
+ image2d<int_u12> tmp;
+ initialize(tmp, arr_ima[0]);
+ mln_piter_(image2d<int_u12>) p(arr_ima[0].domain());
+ mln_qiter_(window2d) q3(win_c4, p);
+ mln_qiter_(window2d) q5(win_c12p, p);
+ for (unsigned i = 0; i < arr_ima.nelements(); ++i)
+ {
for_all(p)
{
// Median 3
- ima_median3(p).append(ima_arr(p)[0]);
- for (unsigned i = 1; i < ima_arr(p).nelements() - 1; ++i)
- {
- accu_med.init();
- accu_med.take(ima_arr(p)[i - 1]);
- accu_med.take(ima_arr(p)[i]);
- accu_med.take(ima_arr(p)[i + 1]);
- ima_median3(p).append(accu_med.to_result());
+ accu_med3.init();
+ for_all(q3) if (arr_ima[i].domain().has(q3))
+ accu_med3.take(arr_ima[i](q3));
+ tmp(p) = accu_med3.to_result();
}
- ima_median3(p).append(ima_arr(p)[ima_arr(p).nelements() - 1]);
+ ima_median3.append(duplicate(tmp));
+ for_all(p)
+ {
// Median 5
- ima_median5(p).append(ima_arr(p)[0]);
- ima_median5(p).append(ima_arr(p)[1]);
- for (unsigned i = 2; i < ima_arr(p).nelements() - 2; ++i)
- {
- accu_med.init();
- accu_med.take(ima_arr(p)[i - 2]);
- accu_med.take(ima_arr(p)[i - 1]);
- accu_med.take(ima_arr(p)[i]);
- accu_med.take(ima_arr(p)[i + 1]);
- accu_med.take(ima_arr(p)[i + 2]);
- ima_median5(p).append(accu_med.to_result());
+ accu_med5.init();
+ for_all(q5) if (arr_ima[i].domain().has(q5))
+ accu_med5.take(arr_ima[i](q5));
+ tmp(p) = accu_med5.to_result();
}
- ima_median5(p).append(ima_arr(p)[ima_arr(p).nelements() - 2]);
- ima_median5(p).append(ima_arr(p)[ima_arr(p).nelements() - 1]);
+ ima_median5.append(duplicate(tmp));
}
/////////////
@@ -91,12 +99,35 @@
// Outputs //
// //
/////////////
- io::plot::save(ima_median3(point2d(160, 120)), "median3_tumeur.plot");
- io::plot::save(ima_median3(point2d(34, 94)), "median3_air.plot");
- io::plot::save(ima_median3(point2d(122, 115)), "median3_poumon.plot");
- io::plot::save(ima_median5(point2d(160, 120)), "median5_tumeur.plot");
- io::plot::save(ima_median5(point2d(34, 94)), "median5_air.plot");
- io::plot::save(ima_median5(point2d(122, 115)), "median5_poumon.plot");
+ util::array<int_u12> arr_tumeur3;
+ util::array<int_u12> arr_tumeur5;
+ for (unsigned i = 0; i < ima_median3.nelements(); ++i)
+ {
+ arr_tumeur3.append(ima_median3[i](point2d(160, 120)));
+ arr_tumeur5.append(ima_median5[i](point2d(160, 120)));
+ }
+ io::plot::save(arr_tumeur3, "median3_tumeur.plot");
+ io::plot::save(arr_tumeur5, "median5_tumeur.plot");
+
+ util::array<int_u12> arr_air3;
+ util::array<int_u12> arr_air5;
+ for (unsigned i = 0; i < ima_median3.nelements(); ++i)
+ {
+ arr_air3.append(ima_median3[i](point2d(34, 94)));
+ arr_air5.append(ima_median5[i](point2d(34, 94)));
+ }
+ io::plot::save(arr_air3, "median3_air.plot");
+ io::plot::save(arr_air5, "median5_air.plot");
+
+ util::array<int_u12> arr_poumon3;
+ util::array<int_u12> arr_poumon5;
+ for (unsigned i = 0; i < ima_median3.nelements(); ++i)
+ {
+ arr_poumon3.append(ima_median3[i](point2d(122, 115)));
+ arr_poumon5.append(ima_median5[i](point2d(122, 115)));
+ }
+ io::plot::save(arr_poumon3, "median3_poumon.plot");
+ io::plot::save(arr_poumon5, "median5_poumon.plot");
return 0;
}
Index: trunk/milena/sandbox/fabien/igr/space_smooth/morpho.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/space_smooth/morpho.cc (revision 3596)
+++ trunk/milena/sandbox/fabien/igr/space_smooth/morpho.cc (revision 3597)
@@ -48,15 +48,11 @@
///////////////////
image3d<int_u12> input;
io::dicom::load(input, argv[1]);
- image2d<util::array<int_u12> > ima_arr(input.nrows(), input.ncols());
+ util::array<image2d<int_u12> > arr_ima;
for (int i = 0; i < input.nslices(); ++i)
{
image2d<int_u12> tmp_slice = duplicate(slice(input, i));
- mln_piter_(image2d<int_u12>) p(tmp_slice.domain());
- for_all(p)
- {
- ima_arr(p).append(tmp_slice(p));
- }
+ arr_ima.append(tmp_slice);
}
////////////
@@ -64,10 +60,8 @@
// Morpho //
// //
////////////
- image2d<image1d<int_u12> > ima_morpho;
- initialize(ima_morpho, ima_arr);
+ util::array<image2d<int_u12> > ima_morpho;
mln_piter_(image2d<int_u12>) p(ima_morpho.domain());
- accu::median_h<int_u12> accu_med;
for_all(p)
{
image1d<int_u12> tmp_ima;
Index: trunk/milena/sandbox/fabien/igr/space_smooth/linear.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/space_smooth/linear.cc (revision 3596)
+++ trunk/milena/sandbox/fabien/igr/space_smooth/linear.cc (revision 3597)
@@ -48,12 +48,12 @@
// Linear convolution //
// //
////////////////////////
- float ws[] = { 0, 1/8, 0,
- 1/8, 1/2, 1/8,
- 0, 1/8, 0 };
+ float ws[] = { 0, 1/8.f, 0,
+ 1/8.f, 1/2.f, 1/8.f,
+ 0, 1/8.f, 0 };
util::array<image2d<float> > ima_linear;
- for (unsigned i = 1; i < arr_ima.nelements(); ++i)
+ for (unsigned i = 0; i < arr_ima.nelements(); ++i)
ima_linear.append(linear::convolve(arr_ima[i], make::w_window2d(ws)));
/////////////
Index: trunk/milena/sandbox/fabien/igr/time_smooth/linear.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/time_smooth/linear.cc (revision 3596)
+++ trunk/milena/sandbox/fabien/igr/time_smooth/linear.cc (revision 3597)
@@ -52,7 +52,7 @@
image2d<util::array<int_u12> > ima_linear;
initialize(ima_linear, ima_arr);
mln_piter_(image2d<int_u12>) p(ima_linear.domain());
- accu::median<int_u12> accu_med;
+ accu::median_h<int_u12> accu_med;
for_all(p)
{
ima_linear(p).append(ima_arr(p)[0]);
Index: trunk/milena/sandbox/fabien/igr/Makefile
===================================================================
--- trunk/milena/sandbox/fabien/igr/Makefile (revision 3596)
+++ trunk/milena/sandbox/fabien/igr/Makefile (revision 3597)
@@ -47,6 +47,9 @@
time_max: time_max.cc
${CXX} -I../../../ ${DICOM} ${MAGICK} ${CXXFLAGS} -lm $^ -o time_max
+first_slice_dicom: first_slice_dicom.cc
+ ${CXX} -I../../../ ${DICOM} ${MAGICK} ${CXXFLAGS} -lm $^ -o first_slice_dicom
+
clean:
rm -rf *.dump *.p?m *.plot *.log *.csv *.dSYM
- rm seg2d seg3d wsd2d wsd3d nbasins_finder grad clo_vol wst graph med thres matlab time_max
+ rm seg2d seg3d wsd2d wsd3d nbasins_finder grad clo_vol wst graph med thres matlab time_max first_slice_dicom
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Several bug fixes.
* mln/histo/array.hh: Layout.
* mln/core/image/image1d.hh
(from_to_): Remove border setting to 0.
Add some hints of future code.
(todo): New.
* mln/core/alias/point1d.hh: Upgrade doc style.
(row, row_t): Fix naming as...
(ind, ind_t): ...those.
* mln/linear/gaussian_directional_2d.hh: New.
* mln/linear/gaussian_1d.hh: New.
Both files have been copied from my sandbox.
* mln/linear/all.hh: Update.
* mln/accu/center.hh (to_result): Make it work when invalid.
(todo): New.
* mln/value/label.hh (prev): New.
* mln/canvas/morpho/attribute_filter.hh
(lambda): Use macro for this arg type.
(attribute_filter_dispatch): Fix missing border adjustment for
the fastest version.
(attribute_filter_fastest): New precondition.
Fix missing border initialization so that it is neutral.
* tests/morpho/closing/volume.cc: Force no border to test
that the border is correctly adapted to nbh.
* mln/labeling/compute.hh: Move code intro trace.
mln/accu/center.hh | 18 ++---
mln/canvas/morpho/attribute_filter.hh | 42 ++++++++-----
mln/core/alias/point1d.hh | 48 +++++++-------
mln/core/image/image1d.hh | 12 +++
mln/histo/array.hh | 1
mln/labeling/compute.hh | 15 +++-
mln/linear/all.hh | 11 ++-
mln/linear/gaussian_1d.hh | 109 ++++++++++++++++++++++++++++++++++
mln/linear/gaussian_directional_2d.hh | 98 ++++++++++++++++++++++++------
mln/value/label.hh | 11 +++
tests/morpho/closing/volume.cc | 5 +
11 files changed, 291 insertions(+), 79 deletions(-)
Index: mln/histo/array.hh
--- mln/histo/array.hh (revision 3595)
+++ mln/histo/array.hh (working copy)
@@ -81,6 +81,7 @@
+
# ifndef MLN_INCLUDE_ONLY
template <typename T>
Index: mln/core/image/image1d.hh
--- mln/core/image/image1d.hh (revision 3595)
+++ mln/core/image/image1d.hh (working copy)
@@ -32,6 +32,8 @@
/// \file mln/core/image/image1d.hh
///
/// Definition of the basic mln::image1d class.
+///
+/// \todo Rewrite from_to(histo, image1d) after Etienne's work.
# include <mln/core/internal/fixme.hh>
# include <mln/core/internal/image_primary.hh>
@@ -576,7 +578,13 @@
void
from_to_(const histo::array<V>& from, image1d<T>& to)
{
- to.init_(make::box1d(from.nvalues()), 0);
+ // FIXME: The code should looks like:
+
+// box1d b(point1d(mln_min(V)), point1d(mln_max(V)));
+// ima.init_(b, 0);
+// for_all(v)
+// from_to(h(v), ima.at_( index_of(v) ));
+ to.init_(make::box1d(from.nvalues()));
for (unsigned i = 0; i < from.nvalues(); ++i)
from_to(from[i], to(point1d(i)));
}
@@ -587,7 +595,7 @@
void
from_to_(const util::array<V>& from, image1d<T>& to)
{
- to.init_(make::box1d(from.nelements()), 0);
+ to.init_(make::box1d(from.nelements()));
for (unsigned i = 0; i < from.nelements(); ++i)
from_to(from[i], to(point1d(i)));
}
Index: mln/core/alias/point1d.hh
--- mln/core/alias/point1d.hh (revision 3595)
+++ mln/core/alias/point1d.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -29,25 +29,26 @@
#ifndef MLN_CORE_ALIAS_POINT1D_HH
# define MLN_CORE_ALIAS_POINT1D_HH
-/*! \file mln/core/alias/point1d.hh
- *
- * \brief Definition of the mln::point1d alias and of its construction
- * routine.
- */
+/// \file mln/core/alias/point1d.hh
+///
+/// Definition of the mln::point1d alias and of its construction
+/// routine.
# include <mln/core/point.hh>
// For site_const_impl and site_mutable_impl.
# include <mln/core/concept/site_proxy.hh>
# include <mln/core/internal/force_exact.hh>
+
namespace mln
{
- /*! \brief Type alias for a point defined on the 1D square grid with
- * integer coordinates.
- */
+ /// Type alias for a point defined on the 1D square grid with
+ /// integer coordinates.
+ //
typedef point<grid::tick, def::coord> point1d;
+
namespace internal
{
@@ -59,8 +60,8 @@
typedef C coord;
enum { dim = 1 };
- typedef const C& row_t;
- const C& row() const;
+ typedef const C& ind_t;
+ const C& ind() const;
const C& operator[](unsigned i) const;
const C& last_coord() const;
@@ -79,8 +80,8 @@
typedef subject_impl< const point<grid::tick, C>, E > super_;
E& exact_();
public:
- using super_::row;
- C& row();
+ using super_::ind;
+ C& ind();
using super_::operator[];
C& operator[](unsigned i);
};
@@ -94,9 +95,9 @@
template <typename C, typename E>
inline
const C&
- subject_impl< const point<grid::tick, C>, E >::row() const
+ subject_impl< const point<grid::tick, C>, E >::ind() const
{
- return exact_().get_subject().row();
+ return exact_().get_subject().ind();
}
template <typename C, typename E>
@@ -104,8 +105,9 @@
const C&
subject_impl< const point<grid::tick, C>, E >::operator[](unsigned i) const
{
- mln_precondition(i < 1);
- return exact_().get_subject()[i];
+ mln_precondition(i == 0);
+ (void)i;
+ return exact_().get_subject()[0];
}
template <typename C, typename E>
@@ -121,9 +123,9 @@
template <typename C, typename E>
inline
C&
- subject_impl< point<grid::tick, C>, E >::row()
+ subject_impl< point<grid::tick, C>, E >::ind()
{
- return exact_().get_subject().row();
+ return exact_().get_subject().ind();
}
template <typename C, typename E>
@@ -131,15 +133,15 @@
C&
subject_impl< point<grid::tick, C>, E >::operator[](unsigned i)
{
- mln_precondition(i < 2);
- return exact_().get_subject()[i];
+ mln_precondition(i == 0);
+ (void)i;
+ return exact_().get_subject()[0];
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::internal
-
} // end of namespace mln
Index: mln/linear/all.hh
--- mln/linear/all.hh (revision 3595)
+++ mln/linear/all.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -50,8 +50,7 @@
{
/// Namespace of local linear routines implementation details.
- namespace impl
- {}
+ namespace impl {}
}
}
@@ -62,7 +61,11 @@
# include <mln/linear/convolve.hh>
# include <mln/linear/convolve_2x1d.hh>
# include <mln/linear/convolve_directional.hh>
+
# include <mln/linear/gaussian.hh>
+# include <mln/linear/gaussian_directional_2d.hh>
+# include <mln/linear/gaussian_1d.hh>
+
# include <mln/linear/lap.hh>
# include <mln/linear/log.hh>
//# include <mln/linear/sobel.hh>
Index: mln/linear/gaussian_directional_2d.hh
--- mln/linear/gaussian_directional_2d.hh (revision 3588)
+++ mln/linear/gaussian_directional_2d.hh (working copy)
@@ -1,3 +1,38 @@
+// Copyright (C) 2009 EPITA Research and 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, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, 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_LINEAR_GAUSSIAN_DIRECTIONAL_2D_HH
+# define MLN_LINEAR_GAUSSIAN_DIRECTIONAL_2D_HH
+
+/// \file mln/linear/gaussian_directional_2d.hh
+///
+/// Directional Gaussian filter for 2D images.
+///
+/// \todo This is experimental code to be merged with regular code...
#include <mln/core/image/image2d.hh>
#include <mln/extension/adjust_fill.hh>
@@ -11,6 +46,17 @@
namespace linear
{
+
+ template <typename I>
+ mln_concrete(I)
+ gaussian_directional_2d(const Image<I>& input,
+ unsigned dir, double sigma,
+ const mln_value(I)& bdr);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
namespace my
{
@@ -20,14 +66,14 @@
DericheGaussianFirstDerivative,
DericheGaussianSecondDerivative };
- std::vector<MLN_FLOAT> n, d, nm, dm;
- MLN_FLOAT sumA, sumC;
+ std::vector<double> n, d, nm, dm;
+ double sumA, sumC;
- recursivefilter_coef_(MLN_FLOAT a0, MLN_FLOAT a1,
- MLN_FLOAT b0, MLN_FLOAT b1,
- MLN_FLOAT c0, MLN_FLOAT c1,
- MLN_FLOAT w0, MLN_FLOAT w1,
- MLN_FLOAT s, FilterType filter_type)
+ recursivefilter_coef_(double a0, double a1,
+ double b0, double b1,
+ double c0, double c1,
+ double w0, double w1,
+ double s, FilterType filter_type)
{
n.reserve(5);
d.reserve(5);
@@ -39,10 +85,10 @@
w0 /= s;
w1 /= s;
- MLN_FLOAT sin0 = sin(w0);
- MLN_FLOAT sin1 = sin(w1);
- MLN_FLOAT cos0 = cos(w0);
- MLN_FLOAT cos1 = cos(w1);
+ double sin0 = sin(w0);
+ double sin1 = sin(w1);
+ double cos0 = cos(w0);
+ double cos1 = cos(w1);
switch (filter_type) {
@@ -81,7 +127,7 @@
case DericheGaussianSecondDerivative :
{
- MLN_FLOAT aux;
+ double aux;
aux =
12.0 * cos0 * exp( 3.0 * b0 ) - 3.0 * exp( 2.0 * b0 )
+ 8.0 * cos0 * cos0 * cos0 * exp( 3.0 * b0 ) - 12.0 * cos0 * cos0 *
@@ -197,15 +243,15 @@
template <typename I, typename C>
inline
void
- recursivefilter_directional_2d_generic(I& ima,
+ recursivefilter_directional_generic(I& ima,
const C& c,
const mln_psite(I)& start,
const mln_psite(I)& finish,
int len,
const mln_deduce(I, psite, delta)& d)
{
- std::vector<MLN_FLOAT> tmp1(len);
- std::vector<MLN_FLOAT> tmp2(len);
+ std::vector<double> tmp1(len);
+ std::vector<double> tmp2(len);
tmp1[0] =
c.n[0]*ima(start);
@@ -292,7 +338,7 @@
template <typename I, typename C>
inline
void
- recursivefilter_directional_2d_fastest(I& ima,
+ recursivefilter_directional_fastest(I& ima,
const C& c,
const mln_psite(I)& start,
const mln_psite(I)& finish,
@@ -303,8 +349,8 @@
// extension::adjust_fill(ima, 5 * int(151 + .50001) + 1, bdr);
// extension::fill(ima, bdr);
- std::vector<MLN_FLOAT> tmp1(len);
- std::vector<MLN_FLOAT> tmp2(len);
+ std::vector<double> tmp1(len);
+ std::vector<double> tmp2(len);
unsigned delta_offset = ima.delta_index(d);
unsigned
@@ -418,9 +464,14 @@
inline
mln_concrete(I)
gaussian_directional_2d(const Image<I>& input_,
- unsigned dir, MLN_FLOAT sigma,
+ unsigned dir, double sigma,
const mln_value(I)& bdr)
{
+ trace::entering("linear::gaussian_directional_2d");
+
+ typedef mln_site(I) P;
+ mlc_bool(P::dim == 2)::check();
+
const I& input = exact(input_);
mln_precondition(dir == 0 || dir == 1);
@@ -447,7 +498,7 @@
if (dir == 0)
{
for (int j = 0; j < ncols; ++j)
- recursivefilter_directional_2d_fastest(output, coef,
+ recursivefilter_directional_fastest(output, coef,
point2d(- b, j),
point2d(nrows - 1 + b, j),
nrows + 2 * b,
@@ -458,7 +509,7 @@
if (dir == 1)
{
for (int i = 0; i < nrows; ++i)
- recursivefilter_directional_2d_fastest(output, coef,
+ recursivefilter_directional_fastest(output, coef,
point2d(i, - b),
point2d(i, ncols - 1 + b),
ncols + 2 * b,
@@ -466,10 +517,15 @@
bdr);
}
+ trace::exiting("linear::gaussian_directional_2d");
return output;
}
+# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::linear
} // end of namespace mln
+
+
+#endif // ! MLN_LINEAR_GAUSSIAN_DIRECTIONAL_2D_HH
Property changes on: mln/linear/gaussian_directional_2d.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/linear/gaussian_1d.hh
--- mln/linear/gaussian_1d.hh (revision 0)
+++ mln/linear/gaussian_1d.hh (revision 0)
@@ -0,0 +1,109 @@
+// Copyright (C) 2009 EPITA Research and 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, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, 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_LINEAR_GAUSSIAN_1D_HH
+# define MLN_LINEAR_GAUSSIAN_1D_HH
+
+/// \file mln/linear/gaussian_1d.hh
+///
+/// Gaussian filter for fastest 1D images.
+///
+/// \todo This is experimental code to be merged with regular code...
+
+#include <mln/core/image/image1d.hh>
+#include <mln/linear/gaussian_directional_2d.hh>
+
+
+
+namespace mln
+{
+
+ namespace linear
+ {
+
+
+ template <typename I>
+ mln_concrete(I)
+ gaussian_1d(const Image<I>& input,
+ double sigma,
+ const mln_value(I)& bdr);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ gaussian_1d(const Image<I>& input_,
+ double sigma,
+ const mln_value(I)& bdr)
+ {
+ trace::entering("linear::gaussian_1d");
+
+ typedef mln_site(I) P;
+ mlc_bool(P::dim == 1)::check();
+
+ const I& input = exact(input_);
+ mln_precondition(input.is_valid());
+
+ my::recursivefilter_coef_ coef(1.68f, 3.735f,
+ 1.783f, 1.723f,
+ -0.6803f, -0.2598f,
+ 0.6318f, 1.997f,
+ sigma,
+ my::recursivefilter_coef_::DericheGaussian);
+
+ extension::adjust_fill(input, 5 * int(sigma + .50001) + 1, bdr);
+ mln_concrete(I) output = duplicate(input);
+
+ if (sigma < 0.006)
+ return output;
+
+ int
+ ninds = geom::ninds(input),
+ b = input.border();
+
+ recursivefilter_directional_fastest(output, coef,
+ point1d(- b),
+ point1d(ninds - 1 + b),
+ ninds + 2 * b,
+ dpoint1d(1),
+ bdr);
+
+ trace::exiting("linear::gaussian_1d");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::linear
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LINEAR_GAUSSIAN_1D_HH
Index: mln/accu/center.hh
--- mln/accu/center.hh (revision 3595)
+++ mln/accu/center.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 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
@@ -31,7 +32,8 @@
/// \file mln/accu/center.hh
///
/// Define an accumulator that computes the mass center of a site set.
-
+///
+/// \todo Fix to_result() value when invalid...
# include <mln/accu/internal/base.hh>
# include <mln/accu/bbox.hh>
@@ -66,7 +68,6 @@
/// Get the value of the accumulator.
V to_result() const;
- operator V() const;
operator P() const;
/// Check whether this accu is able to return a result.
@@ -136,19 +137,14 @@
V
center<P,V>::to_result() const
{
- mln_precondition(is_valid());
+ // mln_precondition(is_valid());
+ if (! is_valid())
+ return V();
return center_ / nsites_;
}
template <typename P, typename V>
inline
- center<P,V>::operator V() const
- {
- return to_result();
- }
-
- template <typename P, typename V>
- inline
center<P,V>::operator P() const
{
return P(to_result());
Index: mln/value/label.hh
--- mln/value/label.hh (revision 3595)
+++ mln/value/label.hh (working copy)
@@ -155,6 +155,9 @@
/// Return the next value.
label<n> next() const;
+ /// Return the previous value.
+ label<n> prev() const;
+
};
@@ -279,6 +282,14 @@
template <unsigned n>
inline
+ label<n>
+ label<n>::prev() const
+ {
+ return label<n>(this->v_ - 1);
+ }
+
+ template <unsigned n>
+ inline
std::ostream& operator<<(std::ostream& ostr, const label<n>& i)
{
return ostr << debug::format(i.to_equiv());
Index: mln/canvas/morpho/attribute_filter.hh
--- mln/canvas/morpho/attribute_filter.hh (revision 3595)
+++ mln/canvas/morpho/attribute_filter.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -39,14 +39,15 @@
# include <mln/core/concept/accumulator.hh>
# include <mln/level/sort_offsets.hh>
-
# include <mln/trait/accumulators.hh>
-
# include <mln/util/pix.hh>
+# include <mln/border/get.hh>
# include <mln/data/fill.hh>
+# include <mln/extension/adjust_fill.hh>
# include <mln/level/sort_psites.hh>
+
namespace mln
{
@@ -56,16 +57,20 @@
namespace morpho
{
- // Facade Fwd Declaration
+ // FIXME: Doc!
+
template <typename I, typename N, typename A>
mln_concrete(I)
attribute_filter(const Image<I>& input, const Neighborhood<N>& nbh,
- const Accumulator<A>& a, const typename A::result& lambda,
+ const Accumulator<A>& a, const mln_result(A)& lambda,
bool increasing);
+
+
# ifndef MLN_INCLUDE_ONLY
- namespace impl {
+ namespace impl
+ {
template <typename A, typename I>
void take_as_init_fastest (trait::accumulator::when_pix::use_none, A& accu,
@@ -128,8 +133,9 @@
}
- namespace generic {
+ namespace generic
+ {
////////////////////////
/// Generic version. ///
@@ -153,7 +159,7 @@
const Neighborhood<N>& nbh_,
const Site_Set<S>& s_,
const Accumulator<A>& a_,
- const typename A::result& lambda)
+ const mln_result(A)& lambda)
{
trace::entering("canvas::morpho::impl::generic::attribute_filter");
// FIXME: Test?!
@@ -278,7 +284,7 @@
const Neighborhood<N>& nbh_,
const util::array<unsigned>& s,
const Accumulator<A>& a_,
- const typename A::result& lambda)
+ const mln_result(A)& lambda)
{
trace::entering("canvas::morpho::impl::attribute_filter_fastest");
// FIXME: Tests?
@@ -287,6 +293,10 @@
const N& nbh = exact(nbh_);
(void)a_;
+ // The border adaptation is performed in the calling scope since
+ // we want offsets of 's' to match the image structure / dimensions.
+ mln_precondition(border::get(input) >= nbh.delta());
+
mln_concrete(I) output;
initialize(output, input);
@@ -303,6 +313,8 @@
{
initialize(deja_vu, input);
data::fill(deja_vu, false);
+ extension::fill(deja_vu, true); // So the border is neutral.
+
initialize(activity, input);
data::fill(activity, true);
initialize(parent, input);
@@ -387,7 +399,7 @@
const Image<I>& input,
const Neighborhood<N>& nbh,
const Accumulator<A>& a,
- const typename A::result& lambda,
+ const mln_result(A)& lambda,
bool increasing)
{
p_array<mln_psite(I)> s = increasing ?
@@ -405,9 +417,11 @@
const Image<I>& input,
const Neighborhood<N>& nbh,
const Accumulator<A>& a,
- const typename A::result& lambda,
+ const mln_result(A)& lambda,
bool increasing)
{
+ extension::adjust(input, nbh);
+
util::array<unsigned> s =
increasing ?
level::sort_offsets_increasing(input) :
@@ -424,7 +438,7 @@
attribute_filter_dispatch(const Image<I>& input,
const Neighborhood<N>& nbh,
const Accumulator<A>& a,
- const typename A::result& lambda,
+ const mln_result(A)& lambda,
bool increasing)
{
enum {
@@ -451,7 +465,7 @@
attribute_filter(const Image<I>& input,
const Neighborhood<N>& nbh,
const Accumulator<A>& a,
- const typename A::result& lambda,
+ const mln_result(A)& lambda,
bool increasing)
{
return internal::attribute_filter_dispatch(input, nbh, a, lambda, increasing);
Index: mln/labeling/compute.hh
--- mln/labeling/compute.hh (revision 3595)
+++ mln/labeling/compute.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 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
@@ -39,7 +40,7 @@
# include <mln/core/concept/accumulator.hh>
# include <mln/core/concept/meta_accumulator.hh>
# include <mln/util/array.hh>
-# include <mln/convert/to.hh>
+# include <mln/convert/from_to.hh>
namespace mln
@@ -180,8 +181,11 @@
for_all(p)
accus[label(p)].take(p);
+ util::array<mln_result(A)> res;
+ convert::from_to(accus, res);
+
trace::exiting("labeling::impl::generic::compute");
- return convert::to< util::array<mln_result(A)> >(accus);
+ return res;
}
@@ -206,8 +210,11 @@
for_all(p)
accus[label(p)].take(input(p));
+ util::array<mln_result(A)> res;
+ convert::from_to(accus, res);
+
trace::exiting("labeling::impl::generic::compute");
- return convert::to< util::array<mln_result(A)> >(accus);
+ return res;
}
} // end of namespace mln::labeling::impl::generic
Index: tests/morpho/closing/volume.cc
--- tests/morpho/closing/volume.cc (revision 3595)
+++ tests/morpho/closing/volume.cc (working copy)
@@ -40,6 +40,8 @@
#include <mln/morpho/closing/volume.hh>
#include <mln/morpho/attribute/volume.hh>
+#include <mln/border/resize.hh>
+
#include "tests/data.hh"
@@ -51,6 +53,9 @@
typedef image2d<int_u8> I;
I lena;
io::pgm::load(lena, MLN_IMG_DIR "/tiny.pgm");
+
+ border::resize(lena, 0);
+
io::pgm::save(morpho::closing::volume(lena, c4(), 10000),
"ref.pgm");
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add into scribo a simple binarization.
* scribo/binarization: New directory.
* scribo/binarization/simple.hh: New.
* scribo/src/binarization: New directory.
* scribo/src/Makefile.am: Update.
* scribo/src/binarization/Makefile.am: New.
* scribo/src/binarization/simple.cc: New.
binarization/simple.hh | 178 +++++++++++++++++++++++++++++++++++++++++++
src/Makefile.am | 3
src/binarization/Makefile.am | 9 ++
src/binarization/simple.cc | 36 ++++++++
4 files changed, 226 insertions(+)
Index: scribo/src/binarization/Makefile.am
--- scribo/src/binarization/Makefile.am (revision 0)
+++ scribo/src/binarization/Makefile.am (revision 0)
@@ -0,0 +1,9 @@
+## Process this file through Automake to create Makefile.in -*- Makefile -*-
+
+include $(top_srcdir)/milena/sandbox/scribo/scribo.mk
+
+bin_PROGRAMS = \
+ simple
+
+simple_SOURCES = simple.cc
+
Index: scribo/src/binarization/simple.cc
--- scribo/src/binarization/simple.cc (revision 0)
+++ scribo/src/binarization/simple.cc (revision 0)
@@ -0,0 +1,36 @@
+#include <scribo/binarization/simple.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pbm/save.hh>
+
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pgm output.pbm" << std::endl
+ << " Simple binarization in SCRIBO." << std::endl;
+ std::abort();
+}
+
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+
+ if (argc != 3)
+ usage(argv);
+
+ trace::entering("main");
+
+ image2d<int_u8> input;
+ io::pgm::load(input, argv[1]);
+
+
+ io::pbm::save(scribo::binarization::simple(input),
+ argv[2]);
+
+
+ trace::exiting("main");
+}
Index: scribo/src/Makefile.am
--- scribo/src/Makefile.am (revision 3594)
+++ scribo/src/Makefile.am (working copy)
@@ -2,6 +2,9 @@
include $(top_srcdir)/milena/sandbox/scribo/scribo.mk
+SUBDIRS = \
+ binarization
+
bin_PROGRAMS = \
dmap \
extract_text_single_link \
Index: scribo/binarization/simple.hh
--- scribo/binarization/simple.hh (revision 0)
+++ scribo/binarization/simple.hh (revision 0)
@@ -0,0 +1,178 @@
+// Copyright (C) 2009 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. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+
+#ifndef SCRIBO_BINARIZATION_SIMPLE_HH
+# define SCRIBO_BINARIZATION_SIMPLE_HH
+
+/// \file scribo/binarization/simple.hh
+///
+/// Simple binarization of a gray-level document.
+
+# include <mln/core/image/image1d.hh>
+# include <mln/core/alias/neighb1d.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+
+# include <mln/core/routine/duplicate.hh>
+# include <mln/core/image/image_if.hh>
+# include <mln/pw/all.hh>
+
+# include <mln/histo/compute.hh>
+# include <mln/debug/histo.hh>
+# include <mln/convert/from_to.hh>
+
+# include <mln/morpho/elementary/gradient_external.hh>
+# include <mln/morpho/closing/height.hh>
+# include <mln/morpho/closing/volume.hh>
+# include <mln/morpho/watershed/flooding.hh>
+
+# include <mln/linear/gaussian_1d.hh>
+# include <mln/labeling/regional_minima.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/value/label_8.hh>
+# include <mln/accu/center.hh>
+
+
+
+namespace scribo
+{
+
+ namespace binarization
+ {
+
+ using namespace mln;
+
+ /// Simple binarization of a gray-level document.
+ /*!
+ *
+ * \param[in] input_ A binary image.
+ * \param[in] nbh_ The neighborhood used for labeling image components.
+ * \param[out] nlines The number of lines found.
+ * \param[in] vwin Window used to extract the vertical lines in a morphological
+ * opening
+ * \param[in] hwin Window used to extract the horizontal lines in a morphological
+ * opening
+ *
+ * \return pair of array of bounding boxes. The first array holds the
+ * vertical lines bounding boxes and the second one the
+ * horizontal lines bounding boxes.
+ */
+ template <typename I>
+ mln_ch_value(I, bool)
+ simple(const Image<I>& input);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ inline
+ mln_ch_value(I, bool)
+ simple(const Image<I>& input_)
+ {
+ trace::entering("scribo::binarization::simple");
+
+ const I& input = exact(input_);
+ mln_precondition(input.is_valid());
+
+ const float sigma = 5; // FIXME: hard-coded!
+
+ typedef mln_value(I) V;
+ histo::array<V> h;
+
+ {
+ mln_concrete(I) g;
+ g = morpho::elementary::gradient_external(input, c4());
+ g = morpho::closing::height(g, c4(), 5); // FIXME: hard-coded!
+
+ unsigned nbasins;
+ mln_ch_value(I, unsigned) w = morpho::watershed::flooding(g, c4(), nbasins);
+ h = histo::compute(input | (pw::value(w) == pw::cst(0)));
+ }
+
+
+ util::array<point1d> c;
+ value::label_8 n;
+
+ {
+ image1d<unsigned> h_, hs_;
+ image1d<value::label_8> l;
+
+ convert::from_to(h, h_);
+ hs_ = linear::gaussian_1d(h_, sigma, 0);
+ l = labeling::regional_minima(hs_, c2(), n);
+
+ if (n < 3)
+ {
+ std::cerr << "This method has not worked properly!" << std::endl;
+
+ debug::histo(h, "tmp_h.txt");
+
+ std::ofstream file("tmp_hs.txt");
+ mln_piter(box1d) p(h_.domain());
+ for_all(p)
+ file << p.ind() << ' ' << hs_(p) << std::endl;
+ file.close();
+
+ std::abort();
+ }
+
+ accu::center<point1d, point1d> a;
+ c = labeling::compute(a, l, n);
+ c[0] = point1d(0); // Force a neutral value for the non-label value (0).
+ }
+
+ int threshold;
+
+ {
+ std::vector<int> v;
+ for (unsigned i = 0; i <= n; ++i)
+ v.push_back(c[i].ind());
+ std::sort(v.begin(), v.end());
+ threshold = v[n.prev()];
+
+ // std::cout << "threshold = " << threshold << std::endl;
+ }
+
+ mln_ch_value(I, bool) output;
+ output = duplicate((pw::value(input) > pw::cst(threshold)) | input.domain());
+
+ trace::exiting("scribo::binarization::simple");
+ return output;
+ }
+
+# endif // !MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_BINARIZATION_SIMPLE_HH
1
0
30 Mar '09
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-30 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Add time smoothing in IGR and drafts of space smoothing.
* fabien/igr/Makefile.rules: New file to centralize rules.
* fabien/igr/img/slice_7.pgm: Remove.
* fabien/igr/img: Remove.
* fabien/igr/space_smooth/Makefile: New.
* fabien/igr/space_smooth/linear.cc: Implements linear space smoothing.
* fabien/igr/space_smooth/median.cc: Draft.
* fabien/igr/space_smooth/morpho.cc: Draft.
* fabien/igr/time_smooth/Makefile: New.
* fabien/igr/time_smooth/linear.cc: Implements linear time smoothing.
* fabien/igr/time_smooth/median.cc: Implements median time smoothing.
* fabien/igr/time_smooth/morpho.cc: Implements morpho time smoothing.
---
Makefile.rules | 9 ++++
space_smooth/Makefile | 15 +++++++
space_smooth/linear.cc | 75 ++++++++++++++++++++++++++++++++++++
space_smooth/median.cc | 102 +++++++++++++++++++++++++++++++++++++++++++++++++
space_smooth/morpho.cc | 102 +++++++++++++++++++++++++++++++++++++++++++++++++
time_smooth/Makefile | 15 +++++++
time_smooth/linear.cc | 77 ++++++++++++++++++++++++++++++++++++
time_smooth/median.cc | 102 +++++++++++++++++++++++++++++++++++++++++++++++++
time_smooth/morpho.cc | 102 +++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 599 insertions(+)
Index: trunk/milena/sandbox/fabien/igr/space_smooth/median.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/space_smooth/median.cc (revision 0)
+++ trunk/milena/sandbox/fabien/igr/space_smooth/median.cc (revision 3594)
@@ -0,0 +1,102 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/core/image/cast_image.hh>
+#include <mln/core/image/slice_image.hh>
+#include <mln/core/routine/duplicate.hh>
+
+#include <mln/value/int_u12.hh>
+
+#include <mln/io/dicom/load.hh>
+#include <mln/io/plot/save.hh>
+
+#include <mln/accu/median_h.hh>
+#include <mln/util/array.hh>
+
+
+using namespace mln;
+using value::int_u12;
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cout << "Usage: " << argv[0] << "input" << std::endl;
+ return 1;
+ }
+
+ ///////////////////
+ // //
+ // Image loading //
+ // //
+ ///////////////////
+ image3d<int_u12> input;
+ io::dicom::load(input, argv[1]);
+ image2d<util::array<int_u12> > ima_arr(input.nrows(), input.ncols());
+ for (int i = 0; i < input.nslices(); ++i)
+ {
+ image2d<int_u12> tmp_slice = duplicate(slice(input, i));
+ mln_piter_(image2d<int_u12>) p(tmp_slice.domain());
+ for_all(p)
+ {
+ ima_arr(p).append(tmp_slice(p));
+ }
+ }
+
+ ////////////
+ // //
+ // Median //
+ // //
+ ////////////
+ image2d<util::array<int_u12> > ima_median3;
+ image2d<util::array<int_u12> > ima_median5;
+ initialize(ima_median3, ima_arr);
+ initialize(ima_median5, ima_arr);
+ mln_piter_(image2d<int_u12>) p(ima_median3.domain());
+ accu::median_h<int_u12> accu_med;
+ for_all(p)
+ {
+ // Median 3
+ ima_median3(p).append(ima_arr(p)[0]);
+ for (unsigned i = 1; i < ima_arr(p).nelements() - 1; ++i)
+ {
+ accu_med.init();
+ accu_med.take(ima_arr(p)[i - 1]);
+ accu_med.take(ima_arr(p)[i]);
+ accu_med.take(ima_arr(p)[i + 1]);
+ ima_median3(p).append(accu_med.to_result());
+ }
+ ima_median3(p).append(ima_arr(p)[ima_arr(p).nelements() - 1]);
+
+ // Median 5
+ ima_median5(p).append(ima_arr(p)[0]);
+ ima_median5(p).append(ima_arr(p)[1]);
+ for (unsigned i = 2; i < ima_arr(p).nelements() - 2; ++i)
+ {
+ accu_med.init();
+ accu_med.take(ima_arr(p)[i - 2]);
+ accu_med.take(ima_arr(p)[i - 1]);
+ accu_med.take(ima_arr(p)[i]);
+ accu_med.take(ima_arr(p)[i + 1]);
+ accu_med.take(ima_arr(p)[i + 2]);
+ ima_median5(p).append(accu_med.to_result());
+ }
+ ima_median5(p).append(ima_arr(p)[ima_arr(p).nelements() - 2]);
+ ima_median5(p).append(ima_arr(p)[ima_arr(p).nelements() - 1]);
+ }
+
+ /////////////
+ // //
+ // Outputs //
+ // //
+ /////////////
+ io::plot::save(ima_median3(point2d(160, 120)), "median3_tumeur.plot");
+ io::plot::save(ima_median3(point2d(34, 94)), "median3_air.plot");
+ io::plot::save(ima_median3(point2d(122, 115)), "median3_poumon.plot");
+ io::plot::save(ima_median5(point2d(160, 120)), "median5_tumeur.plot");
+ io::plot::save(ima_median5(point2d(34, 94)), "median5_air.plot");
+ io::plot::save(ima_median5(point2d(122, 115)), "median5_poumon.plot");
+
+ return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/space_smooth/morpho.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/space_smooth/morpho.cc (revision 0)
+++ trunk/milena/sandbox/fabien/igr/space_smooth/morpho.cc (revision 3594)
@@ -0,0 +1,102 @@
+#include <mln/core/image/image1d.hh>
+#include <mln/core/alias/neighb1d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/core/image/cast_image.hh>
+#include <mln/core/image/slice_image.hh>
+#include <mln/core/routine/duplicate.hh>
+
+#include <mln/value/int_u12.hh>
+
+#include <mln/io/dicom/load.hh>
+#include <mln/io/plot/save.hh>
+
+#include <mln/accu/median_h.hh>
+#include <mln/convert/from_to.hh>
+#include <mln/morpho/closing/area.hh>
+#include <mln/morpho/opening/area.hh>
+#include <mln/util/array.hh>
+
+/*#include <mln/draw/line.hh>
+#include <mln/io/magick/save.hh>
+#include <mln/level/convert.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/literal/all.hh>
+using mln::value::rgb8;
+using mln::value::int_u8;*/
+
+
+using namespace mln;
+using value::int_u12;
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cout << "Usage: " << argv[0] << "input" << std::endl;
+ return 1;
+ }
+
+ ///////////////////
+ // //
+ // Image loading //
+ // //
+ ///////////////////
+ image3d<int_u12> input;
+ io::dicom::load(input, argv[1]);
+ image2d<util::array<int_u12> > ima_arr(input.nrows(), input.ncols());
+ for (int i = 0; i < input.nslices(); ++i)
+ {
+ image2d<int_u12> tmp_slice = duplicate(slice(input, i));
+ mln_piter_(image2d<int_u12>) p(tmp_slice.domain());
+ for_all(p)
+ {
+ ima_arr(p).append(tmp_slice(p));
+ }
+ }
+
+ ////////////
+ // //
+ // Morpho //
+ // //
+ ////////////
+ image2d<image1d<int_u12> > ima_morpho;
+ initialize(ima_morpho, ima_arr);
+ mln_piter_(image2d<int_u12>) p(ima_morpho.domain());
+ accu::median_h<int_u12> accu_med;
+ for_all(p)
+ {
+ image1d<int_u12> tmp_ima;
+ convert::from_to(ima_arr(p), tmp_ima);
+ tmp_ima = morpho::closing::area(tmp_ima, c2(), 3);
+ tmp_ima = morpho::opening::area(tmp_ima, c2(), 3);
+ ima_morpho(p) = tmp_ima;
+ }
+
+ /////////////
+ // //
+ // Outputs //
+ // //
+ /////////////
+ /*image2d<rgb8> ima_color = level::convert(rgb8(), level::stretch(int_u8(), slice(input, 0)));
+ algebra::vec<2, unsigned int> vmin;
+ algebra::vec<2, unsigned int> vmax;
+ vmin[0] = 160;
+ vmin[1] = 120;
+ vmax[0] = 122;
+ vmax[1] = 115;
+ mln_site_(image2d<bool>) pbeg(vmin);
+ mln_site_(image2d<bool>) pend(vmax);
+ draw::line(ima_color, pbeg, pend, literal::red);
+ io::magick::save(ima_color, "test.png");*/
+
+ io::plot::save(ima_morpho(point2d(160, 120)), "morpho_tumeur.plot");
+ io::plot::save(ima_morpho(point2d(34, 94)), "morpho_air.plot");
+ io::plot::save(ima_morpho(point2d(122, 115)), "morpho_poumon.plot");
+
+ return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/space_smooth/Makefile
===================================================================
--- trunk/milena/sandbox/fabien/igr/space_smooth/Makefile (revision 0)
+++ trunk/milena/sandbox/fabien/igr/space_smooth/Makefile (revision 3594)
@@ -0,0 +1,15 @@
+include ../Makefile.rules
+
+
+linear: linear.cc
+ ${CXX} -I../../../../ ${DICOM} ${CXXFLAGS} $^ -o linear
+
+median: median.cc
+ ${CXX} -I../../../../ ${DICOM} ${CXXFLAGS} $^ -o median
+
+morpho: morpho.cc
+ ${CXX} -I../../../../ ${DICOM} ${MAGICK} ${CXXFLAGS} $^ -o morpho
+
+clean:
+ rm -rf *.dump *.p?m *.plot *.log *.csv *.dSYM
+ rm linear median morpho
Index: trunk/milena/sandbox/fabien/igr/space_smooth/linear.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/space_smooth/linear.cc (revision 0)
+++ trunk/milena/sandbox/fabien/igr/space_smooth/linear.cc (revision 3594)
@@ -0,0 +1,75 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/core/image/cast_image.hh>
+#include <mln/core/image/slice_image.hh>
+#include <mln/core/routine/duplicate.hh>
+
+#include <mln/value/int_u12.hh>
+
+#include <mln/io/dicom/load.hh>
+#include <mln/io/plot/save.hh>
+
+#include <mln/accu/median_h.hh>
+#include <mln/linear/convolve.hh>
+#include <mln/make/w_window2d.hh>
+#include <mln/util/array.hh>
+
+
+using namespace mln;
+using value::int_u12;
+
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cout << "Usage: " << argv[0] << "input" << std::endl;
+ return 1;
+ }
+
+ ///////////////////
+ // //
+ // Image loading //
+ // //
+ ///////////////////
+ image3d<int_u12> input;
+ io::dicom::load(input, argv[1]);
+ util::array<image2d<int_u12> > arr_ima;
+ for (int i = 0; i < input.nslices(); ++i)
+ {
+ image2d<int_u12> tmp_slice = duplicate(slice(input, i));
+ arr_ima.append(tmp_slice);
+ }
+
+ ////////////////////////
+ // //
+ // Linear convolution //
+ // //
+ ////////////////////////
+ float ws[] = { 0, 1/8, 0,
+ 1/8, 1/2, 1/8,
+ 0, 1/8, 0 };
+
+ util::array<image2d<float> > ima_linear;
+ for (unsigned i = 1; i < arr_ima.nelements(); ++i)
+ ima_linear.append(linear::convolve(arr_ima[i], make::w_window2d(ws)));
+
+ /////////////
+ // //
+ // Outputs //
+ // //
+ /////////////
+ image2d<util::array<float> > ima_result(input.nrows(), input.ncols());
+ mln_piter_(image2d<util::array<float> >) p(ima_linear[0].domain());
+ for_all(p)
+ for (int i = 0; i < ima_linear.nelements(); ++i)
+ ima_result(p).append(ima_linear[i](p));
+
+ io::plot::save(ima_result(point2d(160, 120)), "linear_tumeur.plot");
+ io::plot::save(ima_result(point2d(34, 94)), "linear_air.plot");
+ io::plot::save(ima_result(point2d(122, 115)), "linear_poumon.plot");
+
+ return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/time_smooth/median.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/time_smooth/median.cc (revision 0)
+++ trunk/milena/sandbox/fabien/igr/time_smooth/median.cc (revision 3594)
@@ -0,0 +1,102 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/core/image/cast_image.hh>
+#include <mln/core/image/slice_image.hh>
+#include <mln/core/routine/duplicate.hh>
+
+#include <mln/value/int_u12.hh>
+
+#include <mln/io/dicom/load.hh>
+#include <mln/io/plot/save.hh>
+
+#include <mln/accu/median_h.hh>
+#include <mln/util/array.hh>
+
+
+using namespace mln;
+using value::int_u12;
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cout << "Usage: " << argv[0] << "input" << std::endl;
+ return 1;
+ }
+
+ ///////////////////
+ // //
+ // Image loading //
+ // //
+ ///////////////////
+ image3d<int_u12> input;
+ io::dicom::load(input, argv[1]);
+ image2d<util::array<int_u12> > ima_arr(input.nrows(), input.ncols());
+ for (int i = 0; i < input.nslices(); ++i)
+ {
+ image2d<int_u12> tmp_slice = duplicate(slice(input, i));
+ mln_piter_(image2d<int_u12>) p(tmp_slice.domain());
+ for_all(p)
+ {
+ ima_arr(p).append(tmp_slice(p));
+ }
+ }
+
+ ////////////
+ // //
+ // Median //
+ // //
+ ////////////
+ image2d<util::array<int_u12> > ima_median3;
+ image2d<util::array<int_u12> > ima_median5;
+ initialize(ima_median3, ima_arr);
+ initialize(ima_median5, ima_arr);
+ mln_piter_(image2d<int_u12>) p(ima_median3.domain());
+ accu::median_h<int_u12> accu_med;
+ for_all(p)
+ {
+ // Median 3
+ ima_median3(p).append(ima_arr(p)[0]);
+ for (unsigned i = 1; i < ima_arr(p).nelements() - 1; ++i)
+ {
+ accu_med.init();
+ accu_med.take(ima_arr(p)[i - 1]);
+ accu_med.take(ima_arr(p)[i]);
+ accu_med.take(ima_arr(p)[i + 1]);
+ ima_median3(p).append(accu_med.to_result());
+ }
+ ima_median3(p).append(ima_arr(p)[ima_arr(p).nelements() - 1]);
+
+ // Median 5
+ ima_median5(p).append(ima_arr(p)[0]);
+ ima_median5(p).append(ima_arr(p)[1]);
+ for (unsigned i = 2; i < ima_arr(p).nelements() - 2; ++i)
+ {
+ accu_med.init();
+ accu_med.take(ima_arr(p)[i - 2]);
+ accu_med.take(ima_arr(p)[i - 1]);
+ accu_med.take(ima_arr(p)[i]);
+ accu_med.take(ima_arr(p)[i + 1]);
+ accu_med.take(ima_arr(p)[i + 2]);
+ ima_median5(p).append(accu_med.to_result());
+ }
+ ima_median5(p).append(ima_arr(p)[ima_arr(p).nelements() - 2]);
+ ima_median5(p).append(ima_arr(p)[ima_arr(p).nelements() - 1]);
+ }
+
+ /////////////
+ // //
+ // Outputs //
+ // //
+ /////////////
+ io::plot::save(ima_median3(point2d(160, 120)), "median3_tumeur.plot");
+ io::plot::save(ima_median3(point2d(34, 94)), "median3_air.plot");
+ io::plot::save(ima_median3(point2d(122, 115)), "median3_poumon.plot");
+ io::plot::save(ima_median5(point2d(160, 120)), "median5_tumeur.plot");
+ io::plot::save(ima_median5(point2d(34, 94)), "median5_air.plot");
+ io::plot::save(ima_median5(point2d(122, 115)), "median5_poumon.plot");
+
+ return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/time_smooth/morpho.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/time_smooth/morpho.cc (revision 0)
+++ trunk/milena/sandbox/fabien/igr/time_smooth/morpho.cc (revision 3594)
@@ -0,0 +1,102 @@
+#include <mln/core/image/image1d.hh>
+#include <mln/core/alias/neighb1d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/core/image/cast_image.hh>
+#include <mln/core/image/slice_image.hh>
+#include <mln/core/routine/duplicate.hh>
+
+#include <mln/value/int_u12.hh>
+
+#include <mln/io/dicom/load.hh>
+#include <mln/io/plot/save.hh>
+
+#include <mln/accu/median_h.hh>
+#include <mln/convert/from_to.hh>
+#include <mln/morpho/closing/area.hh>
+#include <mln/morpho/opening/area.hh>
+#include <mln/util/array.hh>
+
+/*#include <mln/draw/line.hh>
+#include <mln/io/magick/save.hh>
+#include <mln/level/convert.hh>
+#include <mln/level/stretch.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/literal/all.hh>
+using mln::value::rgb8;
+using mln::value::int_u8;*/
+
+
+using namespace mln;
+using value::int_u12;
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cout << "Usage: " << argv[0] << "input" << std::endl;
+ return 1;
+ }
+
+ ///////////////////
+ // //
+ // Image loading //
+ // //
+ ///////////////////
+ image3d<int_u12> input;
+ io::dicom::load(input, argv[1]);
+ image2d<util::array<int_u12> > ima_arr(input.nrows(), input.ncols());
+ for (int i = 0; i < input.nslices(); ++i)
+ {
+ image2d<int_u12> tmp_slice = duplicate(slice(input, i));
+ mln_piter_(image2d<int_u12>) p(tmp_slice.domain());
+ for_all(p)
+ {
+ ima_arr(p).append(tmp_slice(p));
+ }
+ }
+
+ ////////////
+ // //
+ // Morpho //
+ // //
+ ////////////
+ image2d<image1d<int_u12> > ima_morpho;
+ initialize(ima_morpho, ima_arr);
+ mln_piter_(image2d<int_u12>) p(ima_morpho.domain());
+ accu::median_h<int_u12> accu_med;
+ for_all(p)
+ {
+ image1d<int_u12> tmp_ima;
+ convert::from_to(ima_arr(p), tmp_ima);
+ tmp_ima = morpho::closing::area(tmp_ima, c2(), 3);
+ tmp_ima = morpho::opening::area(tmp_ima, c2(), 3);
+ ima_morpho(p) = tmp_ima;
+ }
+
+ /////////////
+ // //
+ // Outputs //
+ // //
+ /////////////
+ /*image2d<rgb8> ima_color = level::convert(rgb8(), level::stretch(int_u8(), slice(input, 0)));
+ algebra::vec<2, unsigned int> vmin;
+ algebra::vec<2, unsigned int> vmax;
+ vmin[0] = 160;
+ vmin[1] = 120;
+ vmax[0] = 122;
+ vmax[1] = 115;
+ mln_site_(image2d<bool>) pbeg(vmin);
+ mln_site_(image2d<bool>) pend(vmax);
+ draw::line(ima_color, pbeg, pend, literal::red);
+ io::magick::save(ima_color, "test.png");*/
+
+ io::plot::save(ima_morpho(point2d(160, 120)), "morpho_tumeur.plot");
+ io::plot::save(ima_morpho(point2d(34, 94)), "morpho_air.plot");
+ io::plot::save(ima_morpho(point2d(122, 115)), "morpho_poumon.plot");
+
+ return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/time_smooth/Makefile
===================================================================
--- trunk/milena/sandbox/fabien/igr/time_smooth/Makefile (revision 0)
+++ trunk/milena/sandbox/fabien/igr/time_smooth/Makefile (revision 3594)
@@ -0,0 +1,15 @@
+include ../Makefile.rules
+
+
+linear: linear.cc
+ ${CXX} -I../../../../ ${DICOM} ${CXXFLAGS} $^ -o linear
+
+median: median.cc
+ ${CXX} -I../../../../ ${DICOM} ${CXXFLAGS} $^ -o median
+
+morpho: morpho.cc
+ ${CXX} -I../../../../ ${DICOM} ${MAGICK} ${CXXFLAGS} $^ -o morpho
+
+clean:
+ rm -rf *.dump *.p?m *.plot *.log *.csv *.dSYM
+ rm linear median morpho
Index: trunk/milena/sandbox/fabien/igr/time_smooth/linear.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/time_smooth/linear.cc (revision 0)
+++ trunk/milena/sandbox/fabien/igr/time_smooth/linear.cc (revision 3594)
@@ -0,0 +1,77 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/core/image/cast_image.hh>
+#include <mln/core/image/slice_image.hh>
+#include <mln/core/routine/duplicate.hh>
+
+#include <mln/value/int_u12.hh>
+
+#include <mln/io/dicom/load.hh>
+#include <mln/io/plot/save.hh>
+
+#include <mln/accu/median_h.hh>
+#include <mln/util/array.hh>
+
+
+using namespace mln;
+using value::int_u12;
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cout << "Usage: " << argv[0] << "input" << std::endl;
+ return 1;
+ }
+
+ ///////////////////
+ // //
+ // Image loading //
+ // //
+ ///////////////////
+ image3d<int_u12> input;
+ io::dicom::load(input, argv[1]);
+ image2d<util::array<int_u12> > ima_arr(input.nrows(), input.ncols());
+ for (int i = 0; i < input.nslices(); ++i)
+ {
+ image2d<int_u12> tmp_slice = duplicate(slice(input, i));
+ mln_piter_(image2d<int_u12>) p(tmp_slice.domain());
+ for_all(p)
+ {
+ ima_arr(p).append(tmp_slice(p));
+ }
+ }
+
+ ////////////////////////
+ // //
+ // Linear convolution //
+ // //
+ ////////////////////////
+ image2d<util::array<int_u12> > ima_linear;
+ initialize(ima_linear, ima_arr);
+ mln_piter_(image2d<int_u12>) p(ima_linear.domain());
+ accu::median<int_u12> accu_med;
+ for_all(p)
+ {
+ ima_linear(p).append(ima_arr(p)[0]);
+ for (unsigned i = 1; i < ima_arr(p).nelements() - 1; ++i)
+ ima_linear(p).append(0.25 * ima_arr(p)[i - 1] + 0.5 * ima_arr(p)[i] + 0.25 * ima_arr(p)[i + 1]);
+ ima_linear(p).append(ima_arr(p)[ima_arr(p).nelements() - 1]);
+ }
+
+ /////////////
+ // //
+ // Outputs //
+ // //
+ /////////////
+ io::plot::save(ima_arr(point2d(160, 120)), "ref_tumeur.plot");
+ io::plot::save(ima_linear(point2d(160, 120)), "linear_tumeur.plot");
+ io::plot::save(ima_arr(point2d(34, 94)), "ref_air.plot");
+ io::plot::save(ima_linear(point2d(34, 94)), "linear_air.plot");
+ io::plot::save(ima_arr(point2d(122, 115)), "ref_poumon.plot");
+ io::plot::save(ima_linear(point2d(122, 115)), "linear_poumon.plot");
+
+ return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/Makefile.rules
===================================================================
--- trunk/milena/sandbox/fabien/igr/Makefile.rules (revision 0)
+++ trunk/milena/sandbox/fabien/igr/Makefile.rules (revision 3594)
@@ -0,0 +1,9 @@
+CXX = llvm-g++
+CXXFLAGS = -DNDEBUG -O4
+
+DICOM_INC = -I/usr/local/include/gdcm-2.0
+DICOM_LIBS = -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib \
+ -framework CoreFoundation
+DICOM = ${DICOM_INC} ${DICOM_LIBS}
+
+MAGICK = `Magick++-config --cppflags --ldflags --libs`
1
0
* mln/core/concept/image.hh: Add an invalid operator= in order to
avoid wrong assignment. See sandbox/bug/concept_and_assignment.cc.
---
milena/ChangeLog | 7 +++++++
milena/mln/core/concept/image.hh | 19 ++++++++++++++++++-
2 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 3ece40a..8753025 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,12 @@
2009-03-30 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Avoid invalid assigments with image concept.
+
+ * mln/core/concept/image.hh: Add an invalid operator= in order to
+ avoid wrong assignment. See sandbox/bug/concept_and_assignment.cc.
+
+2009-03-30 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Add math::sin and math::pi.
* mln/math/all.hh: add new includes.
diff --git a/milena/mln/core/concept/image.hh b/milena/mln/core/concept/image.hh
index e2bc4f8..6b23192 100644
--- a/milena/mln/core/concept/image.hh
+++ b/milena/mln/core/concept/image.hh
@@ -43,6 +43,7 @@
# include <mln/trait/concrete.hh> // FIXME: Should be in all.hh!
# include <mln/trait/images.hh>
+# include <mln/metal/abort.hh>
# include <mln/metal/is_a.hh>
# include <mln/metal/equal.hh>
@@ -73,6 +74,9 @@ namespace mln
{
typedef Image<void> category;
+ template <typename J>
+ Image<E>& operator=(const J& rhs);
+
/*
// provided by internal::image_base:
@@ -110,7 +114,6 @@ namespace mln
};
-
namespace convert
{
@@ -176,6 +179,20 @@ namespace mln
} // end of namespace mln::internal
+ template <typename E>
+ template <typename J>
+ inline
+ Image<E>&
+ Image<E>::operator=(const J&)
+ {
+ /// You are assigning an image of a concrete type to
+ /// an image with a concept type. It does NOT work.
+ ///
+ /// You forgot a call to exact() on the left operand!
+ mlc_abort(E)::check();
+ return *this;
+ }
+
template <typename E>
inline
--
1.5.6.5
1
0