Olena-patches
Threads by month
- ----- 2025 -----
- 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
October 2009
- 7 participants
- 111 discussions

[PATCH 2/5] Add missing copyright headers to configure.ac and Makefile.am's.
by Roland Levillain 29 Oct '09
by Roland Levillain 29 Oct '09
29 Oct '09
* configure.ac,
* Makefile.am,
* bin/Makefile.am,
* config/Makefile.am,
* data/Makefile.am,
* libmd5/Makefile.am,
* src/Makefile.am,
* test/Makefile.am,
* test/vaucanson/Makefile.am:
Here.
---
dynamic-use-of-static-c++/ChangeLog | 15 +++++++++++++++
dynamic-use-of-static-c++/Makefile.am | 16 ++++++++++++++++
dynamic-use-of-static-c++/bin/Makefile.am | 16 ++++++++++++++++
dynamic-use-of-static-c++/config/Makefile.am | 16 ++++++++++++++++
dynamic-use-of-static-c++/configure.ac | 16 ++++++++++++++++
dynamic-use-of-static-c++/data/Makefile.am | 19 ++++++++++++++++++-
dynamic-use-of-static-c++/libmd5/Makefile.am | 17 +++++++++++++++++
dynamic-use-of-static-c++/src/Makefile.am | 16 ++++++++++++++++
dynamic-use-of-static-c++/test/Makefile.am | 16 ++++++++++++++++
.../test/vaucanson/Makefile.am | 16 ++++++++++++++++
10 files changed, 162 insertions(+), 1 deletions(-)
diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog
index 2a072f4..aa42cf6 100644
--- a/dynamic-use-of-static-c++/ChangeLog
+++ b/dynamic-use-of-static-c++/ChangeLog
@@ -1,3 +1,18 @@
+2009-10-27 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Add missing copyright headers to configure.ac and Makefile.am's.
+
+ * configure.ac,
+ * Makefile.am,
+ * bin/Makefile.am,
+ * config/Makefile.am,
+ * data/Makefile.am,
+ * libmd5/Makefile.am,
+ * src/Makefile.am,
+ * test/Makefile.am,
+ * test/vaucanson/Makefile.am:
+ Here.
+
2009-10-26 Roland Levillain <roland(a)lrde.epita.fr>
Send dyn patches to the olena-patches mailing list.
diff --git a/dynamic-use-of-static-c++/Makefile.am b/dynamic-use-of-static-c++/Makefile.am
index 55d40c3..a769c69 100644
--- a/dynamic-use-of-static-c++/Makefile.am
+++ b/dynamic-use-of-static-c++/Makefile.am
@@ -1,3 +1,19 @@
+# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
SUBDIRS = libltdl libmd5 bin src config data test
ACLOCAL_AMFLAGS = -I config -I libltdl
diff --git a/dynamic-use-of-static-c++/bin/Makefile.am b/dynamic-use-of-static-c++/bin/Makefile.am
index 41bad07..4b0a257 100644
--- a/dynamic-use-of-static-c++/bin/Makefile.am
+++ b/dynamic-use-of-static-c++/bin/Makefile.am
@@ -1,3 +1,19 @@
+# Copyright (C) 2005 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
bin_SCRIPTS = dyn-config
# FIXME put dyn- before these binaries
noinst_SCRIPTS = mk_swig_input swig_tree_to_yaml yaml_to_dyn_decls
diff --git a/dynamic-use-of-static-c++/config/Makefile.am b/dynamic-use-of-static-c++/config/Makefile.am
index 0b6a05c..5209d05 100644
--- a/dynamic-use-of-static-c++/config/Makefile.am
+++ b/dynamic-use-of-static-c++/config/Makefile.am
@@ -1 +1,17 @@
+# Copyright (C) 2005 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
ruby.m4: rbconfig_gen.rb config/mk_local_config_rb_in.rb
diff --git a/dynamic-use-of-static-c++/configure.ac b/dynamic-use-of-static-c++/configure.ac
index fbaa31c..5235efe 100644
--- a/dynamic-use-of-static-c++/configure.ac
+++ b/dynamic-use-of-static-c++/configure.ac
@@ -1,3 +1,19 @@
+# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
AC_PREREQ([2.61])
# Catch some macros that are not expanded.
diff --git a/dynamic-use-of-static-c++/data/Makefile.am b/dynamic-use-of-static-c++/data/Makefile.am
index afdbe34..698b1f8 100644
--- a/dynamic-use-of-static-c++/data/Makefile.am
+++ b/dynamic-use-of-static-c++/data/Makefile.am
@@ -1,4 +1,21 @@
-# Do not install me
+# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
+
+# Do not install me.
lib_LTLIBRARIES = libdyn_function.la
# FIXME: This is probably not portable!
# libdyn_function_la_LDFLAGS = `dyn-config --libtool-libs`
diff --git a/dynamic-use-of-static-c++/libmd5/Makefile.am b/dynamic-use-of-static-c++/libmd5/Makefile.am
index a445800..9d4a4db 100644
--- a/dynamic-use-of-static-c++/libmd5/Makefile.am
+++ b/dynamic-use-of-static-c++/libmd5/Makefile.am
@@ -1,3 +1,20 @@
+# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
+
# A C++ implementation of the MD5 algorithm adapted from RSA Data
# Security's implementation.
#
diff --git a/dynamic-use-of-static-c++/src/Makefile.am b/dynamic-use-of-static-c++/src/Makefile.am
index 00504b7..7248bb5 100644
--- a/dynamic-use-of-static-c++/src/Makefile.am
+++ b/dynamic-use-of-static-c++/src/Makefile.am
@@ -1,3 +1,19 @@
+# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
include_HEADERS = dyn-all.hh dyn-light.hh
lib_LTLIBRARIES = libdyn.la
diff --git a/dynamic-use-of-static-c++/test/Makefile.am b/dynamic-use-of-static-c++/test/Makefile.am
index 5a6beea..25cec5d 100644
--- a/dynamic-use-of-static-c++/test/Makefile.am
+++ b/dynamic-use-of-static-c++/test/Makefile.am
@@ -1,3 +1,19 @@
+# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
AM_CPPFLAGS = -I$(srcdir)/fixtures -I$(top_srcdir)/src -I$(top_builddir)/src
AM_CXXFLAGS = $(WARNING_CXXFLAGS)
diff --git a/dynamic-use-of-static-c++/test/vaucanson/Makefile.am b/dynamic-use-of-static-c++/test/vaucanson/Makefile.am
index 12719b1..fef65ba 100644
--- a/dynamic-use-of-static-c++/test/vaucanson/Makefile.am
+++ b/dynamic-use-of-static-c++/test/vaucanson/Makefile.am
@@ -1,3 +1,19 @@
+# Copyright (C) 2005 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
# FIXME: Clean me!
check-local_DISABLE: tree.yml
--
1.6.5
1
0
---
dynamic-use-of-static-c++/ChangeLog | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog
index 4ed1afd..2a072f4 100644
--- a/dynamic-use-of-static-c++/ChangeLog
+++ b/dynamic-use-of-static-c++/ChangeLog
@@ -303,7 +303,7 @@
Disable the ruby segv handler.
* src/function_loader.cc: Ignore segv cause the system handle it
- normally.
+ normally.
2005-12-06 Nicolas Pouillard <ertai(a)lrde.epita.fr>
@@ -561,7 +561,7 @@
Revert the previous patch.
* src/data.erb.hxx, src/data.erb.hh: Restore this useful piece
- of code.
+ of code.
2005-11-25 Nicolas Pouillard <ertai(a)lrde.epita.fr>
--
1.6.5
1
0
* sandbox/fabien/igr/Makefile: Add target 'all' and do not use
watershed.hh as dependency.
* sandbox/fabien/igr/fun_labels.cc,
* sandbox/fabien/igr/graph.cc,
* sandbox/fabien/igr/mean_slices.cc,
* sandbox/fabien/igr/nbasins_finder.cc,
* sandbox/fabien/igr/seg2d.cc,
* sandbox/fabien/igr/seg_vol_irm.hh,
* sandbox/fabien/igr/watershed2d.cc,
* sandbox/fabien/igr/watershed3d.cc,
* sandbox/fabien/igr/wst_edges.cc: Fix compilations issues.
---
milena/sandbox/ChangeLog | 17 +++++
milena/sandbox/fabien/igr/Makefile | 35 +++++++----
milena/sandbox/fabien/igr/fun_labels.cc | 2 +-
milena/sandbox/fabien/igr/graph.cc | 77 ++++++++++--------------
milena/sandbox/fabien/igr/mean_slices.cc | 4 +-
milena/sandbox/fabien/igr/nbasins_finder.cc | 4 +-
milena/sandbox/fabien/igr/seg2d.cc | 4 +-
milena/sandbox/fabien/igr/seg_vol_irm.hh | 19 +++---
milena/sandbox/fabien/igr/watershed2d.cc | 87 +++++++++++---------------
milena/sandbox/fabien/igr/watershed3d.cc | 84 +++++++++++---------------
milena/sandbox/fabien/igr/wst_edges.cc | 2 +-
11 files changed, 160 insertions(+), 175 deletions(-)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 08e7332..4191a7e 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,22 @@
2009-10-28 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix compilation issues in IGR's code.
+
+ * sandbox/fabien/igr/Makefile: Add target 'all' and do not use
+ watershed.hh as dependency.
+
+ * sandbox/fabien/igr/fun_labels.cc,
+ * sandbox/fabien/igr/graph.cc,
+ * sandbox/fabien/igr/mean_slices.cc,
+ * sandbox/fabien/igr/nbasins_finder.cc,
+ * sandbox/fabien/igr/seg2d.cc,
+ * sandbox/fabien/igr/seg_vol_irm.hh,
+ * sandbox/fabien/igr/watershed2d.cc,
+ * sandbox/fabien/igr/watershed3d.cc,
+ * sandbox/fabien/igr/wst_edges.cc: Fix compilations issues.
+
+2009-10-28 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Update IGR's GUI.
* demo.pro: Include new files.
diff --git a/milena/sandbox/fabien/igr/Makefile b/milena/sandbox/fabien/igr/Makefile
index e532fe8..8ded9e0 100644
--- a/milena/sandbox/fabien/igr/Makefile
+++ b/milena/sandbox/fabien/igr/Makefile
@@ -1,23 +1,33 @@
include Makefile.rules
+TGT= seg2d seg3d wsd2d wsd3d nbasins \
+ grad clo_vol wst maj graph med \
+ thres matlab time_max time_max_norm \
+ fun_labels mean_slices \
+ crop label2gif min_max_float filter \
+ norm dist_edges wst_edges mean_median_label \
+ filter_morpho_us
+
+all: $(TGT)
+
seg2d: seg_vol_irm.hh seg2d.cc
${CXX} -I../../../ ${DICOM} ${CXXFLAGS} seg2d.cc -o seg2d
seg3d: seg_vol_irm.hh seg3d.cc
${CXX} -I../../../ ${DICOM} ${CXXFLAGS} seg3d.cc -o seg3d
-wsd2d: watershed.hh watershed2d.cc
+wsd2d: watershed2d.cc
${CXX} -I../../../ ${DICOM} ${CXXFLAGS} $^ -o wsd2d
-wsd3d: watershed.hh watershed3d.cc
+wsd3d: watershed3d.cc
${CXX} -I../../../ ${DICOM} ${CXXFLAGS} $^ -o wsd3d
nbasins: nbasins_finder.cc
${CXX} -I../../../ ${DICOM} ${CXXFLAGS} $^ -o nbasins_finder
-
+
grad: grad.cc
${CXX} -I../../../ ${CXXFLAGS} $^ -o grad
-
+
clo_vol: clo_vol.cc
${CXX} -I../../../ ${CXXFLAGS} $^ -o clo_vol
@@ -26,27 +36,24 @@ wst: wst.cc
maj: maj.cc
${CXX} -I../../../ ${CXXFLAGS} $^ -o maj
-
+
graph: graph.cc
${CXX} -I../../../ ${DICOM} ${CXXFLAGS} $^ -o graph
-
+
med: med.cc
${CXX} -I../../../ ${CXXFLAGS} $^ -o med
-
+
thres: thres.cc
${CXX} -I../../../ ${CXXFLAGS} $^ -o thres
-
+
matlab: matlab.cc
${CXX} -I../../../ ${DICOM} ${CXXFLAGS} -lm $^ -o matlab
-
+
time_max: time_max.cc
${CXX} -I../../../ ${DICOM} ${MAGICK} ${CXXFLAGS} -lm $^ -o time_max
-
+
time_max_norm: time_max_norm.cc
${CXX} -I../../../ ${CXXFLAGS} -lm $^ -o time_max_norm
-
-first_slice_dicom: first_slice_dicom.cc
- ${CXX} -I../../../ ${DICOM} ${MAGICK} ${CXXFLAGS} -lm $^ -o first_slice_dicom
fun_labels: fun_labels.cc
${CXX} -I../../../ ${CXXFLAGS} $^ -o fun_labels
@@ -73,7 +80,7 @@ norm: norm.cc
dist_edges: dist_edges.cc
${CXX} -I../../../ ${CXXFLAGS} $^ -o dist_edges
-
+
wst_edges: wst_edges.cc
${CXX} -I../../../ ${CXXFLAGS} $^ -o wst_edges
diff --git a/milena/sandbox/fabien/igr/fun_labels.cc b/milena/sandbox/fabien/igr/fun_labels.cc
index 6e48b70..52e661a 100644
--- a/milena/sandbox/fabien/igr/fun_labels.cc
+++ b/milena/sandbox/fabien/igr/fun_labels.cc
@@ -133,7 +133,7 @@ void plot_all_labels(Image<I>& ima, Image<L>& ima_labels, unsigned nlabels)
template <typename L>
inline
-void save_label_plot(int count, const char* desc, L prev_lbl, util::array<float> arr, int start)
+void save_label_plot(int count, const char* desc, L prev_lbl, const util::array<float>& arr, int start)
{
std::ostringstream slabel;
if (count < 10)
diff --git a/milena/sandbox/fabien/igr/graph.cc b/milena/sandbox/fabien/igr/graph.cc
index 80f7656..b0efdc5 100644
--- a/milena/sandbox/fabien/igr/graph.cc
+++ b/milena/sandbox/fabien/igr/graph.cc
@@ -1,64 +1,53 @@
#include <iostream>
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/image3d.hh>
-#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/core/alias/dpoint2d.hh>
#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/alias/window2d.hh>
#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/alias/vec3d.hh>
+#include <mln/core/alias/window2d.hh>
#include <mln/core/alias/window3d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/routine/extend.hh>
+#include <mln/core/var.hh>
-#include <mln/io/dump/all.hh>
-#include <mln/io/dicom/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/value/int_u12.hh>
-#include <mln/value/label_16.hh>
-#include <mln/value/label_32.hh>
-#include <mln/value/rgb8.hh>
-
-#include <mln/morpho/watershed/flooding.hh>
-
-#include <mln/math/diff_abs.hh>
-
-#include <mln/labeling/mean_values.hh>
-
+#include <mln/accu/center.hh>
+#include <mln/accu/compute.hh>
#include <mln/convert/to_fun.hh>
-#include <mln/make/graph.hh>
-#include <mln/util/graph.hh>
+#include <mln/data/stretch.hh>
-#include <mln/fun/l2l/wrap.hh>
+#include <mln/debug/draw_graph.hh>
-#include <mln/core/var.hh>
-#include <mln/morpho/elementary/dilation.hh>
+#include <mln/draw/box.hh>
-#include <mln/core/routine/extend.hh>
+#include <mln/fun/v2v/id.hh>
-#include <mln/core/alias/vec3d.hh>
-#include <mln/debug/draw_graph.hh>
-#include <mln/accu/center.hh>
+#include <mln/io/dicom/load.hh>
#include <mln/io/dump/all.hh>
-#include <mln/value/label_8.hh>
-#include <mln/value/rgb16.hh>
-#include <mln/accu/compute.hh>
-#include <mln/core/alias/dpoint2d.hh>
-#include <mln/draw/box.hh>
-#include <mln/data/stretch.hh>
-#include <mln/fun/v2v/id.hh>
-#include <mln/fun/l2l/wrap.hh>
-#include <mln/core/image/line_graph_elt_neighborhood.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/labeling/colorize.hh>
#include <mln/labeling/mean_values.hh>
-#include <mln/extension/adjust_fill.hh>
-#include <mln/extract/all.hh>
+
#include <mln/make/region_adjacency_graph.hh>
-#include <mln/labeling/colorize.hh>
+#include <mln/math/diff_abs.hh>
+#include <mln/morpho/elementary/dilation.hh>
+#include <mln/morpho/watershed/flooding.hh>
+#include <mln/util/graph.hh>
+#include <mln/value/int_u12.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_16.hh>
+#include <mln/value/label_32.hh>
+#include <mln/value/label_8.hh>
+#include <mln/value/rgb16.hh>
+#include <mln/value/rgb8.hh>
// Given a color image and a wshed image, computes the component graph.
// Vertex values are computed thanks to a RGB image.
@@ -274,7 +263,7 @@ int main(int argc, char *argv[])
io::dicom::load(dcm, argv[3]);
/// Build graph
- util::graph g = make::graph(wshed, c4(), nbasins);
+ util::graph g = make::region_adjacency_graph(wshed, c4(), nbasins);
// Build graph images and compute distance values with a RGB image.
mln_VAR(ima_v, make_vertex_graph_image(g, dcm, wshed, nbasins));
mln_VAR(ima_e, make_edge_graph_image(ima_v, g));
@@ -308,7 +297,7 @@ int main(int argc, char *argv[])
image2d<label_16> wsd2 = data::transform(wshed, f);
/// Reconstruct a graph from the simplified image.
- util::graph g2 = make::graph(wsd2, c4(), nbasins2);
+ util::graph g2 = make::region_adjacency_graph(wsd2, c4(), nbasins2);
// Compute distance values with a RGB image.
mln_VAR(ima_v2, make_vertex_graph_image(g2, dcm, wsd2, nbasins2));
diff --git a/milena/sandbox/fabien/igr/mean_slices.cc b/milena/sandbox/fabien/igr/mean_slices.cc
index fe3c38b..d064692 100644
--- a/milena/sandbox/fabien/igr/mean_slices.cc
+++ b/milena/sandbox/fabien/igr/mean_slices.cc
@@ -25,7 +25,7 @@
#include <mln/accu/stat/mean.hh>
#include <mln/accu/stat/median_h.hh>
-#include <mln/labeling/relabel.hh>
+#include <mln/labeling/pack.hh>
#include <mln/labeling/mean_values.hh>
#include <mln/data/compute.hh>
#include <mln/make/image3d.hh>
@@ -76,7 +76,7 @@ int main(int argc, char *argv[])
{
image2d<int_u12> sli = duplicate(slice(ima, i));
image2d<L> sli_labels = duplicate(slice(ima_labels, i));
- image2d<L> labels = labeling::relabel(sli_labels, nlabels);
+ image2d<L> labels = labeling::pack(sli_labels, nlabels);
mln_VAR(mean_slice, labeling::mean_values(sli, labels, nlabels));
arr.append(mean_slice);
}
diff --git a/milena/sandbox/fabien/igr/nbasins_finder.cc b/milena/sandbox/fabien/igr/nbasins_finder.cc
index f1a4337..a621e2b 100644
--- a/milena/sandbox/fabien/igr/nbasins_finder.cc
+++ b/milena/sandbox/fabien/igr/nbasins_finder.cc
@@ -25,8 +25,6 @@
#include <mln/morpho/closing/volume.hh>
#include <mln/morpho/watershed/flooding.hh>
-#include <mln/fun/l2l/wrap.hh>
-
#include <mln/labeling/colorize.hh>
@@ -72,7 +70,7 @@ int main(int argc, char *argv[])
// Visualization
std::cout << " nbasins = " << nbasins << std::endl;
- //io::dump::save(data::transform(wshed, fun::l2l::wrap<int_u8>()), "result_nbasins.dump");
+ //io::dump::save(data::transform(wshed, fun::v2v::wrap<int_u8>()), "result_nbasins.dump");
//io::dump::save(data::stretch(int_u8(), wshed), "result_nbasins.dump");
io::dump::save(labeling::colorize(rgb8(), wshed, nbasins), "result_nbasins.dump");
diff --git a/milena/sandbox/fabien/igr/seg2d.cc b/milena/sandbox/fabien/igr/seg2d.cc
index a14e57a..5cc49d8 100644
--- a/milena/sandbox/fabien/igr/seg2d.cc
+++ b/milena/sandbox/fabien/igr/seg2d.cc
@@ -40,14 +40,14 @@ int main(int argc, char* argv[])
data::fill(ima_thres, false);
unsigned threshold_value = find_threshold_value(ima, c4());
std::cout << "double threshold value = " << threshold_value << std::endl;
- data::fill((ima_thres | pw::value(ima) < pw::cst(threshold_value)).rw(), true);
+ data::fill((ima_thres | (pw::value(ima) < pw::cst(threshold_value))).rw(), true);
io::pbm::save(ima_thres, "result_double.pbm");
data::fill(ima_thres, false);
threshold_value = find_threshold_mean(ima, c4());
std::cout << " deviation threshold value = " << threshold_value << std::endl;
- data::fill((ima_thres | pw::value(ima) < pw::cst(threshold_value)).rw(), true);
+ data::fill((ima_thres | (pw::value(ima) < pw::cst(threshold_value))).rw(), true);
io::pbm::save(ima_thres, "result_deviation.pbm");
diff --git a/milena/sandbox/fabien/igr/seg_vol_irm.hh b/milena/sandbox/fabien/igr/seg_vol_irm.hh
index 8c1711d..a82beb5 100644
--- a/milena/sandbox/fabien/igr/seg_vol_irm.hh
+++ b/milena/sandbox/fabien/igr/seg_vol_irm.hh
@@ -186,7 +186,7 @@ find_threshold_value(const Image<I>& input, const Neighborhood<N>& nbh)
unsigned result = 0;
// We remove the 0 value because it is not part of the image.
- histo::array<mln_value(I)> arr_histo = histo::compute(input | pw::value(input) != 0);
+ histo::array<mln_value(I)> arr_histo = histo::compute(input | (pw::value(input) != 0));
image1d<unsigned> ima_histo;
convert::from_to(arr_histo, ima_histo);
@@ -205,12 +205,12 @@ find_threshold_value(const Image<I>& input, const Neighborhood<N>& nbh)
{
if (!low_done && ((ima_histo(point1d(i)) * 100) / max) > bg_thres)
{
- data::fill((ima_bg | pw::value(input) < pw::cst(i)).rw(), true);
+ data::fill((ima_bg | (pw::value(input) < pw::cst(i))).rw(), true);
low_done = true;
}
if (!high_done && ((ima_histo(point1d(i)) * 100) / max) > (100 - obj_thres))
{
- data::fill((ima_obj | pw::value(input) > pw::cst(i)).rw(), true);
+ data::fill((ima_obj | (pw::value(input) > pw::cst(i))).rw(), true);
high_done = true;
}
}
@@ -246,9 +246,9 @@ find_threshold_value(const Image<I>& input, const Neighborhood<N>& nbh)
data::fill((ima_obj | (pw::value(obj_labels) != pw::cst(arr_o_big[1]))).rw(), false);*/
// Debug output images
- mln_ch_value(I, rgb8) out = data::convert(rgb8(), level::stretch(int_u8(), input));
- data::fill((out | pw::value(morpho::elementary::gradient_internal(ima_bg, nbh)) == true).rw(), literal::red);
- data::fill((out | pw::value(morpho::elementary::gradient_internal(ima_obj, nbh)) == true).rw(), literal::green);
+ mln_ch_value(I, rgb8) out = data::convert(rgb8(), data::stretch(int_u8(), input));
+ data::fill((out | (pw::value(morpho::elementary::gradient_internal(ima_bg, nbh)) == true)).rw(), literal::red);
+ data::fill((out | (pw::value(morpho::elementary::gradient_internal(ima_obj, nbh)) == true)).rw(), literal::green);
save_regions_color(out, metal::int_<I::site::dim>());
if (I::site::dim == 2)
{
@@ -262,8 +262,8 @@ find_threshold_value(const Image<I>& input, const Neighborhood<N>& nbh)
}
// Histo
- histo::array<mln_value(I)> bg_histo = histo::compute(input | pw::value(ima_bg) == true);
- histo::array<mln_value(I)> obj_histo = histo::compute(input | pw::value(ima_obj) == true);
+ histo::array<mln_value(I)> bg_histo = histo::compute(input | (pw::value(ima_bg) == true));
+ histo::array<mln_value(I)> obj_histo = histo::compute(input | (pw::value(ima_obj) == true));
accu::math::sum<unsigned> sum_accu;
image1d<unsigned> ima_bg_histo;
@@ -313,13 +313,14 @@ template <typename I, typename N>
unsigned
find_threshold_mean(const Image<I>& input, const Neighborhood<N>& nbh)
{
+ (void) nbh;
unsigned coef = 1;
accu::stat::mean<unsigned> mean_accu;
unsigned mean = data::compute(mean_accu, (input | (pw::value(input) != 0)));
accu::stat::deviation<unsigned, unsigned, float> dev_accu(mean);
- float deviation = data::compute(dev_accu, (input | pw::value(input) != 0));
+ float deviation = data::compute(dev_accu, (input | (pw::value(input) != 0)));
std::cout << "[mean = " << mean << " | deviation = " << deviation << "]";
return floor(mean + coef * deviation);
diff --git a/milena/sandbox/fabien/igr/watershed2d.cc b/milena/sandbox/fabien/igr/watershed2d.cc
index 858236e..09ece2c 100644
--- a/milena/sandbox/fabien/igr/watershed2d.cc
+++ b/milena/sandbox/fabien/igr/watershed2d.cc
@@ -1,64 +1,51 @@
#include <iostream>
-#include <mln/core/image/image2d.hh>
+
+#include <mln/core/alias/dpoint2d.hh>
#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/alias/vec3d.hh>
#include <mln/core/alias/window2d.hh>
#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/routine/extend.hh>
+#include <mln/core/var.hh>
-#include <mln/io/ppm/save.hh>
-#include <mln/io/ppm/load.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/dicom/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/dump/save.hh>
-
-#include <mln/value/rgb8.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/value/int_u12.hh>
-#include <mln/value/label_16.hh>
+#include <mln/accu/center.hh>
+#include <mln/accu/compute.hh>
+#include <mln/convert/to_fun.hh>
-#include <mln/data/transform.hh>
#include <mln/data/stretch.hh>
+#include <mln/data/transform.hh>
-#include <mln/labeling/mean_values.hh>
+#include <mln/debug/draw_graph.hh>
-#include <mln/convert/to_fun.hh>
+#include <mln/draw/box.hh>
-#include <mln/make/graph.hh>
+#include <mln/fun/v2v/id.hh>
+#include <mln/fun/v2v/wrap.hh>
-#include <mln/morpho/gradient.hh>
-#include <mln/morpho/closing/area.hh>
-#include <mln/morpho/meyer_wst.hh>
+#include <mln/io/dicom/load.hh>
+#include <mln/io/dump/save.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/ppm/all.hh>
-#include <mln/fun/l2l/wrap.hh>
+#include <mln/labeling/mean_values.hh>
-#include <mln/core/var.hh>
-#include <mln/morpho/elementary/dilation.hh>
+#include <mln/make/region_adjacency_graph.hh>
-#include <mln/core/routine/extend.hh>
+#include <mln/math/diff_abs.hh>
-#include <mln/util/graph.hh>
+#include <mln/morpho/closing/area.hh>
+#include <mln/morpho/elementary/dilation.hh>
+#include <mln/morpho/gradient.hh>
+#include <mln/morpho/meyer_wst.hh>
-#include <mln/essential/2d.hh>
-#include <mln/core/alias/vec3d.hh>
-#include <mln/debug/draw_graph.hh>
#include <mln/util/graph.hh>
-#include <mln/accu/center.hh>
-#include <mln/io/dump/all.hh>
-#include <mln/value/label_8.hh>
-#include <mln/value/rgb16.hh>
-#include <mln/accu/compute.hh>
-#include <mln/core/alias/dpoint2d.hh>
-#include <mln/draw/box.hh>
-#include <mln/data/stretch.hh>
-#include <mln/fun/v2v/id.hh>
-#include <mln/fun/l2l/wrap.hh>
-#include <mln/core/image/line_graph_elt_neighborhood.hh>
-#include <mln/morpho/elementary/dilation.hh>
-#include <mln/labeling/mean_values.hh>
-#include <mln/extension/adjust_fill.hh>
-#include <mln/extract/all.hh>
-#include <mln/make/region_adjacency_graph.hh>
+
+#include <mln/value/int_u12.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_16.hh>
+#include <mln/value/rgb8.hh>
@@ -268,16 +255,16 @@ int main(int argc, char *argv[])
image2d<label_16> wshed = morpho::meyer_wst(clo, c4(), nbasins);
io::pgm::save(data::stretch(int_u8(), clo), "wsd_02.pgm");
- io::pgm::save(data::transform(wshed, fun::l2l::wrap<int_u8>()), "wsd_03.pgm");
+ io::pgm::save(data::transform(wshed, fun::v2v::wrap<int_u8>()), "wsd_03.pgm");
mln_VAR(vol2_, morpho::elementary::dilation(extend(wshed | (pw::value(wshed) == 0u), wshed), c8()));
data::fill((wshed | (pw::value(wshed) == 0u)).rw(), vol2_);
- io::pgm::save(data::transform(wshed, fun::l2l::wrap<int_u8>()), "wsd_04.pgm");
+ io::pgm::save(data::transform(wshed, fun::v2v::wrap<int_u8>()), "wsd_04.pgm");
/// Build graph
- util::graph g = make::graph(wshed, c4(), nbasins);
+ util::graph g = make::region_adjacency_graph(wshed, c4(), nbasins);
// Build graph images and compute distance values with a RGB image.
mln_VAR(ima_v, make_vertex_graph_image(g, dcm, wshed, nbasins));
mln_VAR(ima_e, make_edge_graph_image(ima_v, g));
@@ -311,10 +298,10 @@ int main(int argc, char *argv[])
--nbasins2; // nbasins2 does not count the basin with label 0.
image2d<label_16> wsd2 = data::transform(wshed, f);
- io::pgm::save(data::transform(wsd2, fun::l2l::wrap<int_u8>()), "wsd_05.pgm");
+ io::pgm::save(data::transform(wsd2, fun::v2v::wrap<int_u8>()), "wsd_05.pgm");
/// Reconstruct a graph from the simplified image.
- util::graph g2 = make::graph(wsd2, c4(), nbasins2);
+ util::graph g2 = make::region_adjacency_graph(wsd2, c4(), nbasins2);
// Compute distance values with a RGB image.
mln_VAR(ima_v2, make_vertex_graph_image(g2, dcm, wsd2, nbasins2));
@@ -324,8 +311,8 @@ int main(int argc, char *argv[])
data::fill((wsd2 | (pw::value(wsd2) == 0u)).rw(), wsd2_);
- io::pgm::save(data::transform(labeling::mean_values(dcm, wsd2, nbasins2), fun::l2l::wrap<int_u8>()), "wsd_06_mean_colors.pgm");
+ io::pgm::save(data::transform(labeling::mean_values(dcm, wsd2, nbasins2), fun::v2v::wrap<int_u8>()), "wsd_06_mean_colors.pgm");
io::pgm::save(data::stretch(int_u8(), make_debug_graph_image(dcm, ima_v2, ima_e2, box_size, 4095)), "wsd_07_graph_image2_white.pgm");
io::pgm::save(data::stretch(int_u8(), make_debug_graph_image(dcm, ima_v2, ima_e2, box_size, 0)), "wsd_08_graph_image2_black.pgm");
- io::pgm::save(data::transform(wsd2, fun::l2l::wrap<int_u8>()), "wsd_99_result.pgm");
+ io::pgm::save(data::transform(wsd2, fun::v2v::wrap<int_u8>()), "wsd_99_result.pgm");
}
diff --git a/milena/sandbox/fabien/igr/watershed3d.cc b/milena/sandbox/fabien/igr/watershed3d.cc
index 18d4276..3b38bc3 100644
--- a/milena/sandbox/fabien/igr/watershed3d.cc
+++ b/milena/sandbox/fabien/igr/watershed3d.cc
@@ -1,69 +1,55 @@
#include <iostream>
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/image3d.hh>
+#include <mln/core/alias/dpoint2d.hh>
#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/alias/window2d.hh>
#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/alias/vec3d.hh>
+#include <mln/core/alias/window2d.hh>
#include <mln/core/alias/window3d.hh>
#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/routine/extend.hh>
+#include <mln/core/var.hh>
-#include <mln/io/ppm/save.hh>
-#include <mln/io/ppm/load.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/dicom/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/dump/save.hh>
+#include <mln/accu/center.hh>
+#include <mln/accu/compute.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/value/int_u12.hh>
-#include <mln/value/label_16.hh>
-#include <mln/value/label_32.hh>
+#include <mln/convert/to_fun.hh>
-#include <mln/data/transform.hh>
#include <mln/data/stretch.hh>
+#include <mln/data/transform.hh>
-#include <mln/labeling/mean_values.hh>
+#include <mln/debug/draw_graph.hh>
-#include <mln/convert/to_fun.hh>
+#include <mln/draw/box.hh>
-#include <mln/make/graph.hh>
+#include <mln/fun/v2v/wrap.hh>
+#include <mln/fun/v2v/id.hh>
-#include <mln/morpho/elementary/dilation.hh>
-#include <mln/morpho/elementary/gradient.hh>
-#include <mln/morpho/closing/volume.hh>
-#include <mln/morpho/meyer_wst.hh>
+#include <mln/io/dicom/load.hh>
+#include <mln/io/dump/save.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/ppm/all.hh>
-#include <mln/fun/l2l/wrap.hh>
+#include <mln/labeling/mean_values.hh>
-#include <mln/core/var.hh>
+#include <mln/make/region_adjacency_graph.hh>
-#include <mln/core/routine/extend.hh>
+#include <mln/morpho/closing/volume.hh>
+#include <mln/morpho/elementary/dilation.hh>
+#include <mln/morpho/elementary/gradient.hh>
+#include <mln/morpho/meyer_wst.hh>
#include <mln/util/graph.hh>
-#include <mln/essential/2d.hh>
-#include <mln/core/alias/vec3d.hh>
-#include <mln/debug/draw_graph.hh>
-#include <mln/util/graph.hh>
-#include <mln/accu/center.hh>
-#include <mln/io/dump/all.hh>
+#include <mln/value/int_u12.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_16.hh>
+#include <mln/value/label_32.hh>
#include <mln/value/label_8.hh>
#include <mln/value/rgb16.hh>
-#include <mln/accu/compute.hh>
-#include <mln/core/alias/dpoint2d.hh>
-#include <mln/draw/box.hh>
-#include <mln/data/stretch.hh>
-#include <mln/fun/v2v/id.hh>
-#include <mln/fun/l2l/wrap.hh>
-#include <mln/core/image/line_graph_elt_neighborhood.hh>
-#include <mln/morpho/elementary/dilation.hh>
-#include <mln/labeling/mean_values.hh>
-#include <mln/extension/adjust_fill.hh>
-#include <mln/extract/all.hh>
-#include <mln/make/region_adjacency_graph.hh>
-
+#include <mln/value/rgb8.hh>
// Given a color image and a wshed image, computes the component graph.
@@ -281,12 +267,12 @@ int main(int argc, char *argv[])
// Debug
io::dump::save(data::stretch(int_u8(), clo), "wsd_02.dump");
- io::dump::save(data::transform(wshed, fun::l2l::wrap<int_u8>()), "wsd_03.dump");
+ io::dump::save(data::transform(wshed, fun::v2v::wrap<int_u8>()), "wsd_03.dump");
//mln_VAR(vol2_, morpho::elementary::dilation(extend(wshed | (pw::value(wshed) == 0u), wshed), c26()));
//data::fill((wshed | (pw::value(wshed) == 0u)).rw(), vol2_);
- io::dump::save(data::transform(wshed, fun::l2l::wrap<int_u8>()), "wsd_04.dump");
+ io::dump::save(data::transform(wshed, fun::v2v::wrap<int_u8>()), "wsd_04.dump");
/// Graph
trace::quiet = false;
@@ -324,7 +310,7 @@ int main(int argc, char *argv[])
--nbasins2; // nbasins2 does not count the basin with label 0.
image3d<label_32> wsd2 = data::transform(wshed, f);
- io::dump::save(data::transform(wsd2, fun::l2l::wrap<int_u8>()), "wsd_05.dump");
+ io::dump::save(data::transform(wsd2, fun::v2v::wrap<int_u8>()), "wsd_05.dump");
/// Reconstruct a graph from the simplified image.
util::graph g2 = make::graph(wsd2, c6(), nbasins2);
@@ -337,8 +323,8 @@ int main(int argc, char *argv[])
data::fill((wsd2 | (pw::value(wsd2) == 0u)).rw(), wsd2_);
- io::dump::save(data::transform(labeling::mean_values(dcm, wsd2, nbasins2), fun::l2l::wrap<int_u8>()), "wsd_06_mean_colors.dump");
+ io::dump::save(data::transform(labeling::mean_values(dcm, wsd2, nbasins2), fun::v2v::wrap<int_u8>()), "wsd_06_mean_colors.dump");
//io::dump::save(data::stretch(int_u8(), make_debug_graph_image(dcm, ima_v2, ima_e2, box_size, 4095)), "wsd_07_graph_image2_white.dump");
//io::dump::save(data::stretch(int_u8(), make_debug_graph_image(dcm, ima_v2, ima_e2, box_size, 0)), "wsd_08_graph_image2_black.dump");
- io::dump::save(data::transform(wsd2, fun::l2l::wrap<int_u8>()), "wsd_99_result.dump");*/
+ io::dump::save(data::transform(wsd2, fun::v2v::wrap<int_u8>()), "wsd_99_result.dump");*/
}
diff --git a/milena/sandbox/fabien/igr/wst_edges.cc b/milena/sandbox/fabien/igr/wst_edges.cc
index 3524ca8..1d7f37f 100644
--- a/milena/sandbox/fabien/igr/wst_edges.cc
+++ b/milena/sandbox/fabien/igr/wst_edges.cc
@@ -58,7 +58,7 @@
#include "plot_points/int2rgb.hh"
-#include <mln/world/inter_pixel/display_region.hh>
+#include <mln/world/inter_pixel/display_edge.hh>
using namespace mln;
--
1.5.6.5
1
0
* mln/accu/count_labels.hh,
* mln/labeling/relabel.hh: Disable preconditions related to
Symbolic value types.
* mln/data/compare.hh: Pass variable with exact type.
* mln/geom/max_sli.hh,
* mln/geom/min_sli.hh: Use geom::bbox.
* mln/io/plot/save.hh: Rename template parameter.
* mln/util/set.hh: Reindent header.
---
milena/ChangeLog | 17 +++++++++++++++++
milena/mln/accu/count_labels.hh | 4 ++--
milena/mln/data/compare.hh | 2 +-
milena/mln/geom/max_sli.hh | 3 ++-
milena/mln/geom/min_sli.hh | 3 ++-
milena/mln/io/plot/save.hh | 8 ++++----
milena/mln/labeling/relabel.hh | 8 ++++----
milena/mln/util/set.hh | 3 ++-
8 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 8896a5f..6d1aa08 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,22 @@
2009-10-28 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Small fixes.
+
+ * mln/accu/count_labels.hh,
+ * mln/labeling/relabel.hh: Disable preconditions related to
+ Symbolic value types.
+
+ * mln/data/compare.hh: Pass variable with exact type.
+
+ * mln/geom/max_sli.hh,
+ * mln/geom/min_sli.hh: Use geom::bbox.
+
+ * mln/io/plot/save.hh: Rename template parameter.
+
+ * mln/util/set.hh: Reindent header.
+
+2009-10-28 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add data::wrap.
* mln/data/wrap.hh: New.
diff --git a/milena/mln/accu/count_labels.hh b/milena/mln/accu/count_labels.hh
index 7a24766..07c48b2 100644
--- a/milena/mln/accu/count_labels.hh
+++ b/milena/mln/accu/count_labels.hh
@@ -50,8 +50,8 @@ namespace mln
//
template <typename L>
struct count_labels
- : public mln::accu::internal::base< unsigned , count_labels<L> >,
- mlc_is_a(L, mln::value::Symbolic)::check_t
+ : public mln::accu::internal::base< unsigned , count_labels<L> >
+ // mlc_is_a(L, mln::value::Symbolic)::check_t
{
typedef L argument;
diff --git a/milena/mln/data/compare.hh b/milena/mln/data/compare.hh
index 30ea9ce..8a55739 100644
--- a/milena/mln/data/compare.hh
+++ b/milena/mln/data/compare.hh
@@ -95,7 +95,7 @@ namespace mln
mln_precondition(lhs.domain() == rhs.domain());
typedef fun::vv2b::eq<mln_value(L), mln_value(R)> F;
- bool res = test::predicate(lhs_, rhs_, F());
+ bool res = test::predicate(lhs, rhs, F());
trace::exiting("data::compare (==)");
return res;
diff --git a/milena/mln/geom/max_sli.hh b/milena/mln/geom/max_sli.hh
index c016cbc..b0c541c 100644
--- a/milena/mln/geom/max_sli.hh
+++ b/milena/mln/geom/max_sli.hh
@@ -32,6 +32,7 @@
# include <mln/core/concept/image.hh>
+# include <mln/geom/bbox.hh>
namespace mln
{
@@ -53,7 +54,7 @@ namespace mln
trace::entering("mln::geom::max_sli");
mln_precondition(exact(ima).is_valid());
- mln_deduce(I, site, coord) maxsli = exact(ima).bbox().pmax().sli();
+ mln_deduce(I, site, coord) maxsli = geom::bbox(ima).pmax().sli();
trace::exiting("mln::geom::max_sli");
return maxsli;
diff --git a/milena/mln/geom/min_sli.hh b/milena/mln/geom/min_sli.hh
index ecd8857..7b07a8c 100644
--- a/milena/mln/geom/min_sli.hh
+++ b/milena/mln/geom/min_sli.hh
@@ -32,6 +32,7 @@
# include <mln/core/concept/image.hh>
+# include <mln/geom/bbox.hh>
namespace mln
{
@@ -53,7 +54,7 @@ namespace mln
trace::entering("mln::geom::min_sli");
mln_precondition(exact(ima).is_valid());
- mln_deduce(I, site, coord) minsli = exact(ima).bbox().pmin().sli();
+ mln_deduce(I, site, coord) minsli = geom::bbox(ima).pmin().sli();
trace::exiting("mln::geom::min_sli");
return minsli;
diff --git a/milena/mln/io/plot/save.hh b/milena/mln/io/plot/save.hh
index 1a01267..8010afa 100644
--- a/milena/mln/io/plot/save.hh
+++ b/milena/mln/io/plot/save.hh
@@ -57,8 +57,8 @@ namespace mln
\param[out] filename The output file.
\param[in] start_value The start index value of the plot
(optional). */
- template <typename I>
- void save(util::array<I>& arr,
+ template <typename T>
+ void save(util::array<T>& arr,
const std::string& filename,
int start_value = 0);
@@ -82,9 +82,9 @@ namespace mln
trace::exiting("mln::io::plot::save");
}
- template <typename I>
+ template <typename T>
inline
- void save(const util::array<I>& arr, const std::string& filename,
+ void save(const util::array<T>& arr, const std::string& filename,
int start_value = 0)
{
trace::entering("mln::io::plot::save");
diff --git a/milena/mln/labeling/relabel.hh b/milena/mln/labeling/relabel.hh
index b8ebc12..dfb35fb 100644
--- a/milena/mln/labeling/relabel.hh
+++ b/milena/mln/labeling/relabel.hh
@@ -120,7 +120,7 @@ namespace mln
mln_value(I)& new_nlabels)
{
// FIXME: we may want to check that it is exactly a label.
- mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
+// mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
mln_precondition(exact(label).is_valid());
(void) label;
(void) new_nlabels;
@@ -134,7 +134,7 @@ namespace mln
const Function<F>& f)
{
// FIXME: we may want to check that it is exactly a label.
- mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
+// mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
mln_precondition(exact(label).is_valid());
(void) label;
(void) nlabels;
@@ -149,7 +149,7 @@ namespace mln
const Function<F>& f)
{
// FIXME: we may want to check that it is exactly a label.
- mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
+// mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
mln_precondition(exact(label).is_valid());
(void) label;
(void) nlabels;
@@ -164,7 +164,7 @@ namespace mln
const Function<F>& f)
{
// FIXME: we may want to check that it is exactly a label.
- mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
+// mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
mln_precondition(exact(label).is_valid());
(void) label;
(void) nlabels;
diff --git a/milena/mln/util/set.hh b/milena/mln/util/set.hh
index 29c6ea6..d9e91e2 100644
--- a/milena/mln/util/set.hh
+++ b/milena/mln/util/set.hh
@@ -1,4 +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 Olena.
//
--
1.5.6.5
1
0
* mln/data/wrap.hh: New.
* mln/data/all.hh: Include this new file.
---
milena/ChangeLog | 8 +++
milena/mln/data/all.hh | 1 +
milena/mln/data/{all.hh => wrap.hh} | 90 +++++++++++++++++++---------------
3 files changed, 59 insertions(+), 40 deletions(-)
copy milena/mln/data/{all.hh => wrap.hh} (50%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index b6f9ce4..8896a5f 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,11 @@
+2009-10-28 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add data::wrap.
+
+ * mln/data/wrap.hh: New.
+
+ * mln/data/all.hh: Include this new file.
+
2009-10-22 Guillaume Lazzara <z(a)lrde.epita.fr>
Small fixes.
diff --git a/milena/mln/data/all.hh b/milena/mln/data/all.hh
index bc77272..de00450 100644
--- a/milena/mln/data/all.hh
+++ b/milena/mln/data/all.hh
@@ -72,6 +72,7 @@ namespace mln
//<<lrde
# include <mln/data/was.median.hh>
//>>
+# include <mln/data/wrap.hh>
diff --git a/milena/mln/data/all.hh b/milena/mln/data/wrap.hh
similarity index 50%
copy from milena/mln/data/all.hh
copy to milena/mln/data/wrap.hh
index bc77272..1e30f04 100644
--- a/milena/mln/data/all.hh
+++ b/milena/mln/data/wrap.hh
@@ -1,5 +1,4 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
-// Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -24,55 +23,66 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_DATA_ALL_HH
-# define MLN_DATA_ALL_HH
+#ifndef MLN_DATA_WRAP_HH
+# define MLN_DATA_WRAP_HH
/// \file
///
-/// File that includes all data-related routines.
+/// \brief Routine to wrap values such as 0 -> 0 and [1, lmax] maps to [1,
+/// Lmax] (using modulus).
+
+
+#include <mln/core/concept/image.hh>
+
+#include <mln/data/transform.hh>
+#include <mln/fun/v2v/wrap.hh>
namespace mln
{
- /// Namespace of image processing routines related to pixel data.
namespace data
{
- /// Implementation namespace of data namespace.
- namespace impl {
+ /*! \brief Routine to wrap values such as 0 -> 0 and [1, lmax] maps to [1,
+ Lmax] (using modulus).
+
+ \param[in] v The target value type.
+ \param[in] input Input image.
+
+ \return An image with wrapped values.
+ */
+ template <typename V, typename I>
+ mln_ch_value(I, V)
+ wrap(const V& v, const Image<I>& input);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
- /// Generic implementation namespace of data namespace.
- namespace generic {}
+ template <typename V, typename I>
+ mln_ch_value(I, V)
+ wrap(const V& v, const Image<I>& input_)
+ {
+ trace::entering("mln::data::wrap");
+ (void) v;
+ const I& input = exact(input_);
+
+ mln_precondition(input.is_valid());
+
+ mln_ch_value(I, V)
+ output = data::transform(input, fun::v2v::wrap<V>());
+
+ trace::exiting("mln::data::wrap");
+ return output;
}
- }
-}
-
-
-# include <mln/data/abs.hh>
-# include <mln/data/apply.hh>
-# include <mln/data/approx/all.hh>
-# include <mln/data/compare.hh>
-# include <mln/data/compute.hh>
-# include <mln/data/convert.hh>
-# include <mln/data/fast_median.hh>
-# include <mln/data/fill.hh>
-# include <mln/data/median.hh>
-# include <mln/data/naive/all.hh>
-# include <mln/data/paste.hh>
-# include <mln/data/replace.hh>
-# include <mln/data/saturate.hh>
-# include <mln/data/sort_offsets.hh>
-# include <mln/data/sort_psites.hh>
-# include <mln/data/stretch.hh>
-# include <mln/data/to_enc.hh>
-# include <mln/data/transform.hh>
-# include <mln/data/update.hh>
-//<<lrde
-# include <mln/data/was.median.hh>
-//>>
-
-
-
-#endif // ! MLN_DATA_ALL_HH
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::data
+
+} // end of namespace mln
+
+
+#endif // ! MLN_DATA_WRAP_HH
--
1.5.6.5
1
0
* demo.pro: Include new files.
* src/display.cc,
* src/display.hh,
* ui/display.ui: New tab widget.
* src/display_seg.cc,
* src/display_seg.hh: Improve display.
* src/edit_seg.cc,
* src/edit_seg.hh: Improve segmentation editing.
* src/widgets.cc: Include new file.
* ui/main_window.ui: Add a new tab.
---
milena/sandbox/ChangeLog | 20 +++
milena/sandbox/lazzara/igr/gui/demo.pro | 4 +-
.../igr/gui/src/{display_seg.cc => display.cc} | 55 ++-------
.../igr/gui/src/{display_seg.hh => display.hh} | 20 +--
milena/sandbox/lazzara/igr/gui/src/display_seg.cc | 8 +-
milena/sandbox/lazzara/igr/gui/src/display_seg.hh | 3 +-
milena/sandbox/lazzara/igr/gui/src/edit_seg.cc | 128 +++++++++++++------
milena/sandbox/lazzara/igr/gui/src/edit_seg.hh | 17 ++-
milena/sandbox/lazzara/igr/gui/src/widgets.cc | 1 +
milena/sandbox/lazzara/igr/gui/ui/display.ui | 88 ++++++++++++++
milena/sandbox/lazzara/igr/gui/ui/main_window.ui | 21 +++-
scribo/headers.mk | 7 +-
12 files changed, 248 insertions(+), 124 deletions(-)
copy milena/sandbox/lazzara/igr/gui/src/{display_seg.cc => display.cc} (70%)
copy milena/sandbox/lazzara/igr/gui/src/{display_seg.hh => display.hh} (82%)
create mode 100644 milena/sandbox/lazzara/igr/gui/ui/display.ui
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 94935e2..08e7332 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,23 @@
+2009-10-28 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Update IGR's GUI.
+
+ * demo.pro: Include new files.
+
+ * src/display.cc,
+ * src/display.hh,
+ * ui/display.ui: New tab widget.
+
+ * src/display_seg.cc,
+ * src/display_seg.hh: Improve display.
+
+ * src/edit_seg.cc,
+ * src/edit_seg.hh: Improve segmentation editing.
+
+ * src/widgets.cc: Include new file.
+
+ * ui/main_window.ui: Add a new tab.
+
2009-10-28 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add the reconstruction on set by union-find canvas.
diff --git a/milena/sandbox/lazzara/igr/gui/demo.pro b/milena/sandbox/lazzara/igr/gui/demo.pro
index 5d1b3b0..26e1a06 100644
--- a/milena/sandbox/lazzara/igr/gui/demo.pro
+++ b/milena/sandbox/lazzara/igr/gui/demo.pro
@@ -11,6 +11,6 @@ LIBS += -L/lrde/dev/linux-x86/stable/gdcm/lib -lgdcmCommon -lgdcmDICT -lgdcmDSED
#CONFIG += debug
# Input
-HEADERS += src/main_window.hh src/image_viewer.hh src/display_seg.hh src/edit_seg.hh src/internal/interactive_scene.hh
-FORMS += ui/main_window.ui ui/image_viewer.ui ui/display_seg.ui ui/edit_seg.ui
+HEADERS += src/main_window.hh src/image_viewer.hh src/display_seg.hh src/edit_seg.hh src/internal/interactive_scene.hh src/display.hh
+FORMS += ui/main_window.ui ui/image_viewer.ui ui/display_seg.ui ui/edit_seg.ui ui/display.ui
SOURCES += src/main.cc src/main_window.cc src/image_viewer.cc src/widgets.cc src/internal/interactive_scene.cc
diff --git a/milena/sandbox/lazzara/igr/gui/src/display_seg.cc b/milena/sandbox/lazzara/igr/gui/src/display.cc
similarity index 70%
copy from milena/sandbox/lazzara/igr/gui/src/display_seg.cc
copy to milena/sandbox/lazzara/igr/gui/src/display.cc
index eae64a9..050644d 100644
--- a/milena/sandbox/lazzara/igr/gui/src/display_seg.cc
+++ b/milena/sandbox/lazzara/igr/gui/src/display.cc
@@ -28,7 +28,7 @@
#include <QtGui>
# define INCLUDE_MLN_FILES
-#include <src/display_seg.hh>
+#include <src/display.hh>
#include <src/image_viewer.hh>
#include <src/to_qimage.hh>
@@ -61,7 +61,7 @@ namespace mln
namespace demo
{
- display_seg::display_seg(QWidget *parent)
+ display::display(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
@@ -70,14 +70,14 @@ namespace mln
this, SLOT(compute_image(int)));
}
- display_seg::~display_seg()
+ display::~display()
{
}
// Private slots
- void display_seg::on_browseBtn_clicked(bool)
+ void display::on_browseBtn_clicked(bool)
{
QString
filename = QFileDialog::getOpenFileName(this,
@@ -89,39 +89,19 @@ namespace mln
filepath->setText(filename);
}
-
- void display_seg::on_browseSegBtn_clicked(bool)
- {
- QString
- filename = QFileDialog::getOpenFileName(this,
- tr("Open Image."),
- QString(),
- tr("Images (*.dump)"));
-
- if (!filename.isEmpty())
- segfilepath->setText(filename);
- }
-
-
- void display_seg::compute_image(int sli)
+ void display::compute_image(int sli)
{
slice_image<dcm_ima_t> sl_ima = slice(dcm_ima, sli);
- mln_piter_(result_t) p(result.domain());
- for_all(p)
- result(p).lum() = (sl_ima(p) / static_cast<float>(mln_max(value::int_u8))) / 2.0;
-
- QImage ima = to_qimage(data::convert(value::rgb8(), result));
+ QImage ima = to_qimage(data::convert(value::rgb8(), sl_ima));
viewer->update_image(ima);
}
- void display_seg::on_loadBtn_clicked(bool)
+ void display::on_loadBtn_clicked(bool)
{
load_dicom(filepath->text());
- load_seg(segfilepath->text());
- setup_result();
viewer->set_image_layer_count(geom::nslis(dcm_ima));
}
@@ -130,24 +110,7 @@ namespace mln
// Private members
- void display_seg::setup_result()
- {
- initialize(result, seg_ima);
- mln_piter_(result_t) p(result.domain());
- for_all(p)
- {
- result(p).hue() = ((seg_ima(p) * 10) % 359) + 1;
- result(p).sat() = 1;
- }
- }
-
- void display_seg::load_seg(const QString& filename)
- {
- io::dump::load(seg_ima, filename.toStdString());
- }
-
-
- void display_seg::load_dicom(const QString& filename)
+ void display::load_dicom(const QString& filename)
{
image3d<value::int_u12> tmp;
io::dicom::load(tmp, filename.toStdString());
@@ -156,7 +119,7 @@ namespace mln
template <typename I>
- mln_ch_value(I, value::int_u8) display_seg::to_int_u8(const Image<I>& ima_)
+ mln_ch_value(I, value::int_u8) display::to_int_u8(const Image<I>& ima_)
{
const I& ima = exact(ima_);
mln_precondition(ima.is_valid());
diff --git a/milena/sandbox/lazzara/igr/gui/src/display_seg.hh b/milena/sandbox/lazzara/igr/gui/src/display.hh
similarity index 82%
copy from milena/sandbox/lazzara/igr/gui/src/display_seg.hh
copy to milena/sandbox/lazzara/igr/gui/src/display.hh
index c559b0d..a329daf 100644
--- a/milena/sandbox/lazzara/igr/gui/src/display_seg.hh
+++ b/milena/sandbox/lazzara/igr/gui/src/display.hh
@@ -23,7 +23,7 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_DEMO_SRC_DISPLAY_SEG_HH
+#ifndef MLN_DEMO_SRC_DISPLAY_HH
# include <QDir>
# include <QTimer>
@@ -31,7 +31,7 @@
# include <QProcess>
# include <QtGui>
# include <QProgressDialog>
-# include <ui_display_seg.h>
+# include <ui_display.h>
# ifndef INCLUDE_MLN_FILES
# define MLN_INCLUDE_ONLY
@@ -50,29 +50,24 @@ namespace mln
namespace demo
{
- class display_seg : public QWidget, private Ui::DisplaySeg
+ class display : public QWidget, private Ui::Display
{
Q_OBJECT
typedef image3d<value::int_u8> dcm_ima_t;
- typedef image2d<value::int_u16> seg_ima_t;
- typedef image2d<value::hsl_f> result_t;
public:
- display_seg(QWidget *parent = 0);
- ~display_seg();
+ display(QWidget *parent = 0);
+ ~display();
private slots:
void on_browseBtn_clicked(bool);
- void on_browseSegBtn_clicked(bool);
void compute_image(int sli);
void on_loadBtn_clicked(bool);
private: // Members
-
void setup_result();
- void load_seg(const QString& filename);
void load_dicom(const QString& filename);
template <typename I>
@@ -82,9 +77,6 @@ namespace mln
private: // Attributes
dcm_ima_t dcm_ima;
- seg_ima_t seg_ima;
- value::int_u8 nlabels_;
- result_t result;
};
@@ -93,4 +85,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_DEMO_SRC_DISPLAY_SEG_HH
+#endif // ! MLN_DEMO_SRC_DISPLAY_HH
diff --git a/milena/sandbox/lazzara/igr/gui/src/display_seg.cc b/milena/sandbox/lazzara/igr/gui/src/display_seg.cc
index eae64a9..9d36ca2 100644
--- a/milena/sandbox/lazzara/igr/gui/src/display_seg.cc
+++ b/milena/sandbox/lazzara/igr/gui/src/display_seg.cc
@@ -42,7 +42,6 @@
#include <mln/value/hsl.hh>
#include <mln/value/rgb8.hh>
#include <mln/value/int_u12.hh>
-#include <mln/value/int_u8.hh>
#include <mln/value/int_u32.hh>
#include <mln/value/int_u8.hh>
#include <mln/data/convert.hh>
@@ -109,7 +108,7 @@ namespace mln
mln_piter_(result_t) p(result.domain());
for_all(p)
- result(p).lum() = (sl_ima(p) / static_cast<float>(mln_max(value::int_u8))) / 2.0;
+ result(p).lum() = (sl_ima(p) / static_cast<float>(mln_max(value::int_u8))) * 0.7;
QImage ima = to_qimage(data::convert(value::rgb8(), result));
@@ -132,11 +131,12 @@ namespace mln
void display_seg::setup_result()
{
- initialize(result, seg_ima);
+ slice_image<seg_ima_t> sl_ima = slice(seg_ima, 0);
+ initialize(result, sl_ima);
mln_piter_(result_t) p(result.domain());
for_all(p)
{
- result(p).hue() = ((seg_ima(p) * 10) % 359) + 1;
+ result(p).hue() = ((sl_ima(p) * 10) % 359) + 1;
result(p).sat() = 1;
}
}
diff --git a/milena/sandbox/lazzara/igr/gui/src/display_seg.hh b/milena/sandbox/lazzara/igr/gui/src/display_seg.hh
index c559b0d..45207c0 100644
--- a/milena/sandbox/lazzara/igr/gui/src/display_seg.hh
+++ b/milena/sandbox/lazzara/igr/gui/src/display_seg.hh
@@ -40,7 +40,6 @@
# include <mln/core/image/image3d.hh>
# include <mln/core/image/image2d.hh>
# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
# include <mln/value/rgb8.hh>
# include <mln/value/hsl.hh>
@@ -55,7 +54,7 @@ namespace mln
Q_OBJECT
typedef image3d<value::int_u8> dcm_ima_t;
- typedef image2d<value::int_u16> seg_ima_t;
+ typedef image3d<value::int_u8> seg_ima_t;
typedef image2d<value::hsl_f> result_t;
public:
diff --git a/milena/sandbox/lazzara/igr/gui/src/edit_seg.cc b/milena/sandbox/lazzara/igr/gui/src/edit_seg.cc
index 14e58b5..ef22ba8 100644
--- a/milena/sandbox/lazzara/igr/gui/src/edit_seg.cc
+++ b/milena/sandbox/lazzara/igr/gui/src/edit_seg.cc
@@ -32,12 +32,14 @@
#include <mln/core/image/image3d.hh>
#include <mln/core/image/imorph/labeled_image.hh>
+#include <mln/core/image/dmorph/slice_image.hh>
#include <mln/core/concept/function.hh>
+#include <mln/geom/nslis.hh>
+
#include <mln/data/wrap.hh>
#include <mln/data/transform_inplace.hh>
-#include <mln/value/int_u16.hh>
#include <mln/value/int_u8.hh>
#include <mln/io/ppm/save.hh>
@@ -46,9 +48,12 @@
#include <mln/literal/colors.hh>
#include <mln/labeling/colorize.hh>
+#include <mln/labeling/relabel.hh>
#include <mln/fun/v2v/wrap.hh>
+#include <mln/accu/stat/max.hh>
+
namespace mln
{
@@ -57,23 +62,23 @@ namespace mln
// struct merge_component : Function_v2v<merge_component>
// {
-// typedef value::int_u16 result;
+// typedef value::int_u8 result;
-// merge_component(const value::int_u16& replaced,
-// const value::int_u16& by)
+// merge_component(const value::int_u8& replaced,
+// const value::int_u8& by)
// : replaced_(replaced), by_(by)
// {
// }
-// value::int_u16 operator()(const value::int_u16& v) const
+// value::int_u8 operator()(const value::int_u8& v) const
// {
// if (v == replaced_)
// return by_;
// return v;
// }
-// value::int_u16 replaced_;
-// value::int_u16 by_;
+// value::int_u8 replaced_;
+// value::int_u8 by_;
// };
// } // end of namespace mln::internal
@@ -91,7 +96,7 @@ namespace mln
setupUi(this);
connect(viewer, SIGNAL(slider_valueChanged(int)),
- this, SLOT(compute_image()));
+ this, SLOT(compute_image(int)));
connect(viewer, SIGNAL(mouse_draw_line(const QPointF&, const QPointF&)),
this, SLOT(join_components(const QPointF&, const QPointF&)));
@@ -102,38 +107,60 @@ namespace mln
edit_seg::~edit_seg()
{
-
}
void edit_seg::on_browseBtn_clicked(bool)
{
QString
- filename = QFileDialog::getOpenFileName(this,
+ filename = QFileDialog::getOpenFileName(0,
tr("Open Image."),
QString(),
tr("Images (*.dump)"));
if (!filename.isEmpty())
+ {
filepath->setText(filename);
- // Initial load.
- image2d<value::int_u16> tmp;
- io::dump::load(tmp, filepath->text().toStdString());
- seg_ = labeled_image<image2d<value::int_u16> >(tmp);
+ // Release memory
+ seg_.destroy();
+ seg_rgb8_.destroy();
+
+ io::dump::load(seg_, filepath->text().toStdString());
- selected_.resize(seg_.nlabels(), false);
+ mln_assertion(seg_.is_valid());
- image2d<value::int_u8> tmp2 = data::wrap(value::int_u8(), seg_);
- seg_rgb8_ = data::convert(value::rgb8(), tmp2);
+ nlabels_ = data::compute(accu::meta::stat::max(), seg_);
- viewer->set_image_layer_count(1);
+ fselected_.resize(nlabels_, false);
+ selected_.clear();
+
+ seg_rgb8_ = data::convert(value::rgb8(),
+ data::wrap(value::int_u8(), seg_));
+
+ viewer->set_image_layer_count(geom::nslis(seg_));
+ }
}
- void edit_seg::compute_image()
+ void edit_seg::compute_image(int sli)
{
- QImage ima = to_qimage(seg_rgb8_);
+ current_sli_ = sli;
+
+ slice_image<image3d<value::int_u8> > sl_ima = slice(seg_, sli);
+
+ bboxes_ = labeling::compute(accu::meta::shape::bbox(), sl_ima, nlabels_);
+
+
+ slice_image<image3d<value::rgb8> > sl_ima_rgb = slice(seg_rgb8_, sli);
+ for (unsigned i = 0; i < selected_.nelements(); ++i)
+ if (selected_[i] < bboxes_.nelements()
+ && bboxes_(selected_[i]).is_valid())
+ data::fill(((sl_ima_rgb | bboxes_(selected_[i])).rw()
+ | (pw::value(sl_ima) == pw::cst(selected_[i]))).rw(),
+ literal::red);
+
+ QImage ima = to_qimage(duplicate(sl_ima_rgb));
viewer->update_image(ima);
}
@@ -160,42 +187,61 @@ namespace mln
void edit_seg::on_saveBtn_clicked(bool)
{
QString
- filename = QFileDialog::getOpenFileName(this,
+ filename = QFileDialog::getSaveFileName(this,
tr("Save Image."),
QString(),
tr("Images (*.dump)"));
+ if (!filename.isEmpty())
+ {
+ value::int_u8 new_nlabels;
+ image3d<value::int_u8>
+ out = labeling::relabel(seg_, nlabels_,
+ new_nlabels, fselected_);
- image2d<value::int_u16>
- out = data::transform(seg_.unmorph_(), selected_);
+ io::dump::save(out, filename.toStdString());
+ }
- io::dump::save(out, filename.toStdString());
}
void edit_seg::select_component(const QPointF& p)
{
- point2d
- mln_p = point2d(p.y(), p.x());
+ point3d
+ mln_p(current_sli_, p.y(), p.x());
+
+ slice_image<image3d<value::rgb8> >
+ sl_ima_rgb = slice(seg_rgb8_, current_sli_);
+ slice_image<image3d<value::int_u8> >
+ sl_ima = slice(seg_, current_sli_);
- if (seg_.domain().has(mln_p)
- && !selected_(seg_(mln_p))
- && seg_(mln_p) != 0) // Not the wsl
+ if (seg_.domain().has(mln_p))
{
- selected_(seg_(mln_p)) = true;
- data::fill((seg_rgb8_ | seg_.subdomain(seg_(mln_p))).rw(),
- literal::red);
+ value::int_u8 v = seg_(mln_p);
+
+ if (!fselected_(v) && v != 0) // Not the wsl
+ {
+ fselected_(v) = true;
+ selected_.insert(v);
+ data::fill(((sl_ima_rgb | bboxes_(v)).rw()
+ | (pw::value(sl_ima) == pw::cst(v))).rw(),
+ literal::red);
+ }
+ else
+ {
+ fselected_(v) = false;
+ selected_.remove(v);
+
+// fun::v2v::wrap<value::int_u8> f;
+// value::int_u8 v8 = f(v);
+ value::rgb8 v_rgb(v, v, v);
+ data::fill(((sl_ima_rgb | bboxes_(v)).rw()
+ | (pw::value(sl_ima) == pw::cst(v))).rw(), v_rgb);
+ }
}
- else
- {
- selected_(seg_(mln_p)) = false;
- value::rgb8
- v = convert::to<value::rgb8>(fun::v2v:wrap<value::int_u8>(seg_(mln_p)));
- value::rgb8 v(seg_(mln_p), seg_(mln_p), seg_(mln_p));
- data::fill((seg_rgb8_ | seg_.subdomain(seg_(mln_p))).rw(), v);
- }
- compute_image();
+ saveBtn->setEnabled(selected_.nelements() > 0);
+ compute_image(current_sli_);
}
diff --git a/milena/sandbox/lazzara/igr/gui/src/edit_seg.hh b/milena/sandbox/lazzara/igr/gui/src/edit_seg.hh
index 0d22db5..708eb2c 100644
--- a/milena/sandbox/lazzara/igr/gui/src/edit_seg.hh
+++ b/milena/sandbox/lazzara/igr/gui/src/edit_seg.hh
@@ -39,9 +39,10 @@
# include <mln/core/image/image2d.hh>
# include <mln/core/image/imorph/labeled_image.hh>
-# include <mln/value/int_u16.hh>
+# include <mln/value/int_u8.hh>
# include <mln/value/rgb8.hh>
# include <mln/util/array.hh>
+# include <mln/util/set.hh>
namespace mln
{
@@ -61,7 +62,7 @@ namespace mln
private slots:
void on_browseBtn_clicked(bool);
void on_saveBtn_clicked(bool);
- void compute_image();
+ void compute_image(int sli);
void join_components(const QPointF& p1, const QPointF& p2);
void select_component(const QPointF& p);
@@ -69,9 +70,15 @@ namespace mln
private: // Attributes
- labeled_image<image2d<value::int_u16> > seg_;
- image2d<value::rgb8> seg_rgb8_;
- mln::util::array<bool> selected_;
+ image3d<value::int_u8> seg_;
+ value::int_u8 nlabels_;
+ image3d<value::rgb8> seg_rgb8_;
+ mln::util::array<box2d> bboxes_;
+
+ mln::util::array<bool> fselected_;
+ mln::util::set<value::int_u8> selected_;
+
+ int current_sli_;
};
diff --git a/milena/sandbox/lazzara/igr/gui/src/widgets.cc b/milena/sandbox/lazzara/igr/gui/src/widgets.cc
index 5968dc4..0171f61 100644
--- a/milena/sandbox/lazzara/igr/gui/src/widgets.cc
+++ b/milena/sandbox/lazzara/igr/gui/src/widgets.cc
@@ -1,3 +1,4 @@
// FIXME: UGLY!!! Avoir multiple definition of Milena's code.
# include "src/display_seg.cc"
# include "src/edit_seg.cc"
+# include "src/display.cc"
diff --git a/milena/sandbox/lazzara/igr/gui/ui/display.ui b/milena/sandbox/lazzara/igr/gui/ui/display.ui
new file mode 100644
index 0000000..7766e27
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/ui/display.ui
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Display</class>
+ <widget class="QWidget" name="Display">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Image</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="filepath"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="browseBtn">
+ <property name="text">
+ <string>&Browse</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>48</width>
+ <height>17</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="loadBtn">
+ <property name="text">
+ <string>&Load</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="mln::demo::image_viewer" name="viewer" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>mln::demo::image_viewer</class>
+ <extends>QWidget</extends>
+ <header>src/image_viewer.hh</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/milena/sandbox/lazzara/igr/gui/ui/main_window.ui b/milena/sandbox/lazzara/igr/gui/ui/main_window.ui
index 75f3327..bab9d23 100644
--- a/milena/sandbox/lazzara/igr/gui/ui/main_window.ui
+++ b/milena/sandbox/lazzara/igr/gui/ui/main_window.ui
@@ -15,18 +15,23 @@
<widget class="QWidget" name="centralwidget" >
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" >
- <widget class="QTabWidget" name="tabWidget" >
+ <widget class="QTabWidget" name="display" >
<property name="currentIndex" >
<number>0</number>
</property>
- <widget class="mln::demo::display_seg" name="Visualization" >
+ <widget class="mln::demo::display" name="display" >
<attribute name="title" >
- <string>Visualization</string>
+ <string>Display</string>
</attribute>
</widget>
- <widget class="mln::demo::edit_seg" name="Edition" >
+ <widget class="mln::demo::display_seg" name="displaySeg" >
<attribute name="title" >
- <string>Edition</string>
+ <string>Display segmentation</string>
+ </attribute>
+ </widget>
+ <widget class="mln::demo::edit_seg" name="editSeg" >
+ <attribute name="title" >
+ <string>Edit segmentation</string>
</attribute>
</widget>
</widget>
@@ -58,6 +63,12 @@
<header>src/edit_seg.hh</header>
<container>1</container>
</customwidget>
+ <customwidget>
+ <class>mln::demo::display</class>
+ <extends>QWidget</extends>
+ <header>src/display.hh</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>
diff --git a/scribo/headers.mk b/scribo/headers.mk
index 6c8d0cf..15d9b2a 100644
--- a/scribo/headers.mk
+++ b/scribo/headers.mk
@@ -24,8 +24,9 @@ nobase_scribo_HEADERS = \
./draw/bounding_boxes.hh \
./estim/object_groups_v_thickness.hh \
./filter/all.hh \
+./filter/common/object_groups_photo.hh \
+./filter/common/object_links_photo.hh \
./filter/common/objects_photo.hh \
-./filter/object_groups_size_ratio.hh \
./filter/object_groups_small.hh \
./filter/object_groups_v_thickness.hh \
./filter/object_links_bbox_h_ratio.hh \
@@ -37,13 +38,10 @@ nobase_scribo_HEADERS = \
./filter/object_links_non_aligned_simple.hh \
./filter/object_links_non_h_aligned.hh \
./filter/object_links_non_v_aligned.hh \
-./filter/objects_h_thin.hh \
./filter/objects_large.hh \
-./filter/objects_size_ratio.hh \
./filter/objects_small.hh \
./filter/objects_thick.hh \
./filter/objects_thin.hh \
-./filter/objects_v_thin.hh \
./fun/v2b/objects_small_filter.hh \
./make/all.hh \
./make/debug_filename.hh \
@@ -82,7 +80,6 @@ nobase_scribo_HEADERS = \
./primitive/internal/find_root.hh \
./primitive/internal/have_link_valid.hh \
./primitive/internal/init_link_array.hh \
-./primitive/internal/is_invalid_link.hh \
./primitive/internal/is_link_valid.hh \
./primitive/internal/update_graph_link.hh \
./primitive/internal/update_link_array.hh \
--
1.5.6.5
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add the reconstruction on set by union-find canvas.
* theo/mln/morpho/reconstruction/by_dilation.hh: Layout.
* theo/mln/morpho/canvas: New directory.
* theo/mln/morpho/canvas/reconstruction_on_set_tiny.cc: New.
* theo/mln/morpho/canvas/reconstruction_on_set.hh: New.
* theo/mln/morpho/canvas/internal: New directory.
* theo/mln/morpho/canvas/internal/find_root.hh: New.
* theo/mln/morpho/canvas/reconstruction_on_set.cc: New.
canvas/internal/find_root.hh | 89 ++++++++
canvas/reconstruction_on_set.cc | 376 +++++++++++++++++++++++++++++++++++
canvas/reconstruction_on_set.hh | 356 +++++++++++++++++++++++++++++++++
canvas/reconstruction_on_set_tiny.cc | 190 +++++++++++++++++
reconstruction/by_dilation.hh | 2
5 files changed, 1011 insertions(+), 2 deletions(-)
Index: theo/mln/morpho/reconstruction/by_dilation.hh
--- theo/mln/morpho/reconstruction/by_dilation.hh (revision 4679)
+++ theo/mln/morpho/reconstruction/by_dilation.hh (working copy)
@@ -656,7 +656,6 @@
}
}
-
// Sequence---Forth.
{
data::fill(deja_vu, false);
@@ -687,7 +686,6 @@
}
}
-
// Propagation.
{
P p;
Index: theo/mln/morpho/canvas/reconstruction_on_set_tiny.cc
--- theo/mln/morpho/canvas/reconstruction_on_set_tiny.cc (revision 0)
+++ theo/mln/morpho/canvas/reconstruction_on_set_tiny.cc (revision 0)
@@ -0,0 +1,190 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/debug/println.hh>
+
+#include "reconstruction_on_set.hh"
+
+
+
+template <typename F, typename G>
+struct rd_functor
+{
+ const F& f;
+ const G& g;
+
+ rd_functor(const F& f, const G& g)
+ : f(f), g(g)
+ {
+ }
+
+ mln_concrete(F) output;
+ typedef mln_psite(F) P;
+
+ void set_default()
+ {
+ mln::data::fill(output, false);
+ }
+
+ bool domain(const P& p) const
+ {
+ return g(p) == true;
+ }
+
+ void init(const P& p)
+ {
+ output(p) = f(p);
+ }
+
+ void merge(const P& p, const P& r)
+ {
+ output(p) = output(p) || output(r);
+ }
+
+ void border(const P&, const P&)
+ {
+ }
+
+ // Fastest versions.
+ void set_extension_()
+ {
+ mln::border::fill(g, false);
+ }
+ bool domain_(unsigned p) const
+ {
+ return g.element(p) == true;
+ }
+ void init_(unsigned p)
+ {
+ output.element(p) = f.element(p);
+ }
+ void merge_(unsigned p, unsigned r)
+ {
+ output.element(p) = output.element(p) || output.element(r);
+ }
+ bool inspect_border_() const
+ {
+ return false;
+ }
+ void border_(unsigned, unsigned)
+ {
+ }
+};
+
+
+
+
+
+template <typename F, typename G>
+struct rd_alt_functor // /!\ alternative version
+{
+ const F& f;
+ const G& g;
+
+ rd_alt_functor(const F& f, const G& g)
+ : f(f), g(g)
+ {
+ }
+
+ mln_concrete(F) output;
+ typedef mln_psite(F) P;
+
+ void set_default()
+ {
+ mln::data::fill(output, f);
+ }
+
+ bool domain(const P& p) const
+ {
+ return g(p) && ! f(p);
+ }
+
+ void init(const P& p)
+ {
+ output(p) = false;
+ }
+
+ void merge(const P& p, const P& r)
+ {
+ output(p) = output(p) || output(r);
+ }
+
+ void border(const P& p, const P& n)
+ {
+ if (f(n))
+ output(p) = true;
+ }
+
+ // Fastest versions.
+ void set_extension_()
+ {
+ mln::border::fill(f, false);
+ mln::border::fill(g, false);
+ }
+ bool domain_(unsigned p) const
+ {
+ return g.element(p) && ! f.element(p);
+ }
+ void init_(unsigned p)
+ {
+ output.element(p) = false;
+ }
+ void merge_(unsigned p, unsigned r)
+ {
+ output.element(p) = output.element(p) || output.element(r);
+ }
+ bool inspect_border_() const
+ {
+ return true;
+ }
+ void border_(unsigned p, unsigned n)
+ {
+ if (f.element(n))
+ {
+ mln_invariant(f.domain().has(f.point_at_index(n)));
+ output.element(p) = true;
+ }
+ }
+};
+
+
+
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d<bool> I;
+
+ I f, g, o;
+ neighb2d nbh = c4();
+
+ bool gvals[9][5] = { { 0, 1, 1, 1, 0 },
+ { 0, 0, 0, 1, 0 },
+ { 0, 1, 1, 1, 0 },
+ { 0, 1, 0, 0, 0 },
+ { 0, 1, 1, 1, 0 },
+ { 0, 0, 0, 1, 0 },
+ { 0, 1, 1, 1, 0 },
+ { 0, 1, 0, 0, 0 },
+ { 0, 1, 1, 1, 0 } };
+ g = make::image(gvals);
+ debug::println("g", g);
+
+ bool fvals[9][5] = { { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 1, 0, 0 },
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0 } };
+ f = make::image(fvals);
+ debug::println("f", f);
+
+ rd_alt_functor<I,I> fun(f, g);
+ o = morpho::canvas::reconstruction_on_set_union_find(f, g, nbh, fun);
+
+ debug::println("o", o);
+}
Index: theo/mln/morpho/canvas/reconstruction_on_set.hh
--- theo/mln/morpho/canvas/reconstruction_on_set.hh (revision 0)
+++ theo/mln/morpho/canvas/reconstruction_on_set.hh (revision 0)
@@ -0,0 +1,356 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_MORPHO_CANVAS_RECONSTRUCTION_ON_SET_UNION_FIND_HH
+# define MLN_MORPHO_CANVAS_RECONSTRUCTION_ON_SET_UNION_FIND_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/morpho/canvas/internal/find_root.hh>
+
+# include <mln/data/fill.hh>
+# include <mln/border/equalize.hh>
+# include <mln/border/fill.hh>
+
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace canvas
+ {
+
+
+ template <typename I, typename J, typename N,
+ typename F>
+ mln_concrete(I)
+ reconstruction_on_set_union_find(const Image<I>& f, const Image<J>& g, const Neighborhood<N>& nbh,
+ F& functor);
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Implementations.
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I, typename J, typename N,
+ typename F>
+ inline
+ mln_concrete(I)
+ reconstruction_on_set_union_find(const Image<I>& f_, const Image<J>& g_, const Neighborhood<N>& nbh_,
+ F& functor)
+ {
+ trace::entering("morpho::canvas::impl::generic::reconstruction_on_set_union_find");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ typedef mln_psite(I) P;
+ typedef mln_value(I) V;
+
+ // Auxiliary data.
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, P) parent;
+ mln_concrete(I) output;
+
+ // Initialization.
+ {
+ initialize(output, f);
+ functor.output = output;
+
+ initialize(parent, f);
+ initialize(deja_vu, f);
+ data::fill(deja_vu, false);
+
+ functor.set_default(); // <-- set_default
+ }
+
+ // First pass.
+ {
+ mln_fwd_piter(I) p(f.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ if (functor.domain(p)) // <-- domain
+ {
+ // Make-Set.
+ parent(p) = p;
+ functor.init(p); // <-- init
+
+ for_all(n) if (f.domain().has(n))
+ {
+ // See below (*)
+ if (functor.domain(n)) // <-- domain
+ {
+ if (deja_vu(n))
+ {
+ // Do-Union.
+ P r = internal::find_root(parent, n);
+ if (r != p)
+ {
+ parent(r) = p;
+ functor.merge(p, r); // <-- merge
+ }
+ }
+ }
+ else
+ {
+ mln_invariant(deja_vu(n) == false);
+ functor.border(p, n); // <-- border
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+
+ // Second pass.
+ {
+ mln_bkd_piter(I) p(f.domain());
+ for_all(p)
+ if (functor.domain(p)) // <-- domain
+ if (parent(p) != p)
+ output(p) = output(parent(p));
+ }
+
+ // (*) Technical note.
+ // n in D'
+ // | true | false |
+ // deja_vu(n) +----------+--------------+
+ // true | do-union | impossible |
+ // false | no-op | border(p, n) |
+ //
+ // The no-op is sound because /n/ will be processed as a "p in D'" later on.
+
+ trace::exiting("morpho::canvas::impl::generic::reconstruction_on_set_union_find");
+ return output;
+ }
+
+ } // end of namespace morpho::canvas::impl::generic
+
+
+
+ template <typename I, typename J, typename N,
+ typename F>
+ inline
+ mln_concrete(I)
+ reconstruction_on_set_union_find_fastest(const Image<I>& f_, const Image<J>& g_, const Neighborhood<N>& nbh_,
+ F& functor)
+ {
+ trace::entering("morpho::canvas::impl::reconstruction_on_set_union_find_fastest");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ typedef mln_psite(I) P;
+ typedef mln_value(I) V;
+
+ // Auxiliary data.
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, unsigned) parent;
+ mln_concrete(I) output;
+
+ // Initialization.
+ {
+ border::equalize(f, g, nbh.delta());
+ functor.set_extension_(); // <-- set_extension
+
+ initialize(output, f);
+ functor.output = output;
+
+ initialize(parent, f);
+
+ functor.set_default(); // <-- set_default
+ }
+
+ util::array<int> dp = negative_offsets_wrt(f, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ // First pass.
+ {
+ mln_fwd_pixter(const I) pxl(f);
+ for_all(pxl)
+ {
+ unsigned p = pxl.offset();
+ if (functor.domain_(p)) // <-- domain
+ {
+ // Make-Set.
+ parent.element(p) = p;
+ functor.init_(p); // <-- init
+
+ // Deja-vu part.
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (functor.domain_(n)) // <-- domain
+ {
+ mln_invariant(f.domain().has(f.point_at_index(n)));
+ // Do-Union.
+ unsigned r = internal::find_root_fastest(parent, n);
+ if (r != p)
+ {
+ // set_parent, i.e., union
+ parent.element(r) = p;
+ functor.merge_(p, r); // <-- merge
+ }
+ }
+ else
+ functor.border_(p, n); // <-- border
+ }
+
+ // Non-(deja-vu) part.
+ if (functor.inspect_border_())
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p - dp[j];
+ if (! functor.domain_(n)) // <-- domain
+ functor.border_(p, n); // <-- border
+ }
+
+ // (*) Technical note.
+ // n in D'
+ // | true | false |
+ // deja_vu(n) +----------+--------------+
+ // true | do-union | border(p, n) |
+ // false | no-op | border(p, n) |
+ //
+ // In this 'fastest' version, deja-vu(n) does not
+ // mean that n is in D' so we have to handle the
+ // case "deja_vu(n) and n not in D'".
+ }
+ }
+ }
+
+ // Second pass.
+ {
+ mln_bkd_pixter(const I) pxl(f);
+ for_all(pxl)
+ {
+ unsigned p = pxl.offset();
+ if (functor.domain_(p)) // <-- domain
+ if (parent.element(p) != p)
+ output.element(p) = output.element(parent.element(p));
+ }
+ }
+
+ trace::exiting("morpho::canvas::impl::reconstruction_on_set_union_find_fastest");
+ return output;
+ }
+
+
+ } // end of namespace mln::morpho::canvas::impl
+
+
+
+ // Dispatch.
+
+ namespace internal
+ {
+
+ template <typename I, typename J, typename N,
+ typename F>
+ inline
+ mln_concrete(I)
+ reconstruction_on_set_union_find_dispatch(metal::false_,
+ const Image<I>& f, const Image<J>& g, const Neighborhood<N>& nbh,
+ F& functor)
+ {
+ return impl::generic::reconstruction_on_set_union_find(f, g, nbh,
+ functor);
+ }
+
+ template <typename I, typename J, typename N,
+ typename F>
+ inline
+ mln_concrete(I)
+ reconstruction_on_set_union_find_dispatch(metal::true_,
+ const Image<I>& f, const Image<J>& g, const Neighborhood<N>& nbh,
+ F& functor)
+ {
+ return impl::reconstruction_on_set_union_find_fastest(f, g, nbh,
+ functor);
+ }
+
+ template <typename I, typename J, typename N,
+ typename F>
+ inline
+ mln_concrete(I)
+ reconstruction_on_set_union_find_dispatch(const Image<I>& f, const Image<J>& g, const Neighborhood<N>& nbh,
+ F& functor)
+ {
+ enum {
+ is_fastest = (mlc_equal(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value &&
+ mlc_equal(mln_trait_image_speed(J),
+ trait::image::speed::fastest)::value &&
+ mln_is_simple_neighborhood(N)::value)
+ };
+ return reconstruction_on_set_union_find_dispatch(metal::bool_<is_fastest>(),
+ f, g, nbh,
+ functor);
+ }
+
+ } // end of namespace mln::morpho::canvas::internal
+
+
+ // Facade.
+
+ template <typename I, typename J, typename N,
+ typename F>
+ inline
+ mln_concrete(I)
+ reconstruction_on_set_union_find(const Image<I>& f, const Image<J>& g, const Neighborhood<N>& nbh,
+ F& functor)
+ {
+ trace::entering("morpho::canvas::reconstruction_on_set_union_find");
+
+ mln_concrete(I) output;
+ output = internal::reconstruction_on_set_union_find_dispatch(f, g, nbh, functor);
+
+ trace::exiting("morpho::canvas::reconstruction_on_set_union_find");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::canvas
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_CANVAS_RECONSTRUCTION_ON_SET_UNION_FIND_HH
Index: theo/mln/morpho/canvas/internal/find_root.hh
--- theo/mln/morpho/canvas/internal/find_root.hh (revision 0)
+++ theo/mln/morpho/canvas/internal/find_root.hh (revision 0)
@@ -0,0 +1,89 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_MORPHO_CANVAS_INTERNAL_FIND_ROOT_HH
+# define MLN_MORPHO_CANVAS_INTERNAL_FIND_ROOT_HH
+
+# include <mln/core/concept/image.hh>
+
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace canvas
+ {
+
+ namespace internal
+ {
+
+ template <typename Par>
+ mln_psite(Par)
+ find_root(Par& parent, mln_psite(Par) x);
+
+ template <typename Par>
+ unsigned
+ find_root_fastest(Par& parent, unsigned x);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename Par>
+ inline
+ mln_psite(Par)
+ find_root(Par& parent, mln_psite(Par) x)
+ {
+ if (parent(x) == x)
+ return x;
+ else
+ return parent(x) = find_root(parent, parent(x));
+ }
+
+ template <typename Par>
+ inline
+ unsigned
+ find_root_fastest(Par& parent, unsigned x)
+ {
+ if (parent.element(x) == x)
+ return x;
+ else
+ return parent.element(x) = find_root_fastest(parent, parent.element(x));
+ }
+
+ } // end of namespace mln::morpho::canvas::internal
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::canvas
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_CANVAS_INTERNAL_FIND_ROOT_HH
Index: theo/mln/morpho/canvas/reconstruction_on_set.cc
--- theo/mln/morpho/canvas/reconstruction_on_set.cc (revision 0)
+++ theo/mln/morpho/canvas/reconstruction_on_set.cc (revision 0)
@@ -0,0 +1,376 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/debug/println.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/data/compare.hh>
+#include <mln/util/timer.hh>
+
+#include "reconstruction_on_set.hh"
+
+
+// by_dilation
+
+template <typename F, typename G>
+struct rd_functor
+{
+ const F& f;
+ const G& g;
+
+ rd_functor(const F& f, const G& g)
+ : f(f), g(g)
+ {
+ }
+
+ mln_concrete(F) output;
+ typedef mln_psite(F) P;
+
+ void set_default()
+ {
+ mln::data::fill(output, false);
+ }
+
+ bool domain(const P& p) const
+ {
+ return g(p) == true;
+ }
+
+ void init(const P& p)
+ {
+ output(p) = f(p);
+ }
+
+ void merge(const P& p, const P& r)
+ {
+ output(p) = output(p) || output(r);
+ }
+
+ void border(const P&, const P&)
+ {
+ }
+
+ // Fastest versions.
+ void set_extension_()
+ {
+ mln::border::fill(g, false);
+ }
+ bool domain_(unsigned p) const
+ {
+ return g.element(p) == true;
+ }
+ void init_(unsigned p)
+ {
+ output.element(p) = f.element(p);
+ }
+ void merge_(unsigned p, unsigned r)
+ {
+ output.element(p) = output.element(p) || output.element(r);
+ }
+ bool inspect_border_() const
+ {
+ return false;
+ }
+ void border_(unsigned, unsigned)
+ {
+ }
+};
+
+
+
+
+
+template <typename F, typename G>
+struct rd_alt_functor // /!\ alternative version
+{
+ const F& f;
+ const G& g;
+
+ rd_alt_functor(const F& f, const G& g)
+ : f(f), g(g)
+ {
+ }
+
+ mln_concrete(F) output;
+ typedef mln_psite(F) P;
+
+ void set_default()
+ {
+ mln::data::fill(output, f);
+ }
+
+ bool domain(const P& p) const
+ {
+ return g(p) && ! f(p);
+ }
+
+ void init(const P& p)
+ {
+ output(p) = false;
+ }
+
+ void merge(const P& p, const P& r)
+ {
+ output(p) = output(p) || output(r);
+ }
+
+ void border(const P& p, const P& n)
+ {
+ if (f(n))
+ output(p) = true;
+ }
+
+ // Fastest versions.
+ void set_extension_()
+ {
+ mln::border::fill(f, false);
+ mln::border::fill(g, false);
+ }
+ bool domain_(unsigned p) const
+ {
+ return g.element(p) && ! f.element(p);
+ }
+ void init_(unsigned p)
+ {
+ output.element(p) = false;
+ }
+ void merge_(unsigned p, unsigned r)
+ {
+ output.element(p) = output.element(p) || output.element(r);
+ }
+ bool inspect_border_() const
+ {
+ return true;
+ }
+ void border_(unsigned p, unsigned n)
+ {
+ if (f.element(n))
+ {
+ mln_invariant(f.domain().has(f.point_at_index(n)));
+ output.element(p) = true;
+ }
+ }
+};
+
+
+
+// by_erosion
+
+template <typename F, typename G>
+struct re_functor
+{
+ const F& f;
+ const G& g;
+
+ re_functor(const F& f, const G& g)
+ : f(f), g(g)
+ {
+ }
+
+ mln_concrete(F) output;
+ typedef mln_psite(F) P;
+
+ void set_default()
+ {
+ mln::data::fill(output, true);
+ }
+
+ bool domain(const P& p) const
+ {
+ return g(p) == false;
+ }
+
+ void init(const P& p)
+ {
+ output(p) = f(p);
+ }
+
+ void merge(const P& p, const P& r)
+ {
+ output(p) = output(p) && output(r);
+ }
+
+ void border(const P&, const P&)
+ {
+ }
+
+ // Fastest versions.
+ void set_extension_()
+ {
+ mln::border::fill(g, true);
+ }
+ bool domain_(unsigned p) const
+ {
+ return g.element(p) == false;
+ }
+ void init_(unsigned p)
+ {
+ output.element(p) = f.element(p);
+ }
+ void merge_(unsigned p, unsigned r)
+ {
+ output.element(p) = output.element(p) && output.element(r);
+ }
+ bool inspect_border_() const
+ {
+ return false;
+ }
+ void border_(unsigned, unsigned)
+ {
+ }
+};
+
+
+
+
+template <typename F, typename G>
+struct re_alt_functor
+{
+ const F& f;
+ const G& g;
+
+ re_alt_functor(const F& f, const G& g)
+ : f(f), g(g)
+ {
+ }
+
+ mln_concrete(F) output;
+ typedef mln_psite(F) P;
+
+ void set_default()
+ {
+ mln::data::fill(output, g);
+ }
+
+ bool domain(const P& p) const
+ {
+ return f(p) && ! g(p);
+ }
+
+ void init(const P& p)
+ {
+ output(p) = true;
+ }
+
+ void merge(const P& p, const P& r)
+ {
+ output(p) = output(p) && output(r);
+ }
+
+ void border(const P& p, const P& n)
+ {
+ if (! f(n))
+ output(p) = false;
+ }
+
+ // Fastest versions.
+ void set_extension_()
+ {
+ mln::border::fill(f, true);
+ mln::border::fill(g, true);
+ }
+ bool domain_(unsigned p) const
+ {
+ return f.element(p) && ! g.element(p);
+ }
+ void init_(unsigned p)
+ {
+ output.element(p) = true;
+ }
+ void merge_(unsigned p, unsigned r)
+ {
+ output.element(p) = output.element(p) && output.element(r);
+ }
+ bool inspect_border_() const
+ {
+ return true;
+ }
+ void border_(unsigned p, unsigned n)
+ {
+ if (! f.element(n))
+ output.element(p) = false;
+ }
+};
+
+
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d<bool> I;
+
+ I f, g, ref, o;
+ neighb2d nbh = c4();
+
+ io::pbm::load(f, "f_and_g.pbm");
+ io::pbm::load(g, "g.pbm");
+
+ util::timer t;
+
+
+ // by dilation
+ {
+ rd_functor<I,I> fun(f, g);
+ {
+ t.start();
+ ref = morpho::canvas::impl::generic::reconstruction_on_set_union_find(f, g, nbh, fun);
+ std::cout << t.stop() << std::endl;
+ }
+ {
+ t.start();
+ o = morpho::canvas::impl::reconstruction_on_set_union_find_fastest(f, g, nbh, fun);
+ std::cout << t.stop() << std::endl;
+ std::cout << (o == ref ? "OK" : "KO") << std::endl;
+ }
+
+ rd_alt_functor<I,I> fun_alt(f, g);
+ {
+ t.start();
+ o = morpho::canvas::impl::generic::reconstruction_on_set_union_find(f, g, nbh, fun_alt);
+ std::cout << t.stop() << std::endl;
+ std::cout << (o == ref ? "OK" : "KO") << std::endl;
+ }
+ {
+ t.start();
+ o = morpho::canvas::impl::reconstruction_on_set_union_find_fastest(f, g, nbh, fun_alt);
+ std::cout << t.stop() << std::endl;
+ std::cout << (o == ref ? "OK" : "KO") << std::endl;
+ }
+
+ io::pbm::save(ref, "rd.pbm");
+ }
+
+ // by erosion
+ {
+ re_functor<I,I> fun(g, f);
+ {
+ t.start();
+ ref = morpho::canvas::impl::generic::reconstruction_on_set_union_find(g, f, nbh, fun);
+ std::cout << t.stop() << std::endl;
+ }
+ {
+ t.start();
+ o = morpho::canvas::impl::reconstruction_on_set_union_find_fastest(g, f, nbh, fun);
+ std::cout << t.stop() << std::endl;
+ std::cout << (o == ref ? "OK" : "KO") << std::endl;
+ }
+
+ re_alt_functor<I,I> fun_alt(g, f);
+ {
+ t.start();
+ o = morpho::canvas::impl::generic::reconstruction_on_set_union_find(g, f, nbh, fun_alt);
+ std::cout << t.stop() << std::endl;
+ std::cout << (o == ref ? "OK" : "KO") << std::endl;
+ }
+ {
+ t.start();
+ o = morpho::canvas::impl::reconstruction_on_set_union_find_fastest(g, f, nbh, fun_alt);
+ std::cout << t.stop() << std::endl;
+ std::cout << (o == ref ? "OK" : "KO") << std::endl;
+ }
+
+ io::pbm::save(ref, "re.pbm");
+ }
+
+}
1
0
* Makefile.am,
* demo.pro,
* src/bak/mainwindow.cc,
* src/bak/mainwindow.hh,
* src/display_seg.cc,
* src/display_seg.hh,
* src/edit_seg.cc,
* src/edit_seg.hh,
* src/image_viewer.cc,
* src/image_viewer.hh,
* src/internal/interactive_scene.cc,
* src/internal/interactive_scene.hh,
* src/main.cc,
* src/main_window.cc,
* src/main_window.hh,
* src/to_qimage.hh,
* src/widgets.cc,
* ui/bak/mainwindow.ui,
* ui/display_seg.ui,
* ui/edit_seg.ui,
* ui/image_viewer.ui,
* ui/main_window.ui,
* ui_display_seg.h,
* ui_edit_seg.h,
* ui_image_viewer.h,
* ui_main_window.h: New files.
---
milena/sandbox/ChangeLog | 31 ++
milena/sandbox/lazzara/igr/gui/Makefile.am | 11 +
milena/sandbox/lazzara/igr/gui/demo.pro | 16 +
.../sandbox/lazzara/igr/gui/src/bak/mainwindow.cc | 441 ++++++++++++++++++++
.../sandbox/lazzara/igr/gui/src/bak/mainwindow.hh | 146 +++++++
milena/sandbox/lazzara/igr/gui/src/display_seg.cc | 172 ++++++++
milena/sandbox/lazzara/igr/gui/src/display_seg.hh | 96 +++++
milena/sandbox/lazzara/igr/gui/src/edit_seg.cc | 204 +++++++++
milena/sandbox/lazzara/igr/gui/src/edit_seg.hh | 82 ++++
milena/sandbox/lazzara/igr/gui/src/image_viewer.cc | 194 +++++++++
milena/sandbox/lazzara/igr/gui/src/image_viewer.hh | 102 +++++
.../igr/gui/src/internal/interactive_scene.cc | 88 ++++
.../igr/gui/src/internal/interactive_scene.hh | 73 ++++
milena/sandbox/lazzara/igr/gui/src/main.cc | 39 ++
milena/sandbox/lazzara/igr/gui/src/main_window.cc | 56 +++
milena/sandbox/lazzara/igr/gui/src/main_window.hh | 60 +++
milena/sandbox/lazzara/igr/gui/src/to_qimage.hh | 63 +++
milena/sandbox/lazzara/igr/gui/src/widgets.cc | 3 +
.../sandbox/lazzara/igr/gui/ui/bak/mainwindow.ui | 277 ++++++++++++
milena/sandbox/lazzara/igr/gui/ui/display_seg.ui | 108 +++++
milena/sandbox/lazzara/igr/gui/ui/edit_seg.ui | 97 +++++
milena/sandbox/lazzara/igr/gui/ui/image_viewer.ui | 154 +++++++
milena/sandbox/lazzara/igr/gui/ui/main_window.ui | 64 +++
milena/sandbox/lazzara/igr/gui/ui_display_seg.h | 148 +++++++
milena/sandbox/lazzara/igr/gui/ui_edit_seg.h | 130 ++++++
milena/sandbox/lazzara/igr/gui/ui_image_viewer.h | 167 ++++++++
milena/sandbox/lazzara/igr/gui/ui_main_window.h | 92 ++++
27 files changed, 3114 insertions(+), 0 deletions(-)
create mode 100644 milena/sandbox/lazzara/igr/gui/Makefile.am
create mode 100644 milena/sandbox/lazzara/igr/gui/demo.pro
create mode 100644 milena/sandbox/lazzara/igr/gui/src/bak/mainwindow.cc
create mode 100644 milena/sandbox/lazzara/igr/gui/src/bak/mainwindow.hh
create mode 100644 milena/sandbox/lazzara/igr/gui/src/display_seg.cc
create mode 100644 milena/sandbox/lazzara/igr/gui/src/display_seg.hh
create mode 100644 milena/sandbox/lazzara/igr/gui/src/edit_seg.cc
create mode 100644 milena/sandbox/lazzara/igr/gui/src/edit_seg.hh
create mode 100644 milena/sandbox/lazzara/igr/gui/src/image_viewer.cc
create mode 100644 milena/sandbox/lazzara/igr/gui/src/image_viewer.hh
create mode 100644 milena/sandbox/lazzara/igr/gui/src/internal/interactive_scene.cc
create mode 100644 milena/sandbox/lazzara/igr/gui/src/internal/interactive_scene.hh
create mode 100644 milena/sandbox/lazzara/igr/gui/src/main.cc
create mode 100644 milena/sandbox/lazzara/igr/gui/src/main_window.cc
create mode 100644 milena/sandbox/lazzara/igr/gui/src/main_window.hh
create mode 100644 milena/sandbox/lazzara/igr/gui/src/to_qimage.hh
create mode 100644 milena/sandbox/lazzara/igr/gui/src/widgets.cc
create mode 100644 milena/sandbox/lazzara/igr/gui/ui/bak/mainwindow.ui
create mode 100644 milena/sandbox/lazzara/igr/gui/ui/display_seg.ui
create mode 100644 milena/sandbox/lazzara/igr/gui/ui/edit_seg.ui
create mode 100644 milena/sandbox/lazzara/igr/gui/ui/image_viewer.ui
create mode 100644 milena/sandbox/lazzara/igr/gui/ui/main_window.ui
create mode 100644 milena/sandbox/lazzara/igr/gui/ui_display_seg.h
create mode 100644 milena/sandbox/lazzara/igr/gui/ui_edit_seg.h
create mode 100644 milena/sandbox/lazzara/igr/gui/ui_image_viewer.h
create mode 100644 milena/sandbox/lazzara/igr/gui/ui_main_window.h
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 9580b1b..53f1bda 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,34 @@
+2009-10-28 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add a GUI for IGR.
+
+ * Makefile.am,
+ * demo.pro,
+ * src/bak/mainwindow.cc,
+ * src/bak/mainwindow.hh,
+ * src/display_seg.cc,
+ * src/display_seg.hh,
+ * src/edit_seg.cc,
+ * src/edit_seg.hh,
+ * src/image_viewer.cc,
+ * src/image_viewer.hh,
+ * src/internal/interactive_scene.cc,
+ * src/internal/interactive_scene.hh,
+ * src/main.cc,
+ * src/main_window.cc,
+ * src/main_window.hh,
+ * src/to_qimage.hh,
+ * src/widgets.cc,
+ * ui/bak/mainwindow.ui,
+ * ui/display_seg.ui,
+ * ui/edit_seg.ui,
+ * ui/image_viewer.ui,
+ * ui/main_window.ui,
+ * ui_display_seg.h,
+ * ui_edit_seg.h,
+ * ui_image_viewer.h,
+ * ui_main_window.h: New files.
+
2009-10-14 Guillaume Lazzara <z(a)lrde.epita.fr>
* lazzara/fonctionnalites_milena.ods: Add a document listing
diff --git a/milena/sandbox/lazzara/igr/gui/Makefile.am b/milena/sandbox/lazzara/igr/gui/Makefile.am
new file mode 100644
index 0000000..b51084e
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/Makefile.am
@@ -0,0 +1,11 @@
+## Process this file through Automake to create Makefile.in.
+
+include $(top_srcdir)/scribo/scribo.mk
+
+.PHONY : demo
+
+Makefile.demo:
+ qmake-qt4 $(srcdir)/demo/demo.pro -o Makefile.demo
+
+demo: Makefile.demo
+ make -f Makefile.demo all
diff --git a/milena/sandbox/lazzara/igr/gui/demo.pro b/milena/sandbox/lazzara/igr/gui/demo.pro
new file mode 100644
index 0000000..5d1b3b0
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/demo.pro
@@ -0,0 +1,16 @@
+######################################################################
+# Automatically generated by qmake (2.01a) Mon Jun 1 10:28:31 2009
+######################################################################
+
+TEMPLATE = app
+TARGET =
+DEPENDPATH += . src ui
+INCLUDEPATH += . src $(OLN)/milena /lrde/dev/linux-x86/stable/gdcm/include
+DEFINES += NDEBUG
+LIBS += -L/lrde/dev/linux-x86/stable/gdcm/lib -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib
+#CONFIG += debug
+
+# Input
+HEADERS += src/main_window.hh src/image_viewer.hh src/display_seg.hh src/edit_seg.hh src/internal/interactive_scene.hh
+FORMS += ui/main_window.ui ui/image_viewer.ui ui/display_seg.ui ui/edit_seg.ui
+SOURCES += src/main.cc src/main_window.cc src/image_viewer.cc src/widgets.cc src/internal/interactive_scene.cc
diff --git a/milena/sandbox/lazzara/igr/gui/src/bak/mainwindow.cc b/milena/sandbox/lazzara/igr/gui/src/bak/mainwindow.cc
new file mode 100644
index 0000000..673a01a
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/bak/mainwindow.cc
@@ -0,0 +1,441 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <QApplication>
+#include <QtCore>
+#include <QtGui>
+
+# define INCLUDE_MLN_FILES
+#include <src/mainwindow.hh>
+
+#include <src/image_viewer.hh>
+
+#include <mln/core/image/dmorph/slice_image.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/border/resize.hh>
+#include <mln/logical/not.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/value/int_u12.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/data/convert.hh>
+#include <mln/data/stretch.hh>
+#include <mln/io/dicom/all.hh>
+#include <mln/io/dump/all.hh>
+
+
+#include <mln/io/ppm/save.hh>
+
+
+const char * modes[][4] = {
+// { "Text in pictures", "pics", "../src/text_in_photo_ppm", "image-x-generic.png" },
+ { "Segmentation 3d", "seg", "../watershed3d", 0 },
+ { 0, 0, 0 } // Empty line, do NOT delete.
+};
+
+
+// Allow to set up to 3 extra arguments to the binaries.
+//
+// A program will be launched as follow:
+//
+// ./my_program input.pbm <arg1> <arg2> <arg3> output.ppm
+//
+// Unused arguments are set to 0.
+// Each line must be mapped to the related on in the previous
+// array "modes". So DO preserve the order.
+//
+const char *args_list[][3] = {
+ { "51", 0, 0 }
+ // Not empty line needed.
+};
+
+
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ {
+ setupUi(this);
+
+ viewer_ = new image_viewer();
+ gridLayout_2->addWidget(viewer_, 0, 0);
+
+ unsigned nmodes = 0;
+ for (unsigned i = 0; modes[i][0] != 0; ++i)
+ ++nmodes;
+
+ cached_result_.resize(nmodes);
+ exec_prefix_ = "";
+ base_img_dir_ = "/lrde/stockholm/lazzara/svn/olena/git/oln/milena/sandbox/lazzara/igr/gui";
+// QCoreApplication::applicationDirPath();
+
+ pdialog_.setRange(0,0);
+ pdialog_.setLabelText(tr("Please wait while computing..."));
+ pdialog_.setWindowModality(Qt::WindowModal);
+
+ exec_.setReadChannel(QProcess::StandardOutput);
+
+ qDebug() << "Cache located in " << QDir::tempPath();
+
+ connect(&pdialog_, SIGNAL(canceled()), this, SLOT(compute_canceled()));
+
+ connect(viewer_, SIGNAL(slider_valueChanged(int)),
+ this, SLOT(compute_image(int)));
+
+ connect_compute_process();
+
+ // No status bar.
+ setStatusBar(0);
+
+ initToolBar();
+ }
+
+ MainWindow::~MainWindow()
+ {
+ for (int i = 0; i < cached_result_.size(); ++i)
+ foreach(QString value, cached_result_[i])
+ {
+ QFile f(value);
+ f.remove();
+ }
+ }
+
+
+ void MainWindow::set_base_img_dir(const QString& dir)
+ {
+ QDir d(dir);
+ base_img_dir_ = d.absolutePath();
+ }
+
+
+ void MainWindow::initToolBar()
+ {
+ QToolBar *tbar = new QToolBar("Tools");
+ tbar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+
+ for (unsigned i = 0; modes[i][0]; ++i)
+ {
+ QListWidgetItem *item = new QListWidgetItem(modes[i][0], listWidget);
+ item->setData(Qt::UserRole, i);
+ }
+
+ listWidget->setCurrentItem(listWidget->item(0));
+ }
+
+
+
+ void MainWindow::on_browseBtn_clicked(bool)
+ {
+ QString
+ current_dir = mode_ + QString("/");
+
+ qDebug() << (base_img_dir_ + "/" + current_dir);
+ QString
+ filename = QFileDialog::getOpenFileName(this,
+ tr("Open Image."),
+ base_img_dir_ + "/" + current_dir,
+ tr("Images (*.dcm)"));
+
+ prepare_for_run(filename);
+ }
+
+ void MainWindow::prepare_for_run(const QString& filename)
+ {
+ if (!filename.isEmpty())
+ {
+ filepath->setText(filename);
+
+ load_dicom(filename);
+
+ }
+ }
+
+ void MainWindow::load_dicom(const QString& filename)
+ {
+ image3d<value::int_u12> tmp;
+ io::dicom::load(tmp, filename.toStdString().c_str());
+ dcm_ima = to_rgb8(tmp);
+
+ viewer_->set_image_size(geom::nrows(dcm_ima), geom::ncols(dcm_ima),
+ geom::nslis(dcm_ima));
+ }
+
+
+ void MainWindow::compute_image(int sli)
+ {
+ QImage ima = this->convert(duplicate(slice(dcm_ima, sli)));
+ viewer_->updated_image(ima);
+ }
+
+
+ template <typename I>
+ mln_ch_value(I, value::rgb8) MainWindow::to_rgb8(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ mln_ch_value(I, value::rgb8)
+ tmp = data::convert(value::rgb8(),
+ data::stretch(value::int_u8(), ima));
+
+ return tmp;
+ }
+
+
+ template <typename I>
+ QImage MainWindow::convert(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ const int
+ nrows = geom::nrows(ima),
+ ncols = geom::ncols(ima);
+
+ // Required by a one-shot data copy:
+ mln::border::resize(ima, 0);
+
+ QImage qima(ncols, nrows, QImage::Format_RGB888);
+ std::memcpy(qima.scanLine(0),
+ ima.buffer(),
+ ima.nelements() * 3);
+ return qima;
+ }
+
+
+ void MainWindow::on_runBtn_clicked()
+ {
+// if (useCache->isChecked()
+// && cached_result_[mode_].contains(filepath->text()))
+// {
+// last_output_ = cached_result_[mode_][filepath->text()];
+// exec_finished(0, QProcess::NormalExit);
+// return;
+// }
+
+ wait_for_result();
+
+ QStringList args;
+
+ QString input = filepath->text();
+
+ args << input;
+ for (int i = 0; i < args_values_.size(); ++i)
+ args << QString::number(args_values_[i]->value());
+
+ QTemporaryFile f;
+ f.open();
+ args << f.fileName();
+ last_output_ = f.fileName();
+ qDebug() << last_output_;
+
+
+ qDebug() << exec_prefix_ + modes[mode_][2]
+ << " - "
+ << args;
+ exec_.start(exec_prefix_ + modes[mode_][2], args);
+ }
+
+
+ void MainWindow::on_listWidget_currentItemChanged(QListWidgetItem *current,
+ QListWidgetItem *previous)
+ {
+ (void) previous;
+ mode_ = current->data(Qt::UserRole).toInt();
+ update_options(current);
+ }
+
+
+ void MainWindow::update_options(QListWidgetItem */*current*/)
+ {
+ QFormLayout *formLayout = new QFormLayout;
+
+ QProcess process;
+ process.start(modes[mode_][2]);
+ process.waitForFinished();
+
+ QByteArray usage = process.readAllStandardOutput();
+ QList<QByteArray> list = usage.split('<');
+
+ delete frame->layout();
+ args_values_.clear();
+
+ for (int i = 2; i < list.size() - 1; ++i)
+ {
+ args_values_.append(new QSpinBox());
+ args_values_.last()->setValue(atoi(args_list[mode_][i - 2]));
+ formLayout->addRow(list[i].replace('>', ' '), args_values_.last());
+ }
+
+ frame->setLayout(formLayout);
+ }
+
+
+ void MainWindow::on_displayBtn_clicked(bool)
+ {
+ load_dicom(filepath->text());
+ }
+
+
+ void MainWindow::on_filepath_textChanged()
+ {
+ bool b = !filepath->text().isEmpty();
+
+ runBtn->setEnabled(b);
+ displayBtn->setEnabled(b);
+ }
+
+
+ void MainWindow::exec_finished(int rvalue, QProcess::ExitStatus status)
+ {
+ pdialog_.hide();
+ if (rvalue == 0)
+ {
+ if (status != QProcess::CrashExit)
+ {
+ if (useCache->isChecked())
+ cached_result_[mode_][filepath->text()] = last_output_;
+ setEnabled(true);
+ prepare_and_send_result(last_output_);
+ }
+ // Else : canceled.
+ }
+ else
+ exec_error(tr("Error during last run."));
+
+ if (autoDemo->isChecked())
+ timer_.start(timeoutDelay->text().toInt() * 1000);
+ }
+
+
+ void MainWindow::prepare_and_send_result(const QString& output)
+ {
+ QImage ima(output);
+ viewer_->updated_image(ima);
+ }
+
+ void MainWindow::wait_for_result()
+ {
+ reset_progress_dialog();
+
+ pdialog_.show();
+ setEnabled(false);
+ }
+
+ void MainWindow::exec_error(const QString& msg)
+ {
+ setEnabled(true);
+ QMessageBox::critical(0, tr("Error!"),
+ tr("The result cannot be computed!"));
+ qDebug() << "exec_error : " << msg;
+ qDebug() << exec_.readAllStandardOutput();
+ }
+
+ void MainWindow::exec_error(QProcess::ProcessError error)
+ {
+ if (error == QProcess::FailedToStart)
+ exec_error(tr("This program does not exist: ")
+ + exec_prefix_ + modes[mode_][2]);
+ else
+ exec_error(tr("The computation stopped.")
+ + exec_prefix_ + modes[mode_][2]);
+ }
+
+
+
+ void MainWindow::compute_canceled()
+ {
+ setEnabled(true);
+
+ exec_.disconnect();
+ exec_.kill();
+ connect_compute_process();
+
+ }
+
+
+ void MainWindow::on_autoDemo_clicked(bool checked)
+ {
+ if (checked)
+ timer_.start(100);
+ else
+ timer_.stop();
+ }
+
+
+ void MainWindow::timer_timeout()
+ {
+ update_auto_demo_dir();
+ timer_.stop();
+ prepare_for_run(demoDir_.absolutePath() + "/"
+ + demo_files_[demo_index_]);
+ demo_index_ = (demo_index_ + 1) % demo_files_.size();
+ }
+
+ void MainWindow::update_auto_demo_dir()
+ {
+// QString tmp_path = base_img_dir_ + "/" + current_mode();
+// if (demoDir_.path() != tmp_path)
+// {
+// demoDir_.setPath(tmp_path);
+// demo_index_ = 0;
+// demo_files_ = demoDir_.entryList(QDir::NoDotAndDotDot | QDir::Files);
+// }
+ }
+
+
+ void MainWindow::update_process_status()
+ {
+ pdialog_.setLabelText(tr(exec_.readAllStandardOutput()));
+ }
+
+
+ void MainWindow::reset_progress_dialog()
+ {
+ pdialog_.reset();
+ pdialog_.setLabelText(tr("Please wait while computing..."));
+ }
+
+
+ void MainWindow::connect_compute_process()
+ {
+ connect(&exec_, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(exec_finished(int, QProcess::ExitStatus)));
+ connect(&exec_, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT(exec_error(QProcess::ProcessError)));
+ connect(&exec_, SIGNAL(readyReadStandardOutput()),
+ this, SLOT(update_process_status()));
+ }
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
diff --git a/milena/sandbox/lazzara/igr/gui/src/bak/mainwindow.hh b/milena/sandbox/lazzara/igr/gui/src/bak/mainwindow.hh
new file mode 100644
index 0000000..17948e1
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/bak/mainwindow.hh
@@ -0,0 +1,146 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_DEMO_SRC_MAINWINDOW_HH
+
+# include <QDir>
+# include <QTimer>
+# include <QStringList>
+# include <QProcess>
+# include <QtGui>
+# include <QProgressDialog>
+# include <ui_mainwindow.h>
+
+# ifndef INCLUDE_MLN_FILES
+# define MLN_INCLUDE_ONLY
+# endif
+
+# include <mln/core/image/image3d.hh>
+# include <mln/value/rgb8.hh>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ // Forward declaration.
+ class image_viewer;
+
+
+ class MainWindow : public QMainWindow, private Ui::MainWindow
+ {
+ Q_OBJECT
+
+
+ public:
+ MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+ void set_base_img_dir(const QString& dir);
+
+ private slots:
+ void initToolBar();
+
+ void on_browseBtn_clicked(bool b);
+ void on_runBtn_clicked();
+ void on_displayBtn_clicked(bool b);
+ void on_filepath_textChanged();
+ void on_autoDemo_clicked(bool checked);
+
+ void exec_finished(int rvalue, QProcess::ExitStatus status);
+ void exec_error(QProcess::ProcessError error);
+
+ void compute_canceled();
+
+ void timer_timeout();
+
+ void update_process_status();
+
+ void on_listWidget_currentItemChanged(QListWidgetItem *current,
+ QListWidgetItem *previous);
+
+ void compute_image(int sli);
+
+ private: // Members
+
+ void update_pixmap(QGraphicsView* view, const QString& name = QString());
+
+ void load_dicom(const QString& filename);
+
+ template <typename I>
+ mln_ch_value(I, value::rgb8) to_rgb8(const Image<I>& ima_);
+
+ template <typename I>
+ QImage convert(const Image<I>& ima_);
+
+ void prepare_and_send_result(const QString& output);
+
+ void exec_error(const QString& msg);
+
+ void wait_for_result();
+
+ void prepare_for_run(const QString& filename);
+
+ void update_auto_demo_dir();
+
+ void reset_progress_dialog();
+
+ void connect_compute_process();
+
+ void update_options(QListWidgetItem *item);
+
+ private: // Attributes
+ image_viewer *viewer_;
+
+ QString exec_prefix_;
+
+ QString last_output_;
+ QProcess exec_;
+
+ QProgressDialog pdialog_;
+
+ QString base_img_dir_;
+
+ int mode_;
+ image3d<value::rgb8> dcm_ima;
+ QList<QSpinBox*> args_values_;
+
+
+ QVector<QHash<QString, QString> > cached_result_;
+
+ /// Related to auto demo.
+ QTimer timer_;
+ QDir demoDir_;
+ unsigned demo_index_;
+ QStringList demo_files_;
+ };
+
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+#endif // ! MLN_DEMO_SRC_MAINWINDOW_HH
diff --git a/milena/sandbox/lazzara/igr/gui/src/display_seg.cc b/milena/sandbox/lazzara/igr/gui/src/display_seg.cc
new file mode 100644
index 0000000..eae64a9
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/display_seg.cc
@@ -0,0 +1,172 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <QApplication>
+#include <QtCore>
+#include <QtGui>
+
+# define INCLUDE_MLN_FILES
+#include <src/display_seg.hh>
+#include <src/image_viewer.hh>
+
+#include <src/to_qimage.hh>
+
+#include <mln/accu/count_value.hh>
+#include <mln/core/image/dmorph/slice_image.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/border/resize.hh>
+#include <mln/data/compute.hh>
+#include <mln/logical/not.hh>
+#include <mln/value/hsl.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/value/int_u12.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u32.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/data/convert.hh>
+#include <mln/data/stretch.hh>
+#include <mln/io/dicom/all.hh>
+#include <mln/io/dump/all.hh>
+
+
+#include <mln/io/ppm/save.hh>
+
+
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ display_seg::display_seg(QWidget *parent)
+ : QWidget(parent)
+ {
+ setupUi(this);
+
+ connect(viewer, SIGNAL(slider_valueChanged(int)),
+ this, SLOT(compute_image(int)));
+ }
+
+ display_seg::~display_seg()
+ {
+ }
+
+
+ // Private slots
+
+ void display_seg::on_browseBtn_clicked(bool)
+ {
+ QString
+ filename = QFileDialog::getOpenFileName(this,
+ tr("Open Image."),
+ QString(),
+ tr("Images (*.dcm)"));
+
+ if (!filename.isEmpty())
+ filepath->setText(filename);
+ }
+
+
+ void display_seg::on_browseSegBtn_clicked(bool)
+ {
+ QString
+ filename = QFileDialog::getOpenFileName(this,
+ tr("Open Image."),
+ QString(),
+ tr("Images (*.dump)"));
+
+ if (!filename.isEmpty())
+ segfilepath->setText(filename);
+ }
+
+
+ void display_seg::compute_image(int sli)
+ {
+ slice_image<dcm_ima_t> sl_ima = slice(dcm_ima, sli);
+
+ mln_piter_(result_t) p(result.domain());
+ for_all(p)
+ result(p).lum() = (sl_ima(p) / static_cast<float>(mln_max(value::int_u8))) / 2.0;
+
+ QImage ima = to_qimage(data::convert(value::rgb8(), result));
+
+ viewer->update_image(ima);
+ }
+
+
+ void display_seg::on_loadBtn_clicked(bool)
+ {
+ load_dicom(filepath->text());
+ load_seg(segfilepath->text());
+ setup_result();
+
+ viewer->set_image_layer_count(geom::nslis(dcm_ima));
+ }
+
+
+
+ // Private members
+
+ void display_seg::setup_result()
+ {
+ initialize(result, seg_ima);
+ mln_piter_(result_t) p(result.domain());
+ for_all(p)
+ {
+ result(p).hue() = ((seg_ima(p) * 10) % 359) + 1;
+ result(p).sat() = 1;
+ }
+ }
+
+ void display_seg::load_seg(const QString& filename)
+ {
+ io::dump::load(seg_ima, filename.toStdString());
+ }
+
+
+ void display_seg::load_dicom(const QString& filename)
+ {
+ image3d<value::int_u12> tmp;
+ io::dicom::load(tmp, filename.toStdString());
+ dcm_ima = to_int_u8(tmp);
+ }
+
+
+ template <typename I>
+ mln_ch_value(I, value::int_u8) display_seg::to_int_u8(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ mln_ch_value(I, value::int_u8)
+ tmp = data::stretch(value::int_u8(), ima);
+
+ return tmp;
+ }
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/milena/sandbox/lazzara/igr/gui/src/display_seg.hh b/milena/sandbox/lazzara/igr/gui/src/display_seg.hh
new file mode 100644
index 0000000..c559b0d
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/display_seg.hh
@@ -0,0 +1,96 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_DEMO_SRC_DISPLAY_SEG_HH
+
+# include <QDir>
+# include <QTimer>
+# include <QStringList>
+# include <QProcess>
+# include <QtGui>
+# include <QProgressDialog>
+# include <ui_display_seg.h>
+
+# ifndef INCLUDE_MLN_FILES
+# define MLN_INCLUDE_ONLY
+# endif
+
+# include <mln/core/image/image3d.hh>
+# include <mln/core/image/image2d.hh>
+# include <mln/value/int_u8.hh>
+# include <mln/value/int_u16.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/value/hsl.hh>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ class display_seg : public QWidget, private Ui::DisplaySeg
+ {
+ Q_OBJECT
+
+ typedef image3d<value::int_u8> dcm_ima_t;
+ typedef image2d<value::int_u16> seg_ima_t;
+ typedef image2d<value::hsl_f> result_t;
+
+ public:
+ display_seg(QWidget *parent = 0);
+ ~display_seg();
+
+
+ private slots:
+ void on_browseBtn_clicked(bool);
+ void on_browseSegBtn_clicked(bool);
+ void compute_image(int sli);
+ void on_loadBtn_clicked(bool);
+
+ private: // Members
+
+ void setup_result();
+ void load_seg(const QString& filename);
+ void load_dicom(const QString& filename);
+
+ template <typename I>
+ mln_ch_value(I, value::int_u8) to_int_u8(const Image<I>& ima_);
+
+ void prepare_and_send_result(const QString& output);
+
+ private: // Attributes
+ dcm_ima_t dcm_ima;
+ seg_ima_t seg_ima;
+ value::int_u8 nlabels_;
+ result_t result;
+
+ };
+
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+#endif // ! MLN_DEMO_SRC_DISPLAY_SEG_HH
diff --git a/milena/sandbox/lazzara/igr/gui/src/edit_seg.cc b/milena/sandbox/lazzara/igr/gui/src/edit_seg.cc
new file mode 100644
index 0000000..14e58b5
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/edit_seg.cc
@@ -0,0 +1,204 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+
+#include <QtGui>
+
+# define INCLUDE_MLN_FILES
+#include <src/edit_seg.hh>
+#include <src/to_qimage.hh>
+
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/imorph/labeled_image.hh>
+#include <mln/core/concept/function.hh>
+
+#include <mln/data/wrap.hh>
+#include <mln/data/transform_inplace.hh>
+
+#include <mln/value/int_u16.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/io/ppm/save.hh>
+#include <mln/io/dump/load.hh>
+
+#include <mln/literal/colors.hh>
+
+#include <mln/labeling/colorize.hh>
+
+#include <mln/fun/v2v/wrap.hh>
+
+namespace mln
+{
+
+// namespace internal
+// {
+
+// struct merge_component : Function_v2v<merge_component>
+// {
+// typedef value::int_u16 result;
+
+// merge_component(const value::int_u16& replaced,
+// const value::int_u16& by)
+// : replaced_(replaced), by_(by)
+// {
+// }
+
+// value::int_u16 operator()(const value::int_u16& v) const
+// {
+// if (v == replaced_)
+// return by_;
+// return v;
+// }
+
+// value::int_u16 replaced_;
+// value::int_u16 by_;
+// };
+
+// } // end of namespace mln::internal
+
+
+
+
+ namespace demo
+ {
+
+
+ edit_seg::edit_seg(QWidget *parent)
+ : QWidget(parent)
+ {
+ setupUi(this);
+
+ connect(viewer, SIGNAL(slider_valueChanged(int)),
+ this, SLOT(compute_image()));
+
+ connect(viewer, SIGNAL(mouse_draw_line(const QPointF&, const QPointF&)),
+ this, SLOT(join_components(const QPointF&, const QPointF&)));
+
+ connect(viewer, SIGNAL(mouse_click(const QPointF&)),
+ this, SLOT(select_component(const QPointF&)));
+ }
+
+ edit_seg::~edit_seg()
+ {
+
+ }
+
+
+ void edit_seg::on_browseBtn_clicked(bool)
+ {
+ QString
+ filename = QFileDialog::getOpenFileName(this,
+ tr("Open Image."),
+ QString(),
+ tr("Images (*.dump)"));
+
+ if (!filename.isEmpty())
+ filepath->setText(filename);
+
+ // Initial load.
+ image2d<value::int_u16> tmp;
+ io::dump::load(tmp, filepath->text().toStdString());
+ seg_ = labeled_image<image2d<value::int_u16> >(tmp);
+
+ selected_.resize(seg_.nlabels(), false);
+
+ image2d<value::int_u8> tmp2 = data::wrap(value::int_u8(), seg_);
+ seg_rgb8_ = data::convert(value::rgb8(), tmp2);
+
+ viewer->set_image_layer_count(1);
+ }
+
+
+ void edit_seg::compute_image()
+ {
+ QImage ima = to_qimage(seg_rgb8_);
+ viewer->update_image(ima);
+ }
+
+
+ void edit_seg::join_components(const QPointF& p1, const QPointF& p2)
+ {
+// point2d
+// mln_p1 = point2d(p1.y(), p1.x()),
+// mln_p2 = point2d(p2.y(), p2.x());
+// if (seg_.domain().has(mln_p1) && seg_.domain().has(mln_p2) && // in domain
+// seg_(mln_p1) != seg_(mln_p2) // different components
+// && seg_(mln_p1) != 0 && seg_(mln_p2) != 0) // Not the wsl
+// {
+// std::cout << "Merging " << seg_(mln_p1)
+// << " and " << seg_(mln_p2) << std::endl;
+// std::cout << "mln_p1 = " << mln_p1 << " - mln_p2 = " << mln_p2 << std::endl;
+
+// internal::merge_component f(seg_(mln_p1), seg_(mln_p2));
+// data::transform_inplace(seg_, f);
+// compute_image();
+// }
+ }
+
+ void edit_seg::on_saveBtn_clicked(bool)
+ {
+ QString
+ filename = QFileDialog::getOpenFileName(this,
+ tr("Save Image."),
+ QString(),
+ tr("Images (*.dump)"));
+
+
+ image2d<value::int_u16>
+ out = data::transform(seg_.unmorph_(), selected_);
+
+ io::dump::save(out, filename.toStdString());
+ }
+
+
+ void edit_seg::select_component(const QPointF& p)
+ {
+ point2d
+ mln_p = point2d(p.y(), p.x());
+
+ if (seg_.domain().has(mln_p)
+ && !selected_(seg_(mln_p))
+ && seg_(mln_p) != 0) // Not the wsl
+ {
+ selected_(seg_(mln_p)) = true;
+ data::fill((seg_rgb8_ | seg_.subdomain(seg_(mln_p))).rw(),
+ literal::red);
+ }
+ else
+ {
+ selected_(seg_(mln_p)) = false;
+ value::rgb8
+ v = convert::to<value::rgb8>(fun::v2v:wrap<value::int_u8>(seg_(mln_p)));
+
+ value::rgb8 v(seg_(mln_p), seg_(mln_p), seg_(mln_p));
+ data::fill((seg_rgb8_ | seg_.subdomain(seg_(mln_p))).rw(), v);
+ }
+ compute_image();
+ }
+
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
diff --git a/milena/sandbox/lazzara/igr/gui/src/edit_seg.hh b/milena/sandbox/lazzara/igr/gui/src/edit_seg.hh
new file mode 100644
index 0000000..0d22db5
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/edit_seg.hh
@@ -0,0 +1,82 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_DEMO_SRC_EDIT_SEG_HH
+
+# include <QDir>
+# include <QTimer>
+# include <QStringList>
+# include <QProcess>
+# include <QtGui>
+# include <QProgressDialog>
+# include <ui_edit_seg.h>
+
+# ifndef INCLUDE_MLN_FILES
+# define MLN_INCLUDE_ONLY
+# endif
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/image/imorph/labeled_image.hh>
+# include <mln/value/int_u16.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/util/array.hh>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ class edit_seg : public QWidget, private Ui::EditSeg
+ {
+ Q_OBJECT
+
+ public:
+ edit_seg(QWidget *parent = 0);
+ ~edit_seg();
+
+
+ private slots:
+ void on_browseBtn_clicked(bool);
+ void on_saveBtn_clicked(bool);
+ void compute_image();
+ void join_components(const QPointF& p1, const QPointF& p2);
+ void select_component(const QPointF& p);
+
+ private: // Members
+
+
+ private: // Attributes
+ labeled_image<image2d<value::int_u16> > seg_;
+ image2d<value::rgb8> seg_rgb8_;
+ mln::util::array<bool> selected_;
+ };
+
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+#endif // ! MLN_DEMO_SRC_EDIT_SEG_HH
diff --git a/milena/sandbox/lazzara/igr/gui/src/image_viewer.cc b/milena/sandbox/lazzara/igr/gui/src/image_viewer.cc
new file mode 100644
index 0000000..4354aed
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/image_viewer.cc
@@ -0,0 +1,194 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+# include <src/image_viewer.hh>
+# include <src/internal/interactive_scene.hh>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ image_viewer::image_viewer(QWidget *parent)
+ : QWidget(parent), item_(0)
+ {
+ setupUi(this);
+
+ connect(image->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(move_vertical_sliders(int)));
+ connect(image->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(move_horizontal_sliders(int)));
+
+ setup_scene();
+
+ slider->setMinimum(0);
+ visible_slider(false);
+ }
+
+
+
+ image_viewer::~image_viewer()
+ {
+
+ }
+
+
+ // Private members
+
+ void image_viewer::setup_scene()
+ {
+ QGraphicsScene *scene = new internal::interactiveScene();
+ image->setScene(scene);
+
+ connect(scene, SIGNAL(mouse_draw_line(const QPointF&,const QPointF&)),
+ this, SIGNAL(mouse_draw_line(const QPointF&,const QPointF&)));
+ connect(scene, SIGNAL(mouse_click(const QPointF&)),
+ this, SIGNAL(mouse_click(const QPointF&)));
+
+ image->show();
+ }
+
+ void image_viewer::draw_image(const QImage& ima)
+ {
+ QPixmap pixmap = QPixmap::fromImage(ima);
+
+ if (item_ != 0)
+ {
+ image->scene()->removeItem(item_);
+ delete item_;
+ }
+
+ item_ = image->scene()->addPixmap(pixmap);
+ image->scene()->setSceneRect(item_->boundingRect());
+ if (pixmap.width() > image->maximumViewportSize().width())
+ image->fitInView(item_->boundingRect(), Qt::KeepAspectRatio);
+
+ zoomLabel->setEnabled(true);
+ zoomIn->setEnabled(true);
+ zoomOut->setEnabled(true);
+ zoomFixed->setEnabled(true);
+ zoomOriginal->setEnabled(true);
+ }
+
+ void image_viewer::resize_image(const QRectF& rect)
+ {
+ if (item_ != 0)
+ image->fitInView(rect, Qt::KeepAspectRatio);
+ }
+
+ void image_viewer::resizeEvent(QResizeEvent * event)
+ {
+ if (item_ != 0)
+ resize_image(item_->boundingRect());
+ event->ignore();
+ }
+
+
+ void image_viewer::keyPressEvent(QKeyEvent *event)
+ {
+ if (event->text() == QString("+"))
+ {
+ on_zoomIn_clicked();
+ event->accept();
+ }
+ else if (event->text() == QString("-"))
+ {
+ on_zoomOut_clicked();
+ event->accept();
+ }
+ else
+ event->ignore();
+ }
+
+
+ // Private slots
+
+ void image_viewer::visible_slider(bool b)
+ {
+ slider->setVisible(b);
+ label_2->setVisible(b);
+ frame_nb->setVisible(b);
+ }
+
+ void image_viewer::move_vertical_sliders(int value)
+ {
+ image->verticalScrollBar()->setValue(value);
+ }
+
+
+ void image_viewer::move_horizontal_sliders(int value)
+ {
+ image->horizontalScrollBar()->setValue(value);
+ }
+
+
+ void image_viewer::on_slider_valueChanged(int sli)
+ {
+ frame_nb->setText(QString::number(sli));
+ emit slider_valueChanged(sli);
+ }
+
+ void image_viewer::update_image(const QImage& ima)
+ {
+ draw_image(ima);
+ }
+
+
+ void image_viewer::on_zoomIn_clicked()
+ {
+ image->scale(1.2, 1.2);
+ }
+
+ void image_viewer::on_zoomOut_clicked()
+ {
+ image->scale(1 / 1.2, 1 / 1.2);
+ }
+
+ void image_viewer::on_zoomFixed_clicked()
+ {
+ resize_image(item_->boundingRect());
+ }
+
+ void image_viewer::on_zoomOriginal_clicked()
+ {
+ resize_image(image->viewport()->geometry());
+ }
+
+
+ // Public slots
+
+ void image_viewer::set_image_layer_count(unsigned nslis)
+ {
+ visible_slider(nslis > 1);
+
+ slider->setMaximum(nslis - 1);
+ on_slider_valueChanged(0);
+ }
+
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
diff --git a/milena/sandbox/lazzara/igr/gui/src/image_viewer.hh b/milena/sandbox/lazzara/igr/gui/src/image_viewer.hh
new file mode 100644
index 0000000..137cbc2
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/image_viewer.hh
@@ -0,0 +1,102 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_DEMO_SRC_IMAGE_VIEWER_HH
+# define MLN_DEMO_SRC_IMAGE_VIEWER_HH
+
+# include <QApplication>
+# include <QtCore>
+# include <QtGui>
+
+# include <ui_image_viewer.h>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+
+ class image_viewer
+ : public QWidget, private Ui::ImageViewer
+ {
+ Q_OBJECT;
+
+ public:
+ image_viewer(QWidget *parent = 0);
+ ~image_viewer();
+
+
+ private: // members
+ void setup_scene();
+
+ void draw_image(const QImage& ima);
+
+ void resize_image(const QRectF& rect);
+
+ void keyPressEvent(QKeyEvent *event);
+ void resizeEvent(QResizeEvent * event);
+// void mouseMoveEvent(QMouseEvent *e);
+// void mousePressEvent(QMouseEvent *e);
+// void mouseReleasedEvent(QMouseEvent *e);
+
+ private slots:
+ void visible_slider(bool b);
+
+ void move_vertical_sliders(int value);
+ void move_horizontal_sliders(int value);
+
+ void on_slider_valueChanged(int sli);
+
+ void on_zoomIn_clicked();
+ void on_zoomOut_clicked();
+ void on_zoomFixed_clicked();
+ void on_zoomOriginal_clicked();
+
+
+ public slots:
+ void set_image_layer_count(unsigned nslis);
+ void update_image(const QImage& ima);
+
+
+ signals:
+ void slider_valueChanged(int sli);
+ void mouse_draw_line(const QPointF& p1, const QPointF& p2);
+ void mouse_click(const QPointF& p);
+
+
+ private: // attributes
+ QGraphicsItem *item_;
+ bool mouse_moving_;
+ QPoint p_start_;
+ };
+
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+
+#endif // ! MLN_DEMO_SRC_IMAGE_VIEWER_HH
diff --git a/milena/sandbox/lazzara/igr/gui/src/internal/interactive_scene.cc b/milena/sandbox/lazzara/igr/gui/src/internal/interactive_scene.cc
new file mode 100644
index 0000000..b763cc3
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/internal/interactive_scene.cc
@@ -0,0 +1,88 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+# include <src/internal/interactive_scene.hh>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ namespace internal
+ {
+
+ interactiveScene::interactiveScene(QObject * parent)
+ : QGraphicsScene(parent)
+ {
+ line_.setZValue(1);
+
+ QPen pen;
+ pen.setColor(QColor(Qt::red));
+ pen.setStyle(Qt::SolidLine);
+ pen.setWidth(1);
+
+ line_.setPen(pen);
+ }
+
+
+ void interactiveScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
+ {
+ line_.setLine(QLineF(p_start_, e->scenePos()));
+ mouse_moved_ = true;
+
+ e->accept();
+ }
+
+ void interactiveScene::mousePressEvent(QGraphicsSceneMouseEvent *e)
+ {
+ p_start_ = e->scenePos();
+ mouse_moved_ = false;
+
+ line_.setLine(QLineF(e->scenePos(), e->scenePos()));
+ addItem(&line_);
+
+ e->accept();
+ }
+
+ void interactiveScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
+ {
+ if (line_.scene() == this)
+ removeItem(&line_);
+
+ if (mouse_moved_)
+ emit mouse_draw_line(p_start_, e->scenePos());
+ else
+ emit mouse_click(e->scenePos());
+
+ e->ignore();
+ }
+
+
+ } // end of namespace mln::demo::internal
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
diff --git a/milena/sandbox/lazzara/igr/gui/src/internal/interactive_scene.hh b/milena/sandbox/lazzara/igr/gui/src/internal/interactive_scene.hh
new file mode 100644
index 0000000..81f4068
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/internal/interactive_scene.hh
@@ -0,0 +1,73 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_DEMO_SRC_INTERNAL_INTERACTIVE_SCENE_HH
+# define MLN_DEMO_SRC_INTERNAL_INTERACTIVE_SCENE_HH
+
+# include <QtGui/QGraphicsScene>
+# include <QtGui/QGraphicsSceneMouseEvent>
+# include <QtGui/QGraphicsLineItem>
+# include <QtCore/QPoint>
+# include <QtCore/QDebug>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ namespace internal
+ {
+
+ class interactiveScene : public QGraphicsScene
+ {
+ Q_OBJECT
+
+ public:
+
+ interactiveScene(QObject * parent = 0);
+
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *e);
+ void mousePressEvent(QGraphicsSceneMouseEvent *e);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *e);
+
+ signals:
+ void mouse_draw_line(const QPointF& p1, const QPointF& p2);
+ void mouse_click(const QPointF& p);
+
+ private:
+ QGraphicsLineItem line_;
+ bool mouse_moved_;
+ QPointF p_start_;
+ };
+
+
+ } // end of namespace mln::demo::internal
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+#endif // ! MLN_DEMO_SRC_INTERNAL_INTERACTIVE_SCENE_HH
diff --git a/milena/sandbox/lazzara/igr/gui/src/main.cc b/milena/sandbox/lazzara/igr/gui/src/main.cc
new file mode 100644
index 0000000..cbb4ec1
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/main.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <QApplication>
+#include <QtGui>
+
+#include <src/main_window.hh>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ mln::demo::main_window win;
+
+ win.show();
+ return app.exec();
+}
diff --git a/milena/sandbox/lazzara/igr/gui/src/main_window.cc b/milena/sandbox/lazzara/igr/gui/src/main_window.cc
new file mode 100644
index 0000000..bdae998
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/main_window.cc
@@ -0,0 +1,56 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+
+#include <QtCore>
+#include <QtGui>
+#include <src/main_window.hh>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ main_window::main_window(QWidget *parent)
+ : QMainWindow(parent)
+ {
+ setupUi(this);
+
+ // No status bar.
+ setStatusBar(0);
+
+ }
+
+ main_window::~main_window()
+ {
+ }
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
diff --git a/milena/sandbox/lazzara/igr/gui/src/main_window.hh b/milena/sandbox/lazzara/igr/gui/src/main_window.hh
new file mode 100644
index 0000000..502a514
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/main_window.hh
@@ -0,0 +1,60 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_DEMO_SRC_MAIN_WINDOW_HH
+
+# include <QtGui>
+# include <ui_main_window.h>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+
+ class main_window : public QMainWindow, private Ui::MainWindow
+ {
+ Q_OBJECT
+
+ public:
+ main_window(QWidget *parent = 0);
+ ~main_window();
+
+
+ private slots:
+
+ private: // Members
+
+ private: // Attributes
+
+ };
+
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+#endif // ! MLN_DEMO_SRC_MAIN_WINDOW_HH
diff --git a/milena/sandbox/lazzara/igr/gui/src/to_qimage.hh b/milena/sandbox/lazzara/igr/gui/src/to_qimage.hh
new file mode 100644
index 0000000..75c9756
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/to_qimage.hh
@@ -0,0 +1,63 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+
+#ifndef MLN_DEMO_SRC_TO_QIMAGE_HH
+# define MLN_DEMO_SRC_TO_QIMAGE_HH
+
+# include <QtGui/QImage>
+
+# include <mln/core/concept/image.hh>
+# include <mln/geom/nrows.hh>
+# include <mln/geom/ncols.hh>
+# include <mln/border/resize.hh>
+
+namespace mln
+{
+
+ template <typename I>
+ inline
+ QImage to_qimage(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ const int
+ nrows = geom::nrows(ima),
+ ncols = geom::ncols(ima);
+
+ // Required by a one-shot data copy:
+ mln::border::resize(ima, 0);
+
+ QImage qima(ncols, nrows, QImage::Format_RGB888);
+ std::memcpy(qima.scanLine(0),
+ ima.buffer(),
+ ima.nelements() * 3);
+ return qima;
+ }
+
+} // end of namespace mln
+
+#endif // ! MLN_DEMO_SRC_TO_QIMAGE_HH
diff --git a/milena/sandbox/lazzara/igr/gui/src/widgets.cc b/milena/sandbox/lazzara/igr/gui/src/widgets.cc
new file mode 100644
index 0000000..5968dc4
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/src/widgets.cc
@@ -0,0 +1,3 @@
+// FIXME: UGLY!!! Avoir multiple definition of Milena's code.
+# include "src/display_seg.cc"
+# include "src/edit_seg.cc"
diff --git a/milena/sandbox/lazzara/igr/gui/ui/bak/mainwindow.ui b/milena/sandbox/lazzara/igr/gui/ui/bak/mainwindow.ui
new file mode 100644
index 0000000..59c88b7
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/ui/bak/mainwindow.ui
@@ -0,0 +1,277 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>729</width>
+ <height>455</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string/>
+ </property>
+ <property name="dockOptions" >
+ <set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks</set>
+ </property>
+ <property name="unifiedTitleAndToolBarOnMac" >
+ <bool>false</bool>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QGridLayout" name="gridLayout_3" >
+ <item row="0" column="0" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLineEdit" name="filepath" />
+ </item>
+ <item row="0" column="1" >
+ <widget class="QPushButton" name="browseBtn" >
+ <property name="text" >
+ <string>&Browse</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="../demo.qrc" >
+ <normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+B</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" >
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <spacer name="horizontalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="displayBtn" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Refresh</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="../demo.qrc" >
+ <normaloff>:/icons/view-refresh.png</normaloff>:/icons/view-refresh.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_2" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="useCache" >
+ <property name="text" >
+ <string>Enable cache</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="autoDemo" >
+ <property name="text" >
+ <string>Auto demo</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+D</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="timeoutDelay" >
+ <property name="maximumSize" >
+ <size>
+ <width>30</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="inputMask" >
+ <string/>
+ </property>
+ <property name="text" >
+ <string>5</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>s.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line_3" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="runBtn" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Run</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="../demo.qrc" >
+ <normaloff>:/icons/go-next.png</normaloff>:/icons/go-next.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="autoRun" >
+ <property name="text" >
+ <string>Auto Run</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QSplitter" name="splitter" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QWidget" name="" >
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <property name="sizeConstraint" >
+ <enum>QLayout::SetMaximumSize</enum>
+ </property>
+ <item>
+ <widget class="QListWidget" name="listWidget" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="imginfo" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="" >
+ <layout class="QGridLayout" name="gridLayout_2" >
+ <property name="sizeConstraint" >
+ <enum>QLayout::SetNoConstraint</enum>
+ </property>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>729</width>
+ <height>31</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ </widget>
+ <resources>
+ <include location="../demo.qrc" />
+ </resources>
+ <connections>
+ <connection>
+ <sender>filepath</sender>
+ <signal>returnPressed()</signal>
+ <receiver>displayBtn</receiver>
+ <slot>click()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>213</x>
+ <y>62</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>564</x>
+ <y>64</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/milena/sandbox/lazzara/igr/gui/ui/display_seg.ui b/milena/sandbox/lazzara/igr/gui/ui/display_seg.ui
new file mode 100644
index 0000000..f005511
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/ui/display_seg.ui
@@ -0,0 +1,108 @@
+<ui version="4.0" >
+ <class>DisplaySeg</class>
+ <widget class="QWidget" name="DisplaySeg" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="0" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" >
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Image</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="filepath" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="browseBtn" >
+ <property name="text" >
+ <string>&Browse</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2" >
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Segmentation</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="segfilepath" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="browseSegBtn" >
+ <property name="text" >
+ <string>&Browse</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3" >
+ <item>
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>48</width>
+ <height>17</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="loadBtn" >
+ <property name="text" >
+ <string>&Load</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="mln::demo::image_viewer" native="1" name="viewer" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>mln::demo::image_viewer</class>
+ <extends>QWidget</extends>
+ <header>src/image_viewer.hh</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/milena/sandbox/lazzara/igr/gui/ui/edit_seg.ui b/milena/sandbox/lazzara/igr/gui/ui/edit_seg.ui
new file mode 100644
index 0000000..f79026d
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/ui/edit_seg.ui
@@ -0,0 +1,97 @@
+<ui version="4.0" >
+ <class>EditSeg</class>
+ <widget class="QWidget" name="EditSeg" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="0" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2" >
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Segmentation</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="filepath" />
+ </item>
+ <item>
+ <widget class="QPushButton" name="browseBtn" >
+ <property name="text" >
+ <string>&Browse</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3" >
+ <item>
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>48</width>
+ <height>17</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="reloadBtn" >
+ <property name="text" >
+ <string>&Reload</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="saveBtn" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>&Save changes</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="mln::demo::image_viewer" native="1" name="viewer" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>mln::demo::image_viewer</class>
+ <extends>QWidget</extends>
+ <header>src/image_viewer.hh</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/milena/sandbox/lazzara/igr/gui/ui/image_viewer.ui b/milena/sandbox/lazzara/igr/gui/ui/image_viewer.ui
new file mode 100644
index 0000000..450f982
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/ui/image_viewer.ui
@@ -0,0 +1,154 @@
+<ui version="4.0" >
+ <class>ImageViewer</class>
+ <widget class="QWidget" name="ImageViewer" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>464</width>
+ <height>350</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2" >
+ <item>
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="zoomLabel" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Zoom:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="zoomIn" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>+</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="zoomOut" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="zoomFixed" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Fixed width</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="zoomOriginal" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Original size</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGraphicsView" name="image" >
+ <property name="interactive" >
+ <bool>true</bool>
+ </property>
+ <property name="renderHints" >
+ <set>QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="sliderLayout" >
+ <item>
+ <widget class="QSlider" name="slider" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Current Frame :</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="frame_nb" >
+ <property name="font" >
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/milena/sandbox/lazzara/igr/gui/ui/main_window.ui b/milena/sandbox/lazzara/igr/gui/ui/main_window.ui
new file mode 100644
index 0000000..75f3327
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/ui/main_window.ui
@@ -0,0 +1,64 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>487</width>
+ <height>335</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Segmentation tools</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="0" >
+ <widget class="QTabWidget" name="tabWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="mln::demo::display_seg" name="Visualization" >
+ <attribute name="title" >
+ <string>Visualization</string>
+ </attribute>
+ </widget>
+ <widget class="mln::demo::edit_seg" name="Edition" >
+ <attribute name="title" >
+ <string>Edition</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>487</width>
+ <height>31</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>mln::demo::display_seg</class>
+ <extends>QWidget</extends>
+ <header>src/display_seg.hh</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>mln::demo::edit_seg</class>
+ <extends>QWidget</extends>
+ <header>src/edit_seg.hh</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/milena/sandbox/lazzara/igr/gui/ui_display_seg.h b/milena/sandbox/lazzara/igr/gui/ui_display_seg.h
new file mode 100644
index 0000000..5875534
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/ui_display_seg.h
@@ -0,0 +1,148 @@
+/********************************************************************************
+** Form generated from reading ui file 'display_seg.ui'
+**
+** Created: Wed Oct 28 12:45:22 2009
+** by: Qt User Interface Compiler version 4.4.3
+**
+** WARNING! All changes made in this file will be lost when recompiling ui file!
+********************************************************************************/
+
+#ifndef UI_DISPLAY_SEG_H
+#define UI_DISPLAY_SEG_H
+
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QGridLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QPushButton>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QWidget>
+#include "src/image_viewer.hh"
+
+QT_BEGIN_NAMESPACE
+
+class Ui_DisplaySeg
+{
+public:
+ QGridLayout *gridLayout;
+ QVBoxLayout *verticalLayout;
+ QHBoxLayout *horizontalLayout;
+ QLabel *label;
+ QLineEdit *filepath;
+ QPushButton *browseBtn;
+ QHBoxLayout *horizontalLayout_2;
+ QLabel *label_2;
+ QLineEdit *segfilepath;
+ QPushButton *browseSegBtn;
+ QHBoxLayout *horizontalLayout_3;
+ QSpacerItem *horizontalSpacer;
+ QPushButton *loadBtn;
+ mln::demo::image_viewer *viewer;
+
+ void setupUi(QWidget *DisplaySeg)
+ {
+ if (DisplaySeg->objectName().isEmpty())
+ DisplaySeg->setObjectName(QString::fromUtf8("DisplaySeg"));
+ DisplaySeg->resize(400, 300);
+ gridLayout = new QGridLayout(DisplaySeg);
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+ verticalLayout = new QVBoxLayout();
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
+ horizontalLayout = new QHBoxLayout();
+ horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
+ label = new QLabel(DisplaySeg);
+ label->setObjectName(QString::fromUtf8("label"));
+
+ horizontalLayout->addWidget(label);
+
+ filepath = new QLineEdit(DisplaySeg);
+ filepath->setObjectName(QString::fromUtf8("filepath"));
+
+ horizontalLayout->addWidget(filepath);
+
+ browseBtn = new QPushButton(DisplaySeg);
+ browseBtn->setObjectName(QString::fromUtf8("browseBtn"));
+
+ horizontalLayout->addWidget(browseBtn);
+
+
+ verticalLayout->addLayout(horizontalLayout);
+
+ horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
+ label_2 = new QLabel(DisplaySeg);
+ label_2->setObjectName(QString::fromUtf8("label_2"));
+
+ horizontalLayout_2->addWidget(label_2);
+
+ segfilepath = new QLineEdit(DisplaySeg);
+ segfilepath->setObjectName(QString::fromUtf8("segfilepath"));
+
+ horizontalLayout_2->addWidget(segfilepath);
+
+ browseSegBtn = new QPushButton(DisplaySeg);
+ browseSegBtn->setObjectName(QString::fromUtf8("browseSegBtn"));
+
+ horizontalLayout_2->addWidget(browseSegBtn);
+
+
+ verticalLayout->addLayout(horizontalLayout_2);
+
+ horizontalLayout_3 = new QHBoxLayout();
+ horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
+ horizontalSpacer = new QSpacerItem(48, 17, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ horizontalLayout_3->addItem(horizontalSpacer);
+
+ loadBtn = new QPushButton(DisplaySeg);
+ loadBtn->setObjectName(QString::fromUtf8("loadBtn"));
+
+ horizontalLayout_3->addWidget(loadBtn);
+
+
+ verticalLayout->addLayout(horizontalLayout_3);
+
+ viewer = new mln::demo::image_viewer(DisplaySeg);
+ viewer->setObjectName(QString::fromUtf8("viewer"));
+ QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(viewer->sizePolicy().hasHeightForWidth());
+ viewer->setSizePolicy(sizePolicy);
+
+ verticalLayout->addWidget(viewer);
+
+
+ gridLayout->addLayout(verticalLayout, 0, 0, 1, 1);
+
+
+ retranslateUi(DisplaySeg);
+
+ QMetaObject::connectSlotsByName(DisplaySeg);
+ } // setupUi
+
+ void retranslateUi(QWidget *DisplaySeg)
+ {
+ DisplaySeg->setWindowTitle(QApplication::translate("DisplaySeg", "Form", 0, QApplication::UnicodeUTF8));
+ label->setText(QApplication::translate("DisplaySeg", "Image", 0, QApplication::UnicodeUTF8));
+ browseBtn->setText(QApplication::translate("DisplaySeg", "&Browse", 0, QApplication::UnicodeUTF8));
+ label_2->setText(QApplication::translate("DisplaySeg", "Segmentation", 0, QApplication::UnicodeUTF8));
+ browseSegBtn->setText(QApplication::translate("DisplaySeg", "&Browse", 0, QApplication::UnicodeUTF8));
+ loadBtn->setText(QApplication::translate("DisplaySeg", "&Load", 0, QApplication::UnicodeUTF8));
+ Q_UNUSED(DisplaySeg);
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class DisplaySeg: public Ui_DisplaySeg {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // UI_DISPLAY_SEG_H
diff --git a/milena/sandbox/lazzara/igr/gui/ui_edit_seg.h b/milena/sandbox/lazzara/igr/gui/ui_edit_seg.h
new file mode 100644
index 0000000..9d8e07e
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/ui_edit_seg.h
@@ -0,0 +1,130 @@
+/********************************************************************************
+** Form generated from reading ui file 'edit_seg.ui'
+**
+** Created: Wed Oct 28 12:45:22 2009
+** by: Qt User Interface Compiler version 4.4.3
+**
+** WARNING! All changes made in this file will be lost when recompiling ui file!
+********************************************************************************/
+
+#ifndef UI_EDIT_SEG_H
+#define UI_EDIT_SEG_H
+
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QGridLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QPushButton>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QWidget>
+#include "src/image_viewer.hh"
+
+QT_BEGIN_NAMESPACE
+
+class Ui_EditSeg
+{
+public:
+ QGridLayout *gridLayout;
+ QVBoxLayout *verticalLayout;
+ QHBoxLayout *horizontalLayout_2;
+ QLabel *label_2;
+ QLineEdit *filepath;
+ QPushButton *browseBtn;
+ QHBoxLayout *horizontalLayout_3;
+ QSpacerItem *horizontalSpacer;
+ QPushButton *reloadBtn;
+ QPushButton *saveBtn;
+ mln::demo::image_viewer *viewer;
+
+ void setupUi(QWidget *EditSeg)
+ {
+ if (EditSeg->objectName().isEmpty())
+ EditSeg->setObjectName(QString::fromUtf8("EditSeg"));
+ EditSeg->resize(400, 300);
+ gridLayout = new QGridLayout(EditSeg);
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+ verticalLayout = new QVBoxLayout();
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
+ horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
+ label_2 = new QLabel(EditSeg);
+ label_2->setObjectName(QString::fromUtf8("label_2"));
+
+ horizontalLayout_2->addWidget(label_2);
+
+ filepath = new QLineEdit(EditSeg);
+ filepath->setObjectName(QString::fromUtf8("filepath"));
+
+ horizontalLayout_2->addWidget(filepath);
+
+ browseBtn = new QPushButton(EditSeg);
+ browseBtn->setObjectName(QString::fromUtf8("browseBtn"));
+
+ horizontalLayout_2->addWidget(browseBtn);
+
+
+ verticalLayout->addLayout(horizontalLayout_2);
+
+ horizontalLayout_3 = new QHBoxLayout();
+ horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
+ horizontalSpacer = new QSpacerItem(48, 17, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ horizontalLayout_3->addItem(horizontalSpacer);
+
+ reloadBtn = new QPushButton(EditSeg);
+ reloadBtn->setObjectName(QString::fromUtf8("reloadBtn"));
+
+ horizontalLayout_3->addWidget(reloadBtn);
+
+ saveBtn = new QPushButton(EditSeg);
+ saveBtn->setObjectName(QString::fromUtf8("saveBtn"));
+ saveBtn->setEnabled(false);
+
+ horizontalLayout_3->addWidget(saveBtn);
+
+
+ verticalLayout->addLayout(horizontalLayout_3);
+
+ viewer = new mln::demo::image_viewer(EditSeg);
+ viewer->setObjectName(QString::fromUtf8("viewer"));
+ QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(viewer->sizePolicy().hasHeightForWidth());
+ viewer->setSizePolicy(sizePolicy);
+
+ verticalLayout->addWidget(viewer);
+
+
+ gridLayout->addLayout(verticalLayout, 0, 0, 1, 1);
+
+
+ retranslateUi(EditSeg);
+
+ QMetaObject::connectSlotsByName(EditSeg);
+ } // setupUi
+
+ void retranslateUi(QWidget *EditSeg)
+ {
+ EditSeg->setWindowTitle(QApplication::translate("EditSeg", "Form", 0, QApplication::UnicodeUTF8));
+ label_2->setText(QApplication::translate("EditSeg", "Segmentation", 0, QApplication::UnicodeUTF8));
+ browseBtn->setText(QApplication::translate("EditSeg", "&Browse", 0, QApplication::UnicodeUTF8));
+ reloadBtn->setText(QApplication::translate("EditSeg", "&Reload", 0, QApplication::UnicodeUTF8));
+ saveBtn->setText(QApplication::translate("EditSeg", "&Save changes", 0, QApplication::UnicodeUTF8));
+ Q_UNUSED(EditSeg);
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class EditSeg: public Ui_EditSeg {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // UI_EDIT_SEG_H
diff --git a/milena/sandbox/lazzara/igr/gui/ui_image_viewer.h b/milena/sandbox/lazzara/igr/gui/ui_image_viewer.h
new file mode 100644
index 0000000..01cc5df
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/ui_image_viewer.h
@@ -0,0 +1,167 @@
+/********************************************************************************
+** Form generated from reading ui file 'image_viewer.ui'
+**
+** Created: Wed Oct 28 12:45:22 2009
+** by: Qt User Interface Compiler version 4.4.3
+**
+** WARNING! All changes made in this file will be lost when recompiling ui file!
+********************************************************************************/
+
+#ifndef UI_IMAGE_VIEWER_H
+#define UI_IMAGE_VIEWER_H
+
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QGraphicsView>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QPushButton>
+#include <QtGui/QSlider>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class Ui_ImageViewer
+{
+public:
+ QVBoxLayout *verticalLayout_2;
+ QVBoxLayout *verticalLayout;
+ QHBoxLayout *horizontalLayout_2;
+ QSpacerItem *horizontalSpacer;
+ QLabel *zoomLabel;
+ QPushButton *zoomIn;
+ QPushButton *zoomOut;
+ QPushButton *zoomFixed;
+ QPushButton *zoomOriginal;
+ QSpacerItem *horizontalSpacer_2;
+ QGraphicsView *image;
+ QHBoxLayout *sliderLayout;
+ QSlider *slider;
+ QLabel *label_2;
+ QLabel *frame_nb;
+
+ void setupUi(QWidget *ImageViewer)
+ {
+ if (ImageViewer->objectName().isEmpty())
+ ImageViewer->setObjectName(QString::fromUtf8("ImageViewer"));
+ ImageViewer->resize(464, 350);
+ QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(ImageViewer->sizePolicy().hasHeightForWidth());
+ ImageViewer->setSizePolicy(sizePolicy);
+ verticalLayout_2 = new QVBoxLayout(ImageViewer);
+ verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2"));
+ verticalLayout = new QVBoxLayout();
+ verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
+ horizontalLayout_2 = new QHBoxLayout();
+ horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
+ horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ horizontalLayout_2->addItem(horizontalSpacer);
+
+ zoomLabel = new QLabel(ImageViewer);
+ zoomLabel->setObjectName(QString::fromUtf8("zoomLabel"));
+ zoomLabel->setEnabled(false);
+
+ horizontalLayout_2->addWidget(zoomLabel);
+
+ zoomIn = new QPushButton(ImageViewer);
+ zoomIn->setObjectName(QString::fromUtf8("zoomIn"));
+ zoomIn->setEnabled(false);
+
+ horizontalLayout_2->addWidget(zoomIn);
+
+ zoomOut = new QPushButton(ImageViewer);
+ zoomOut->setObjectName(QString::fromUtf8("zoomOut"));
+ zoomOut->setEnabled(false);
+
+ horizontalLayout_2->addWidget(zoomOut);
+
+ zoomFixed = new QPushButton(ImageViewer);
+ zoomFixed->setObjectName(QString::fromUtf8("zoomFixed"));
+ zoomFixed->setEnabled(false);
+
+ horizontalLayout_2->addWidget(zoomFixed);
+
+ zoomOriginal = new QPushButton(ImageViewer);
+ zoomOriginal->setObjectName(QString::fromUtf8("zoomOriginal"));
+ zoomOriginal->setEnabled(false);
+
+ horizontalLayout_2->addWidget(zoomOriginal);
+
+ horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+ horizontalLayout_2->addItem(horizontalSpacer_2);
+
+
+ verticalLayout->addLayout(horizontalLayout_2);
+
+ image = new QGraphicsView(ImageViewer);
+ image->setObjectName(QString::fromUtf8("image"));
+ image->setInteractive(true);
+ image->setRenderHints(QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing);
+
+ verticalLayout->addWidget(image);
+
+ sliderLayout = new QHBoxLayout();
+ sliderLayout->setObjectName(QString::fromUtf8("sliderLayout"));
+ slider = new QSlider(ImageViewer);
+ slider->setObjectName(QString::fromUtf8("slider"));
+ slider->setOrientation(Qt::Horizontal);
+ slider->setTickPosition(QSlider::TicksAbove);
+
+ sliderLayout->addWidget(slider);
+
+ label_2 = new QLabel(ImageViewer);
+ label_2->setObjectName(QString::fromUtf8("label_2"));
+
+ sliderLayout->addWidget(label_2);
+
+ frame_nb = new QLabel(ImageViewer);
+ frame_nb->setObjectName(QString::fromUtf8("frame_nb"));
+ QFont font;
+ font.setBold(true);
+ font.setWeight(75);
+ frame_nb->setFont(font);
+
+ sliderLayout->addWidget(frame_nb);
+
+
+ verticalLayout->addLayout(sliderLayout);
+
+
+ verticalLayout_2->addLayout(verticalLayout);
+
+
+ retranslateUi(ImageViewer);
+
+ QMetaObject::connectSlotsByName(ImageViewer);
+ } // setupUi
+
+ void retranslateUi(QWidget *ImageViewer)
+ {
+ ImageViewer->setWindowTitle(QApplication::translate("ImageViewer", "Form", 0, QApplication::UnicodeUTF8));
+ zoomLabel->setText(QApplication::translate("ImageViewer", "Zoom:", 0, QApplication::UnicodeUTF8));
+ zoomIn->setText(QApplication::translate("ImageViewer", "+", 0, QApplication::UnicodeUTF8));
+ zoomOut->setText(QApplication::translate("ImageViewer", "-", 0, QApplication::UnicodeUTF8));
+ zoomFixed->setText(QApplication::translate("ImageViewer", "Fixed width", 0, QApplication::UnicodeUTF8));
+ zoomOriginal->setText(QApplication::translate("ImageViewer", "Original size", 0, QApplication::UnicodeUTF8));
+ label_2->setText(QApplication::translate("ImageViewer", "Current Frame :", 0, QApplication::UnicodeUTF8));
+ frame_nb->setText(QApplication::translate("ImageViewer", "0", 0, QApplication::UnicodeUTF8));
+ Q_UNUSED(ImageViewer);
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class ImageViewer: public Ui_ImageViewer {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // UI_IMAGE_VIEWER_H
diff --git a/milena/sandbox/lazzara/igr/gui/ui_main_window.h b/milena/sandbox/lazzara/igr/gui/ui_main_window.h
new file mode 100644
index 0000000..0f1ce23
--- /dev/null
+++ b/milena/sandbox/lazzara/igr/gui/ui_main_window.h
@@ -0,0 +1,92 @@
+/********************************************************************************
+** Form generated from reading ui file 'main_window.ui'
+**
+** Created: Wed Oct 28 13:14:49 2009
+** by: Qt User Interface Compiler version 4.4.3
+**
+** WARNING! All changes made in this file will be lost when recompiling ui file!
+********************************************************************************/
+
+#ifndef UI_MAIN_WINDOW_H
+#define UI_MAIN_WINDOW_H
+
+#include <QtCore/QVariant>
+#include <QtGui/QAction>
+#include <QtGui/QApplication>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QGridLayout>
+#include <QtGui/QMainWindow>
+#include <QtGui/QMenuBar>
+#include <QtGui/QStatusBar>
+#include <QtGui/QTabWidget>
+#include <QtGui/QWidget>
+#include "src/display_seg.hh"
+#include "src/edit_seg.hh"
+
+QT_BEGIN_NAMESPACE
+
+class Ui_MainWindow
+{
+public:
+ QWidget *centralwidget;
+ QGridLayout *gridLayout;
+ QTabWidget *tabWidget;
+ mln::demo::display_seg *Visualization;
+ mln::demo::edit_seg *Edition;
+ QMenuBar *menubar;
+ QStatusBar *statusbar;
+
+ void setupUi(QMainWindow *MainWindow)
+ {
+ if (MainWindow->objectName().isEmpty())
+ MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
+ MainWindow->resize(487, 335);
+ centralwidget = new QWidget(MainWindow);
+ centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
+ gridLayout = new QGridLayout(centralwidget);
+ gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+ tabWidget = new QTabWidget(centralwidget);
+ tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
+ Visualization = new mln::demo::display_seg();
+ Visualization->setObjectName(QString::fromUtf8("Visualization"));
+ tabWidget->addTab(Visualization, QString());
+ Edition = new mln::demo::edit_seg();
+ Edition->setObjectName(QString::fromUtf8("Edition"));
+ tabWidget->addTab(Edition, QString());
+
+ gridLayout->addWidget(tabWidget, 0, 0, 1, 1);
+
+ MainWindow->setCentralWidget(centralwidget);
+ menubar = new QMenuBar(MainWindow);
+ menubar->setObjectName(QString::fromUtf8("menubar"));
+ menubar->setGeometry(QRect(0, 0, 487, 31));
+ MainWindow->setMenuBar(menubar);
+ statusbar = new QStatusBar(MainWindow);
+ statusbar->setObjectName(QString::fromUtf8("statusbar"));
+ MainWindow->setStatusBar(statusbar);
+
+ retranslateUi(MainWindow);
+
+ tabWidget->setCurrentIndex(0);
+
+
+ QMetaObject::connectSlotsByName(MainWindow);
+ } // setupUi
+
+ void retranslateUi(QMainWindow *MainWindow)
+ {
+ MainWindow->setWindowTitle(QApplication::translate("MainWindow", "Segmentation tools", 0, QApplication::UnicodeUTF8));
+ tabWidget->setTabText(tabWidget->indexOf(Visualization), QApplication::translate("MainWindow", "Visualization", 0, QApplication::UnicodeUTF8));
+ tabWidget->setTabText(tabWidget->indexOf(Edition), QApplication::translate("MainWindow", "Edition", 0, QApplication::UnicodeUTF8));
+ Q_UNUSED(MainWindow);
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class MainWindow: public Ui_MainWindow {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // UI_MAIN_WINDOW_H
--
1.5.6.5
1
0
* debug/alignment_decision_image.hh,
* debug/links_decision_image.hh,
* debug/save_object_diff.hh,
* debug/several_links_decision_image.hh: New.
---
scribo/ChangeLog | 9 ++
scribo/debug/alignment_decision_image.hh | 170 +++++++++++++++++++++++
scribo/debug/links_decision_image.hh | 127 ++++++++++++++++++
scribo/debug/save_object_diff.hh | 98 ++++++++++++++
scribo/debug/several_links_decision_image.hh | 185 ++++++++++++++++++++++++++
5 files changed, 589 insertions(+), 0 deletions(-)
create mode 100644 scribo/debug/alignment_decision_image.hh
create mode 100644 scribo/debug/links_decision_image.hh
create mode 100644 scribo/debug/save_object_diff.hh
create mode 100644 scribo/debug/several_links_decision_image.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index deee412..5e2d69e 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,14 @@
2009-10-22 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add new debug routines.
+
+ * debug/alignment_decision_image.hh,
+ * debug/links_decision_image.hh,
+ * debug/save_object_diff.hh,
+ * debug/several_links_decision_image.hh: New.
+
+2009-10-22 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Revamp Sauvola binarization.
* binarization/sauvola.hh: Revamp and now returns a threshold
diff --git a/scribo/debug/alignment_decision_image.hh b/scribo/debug/alignment_decision_image.hh
new file mode 100644
index 0000000..9a4fa50
--- /dev/null
+++ b/scribo/debug/alignment_decision_image.hh
@@ -0,0 +1,170 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEBUG_ALIGNMENT_DECISION_IMAGE_HH
+# define SCRIBO_DEBUG_ALIGNMENT_DECISION_IMAGE_HH
+
+/// \file
+///
+/// Save a color image showing the difference between to object groups.
+
+# include <mln/core/concept/image.hh>
+# include <mln/data/convert.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/literal/colors.hh>
+# include <mln/util/array.hh>
+# include <mln/util/couple.hh>
+
+# include <scribo/core/object_groups.hh>
+# include <scribo/draw/bounding_boxes.hh>
+
+
+namespace scribo
+{
+
+ namespace debug
+ {
+
+ using namespace mln;
+
+ enum Alignment { top, center, bottom };
+
+ /*! \brief Save a color image showing the difference between to
+ object links.
+
+ \input[in] input An image. It's value type must be convertible
+ towards rgb8.
+ \input[in] links Object links information.
+ \input[in] filtered_links A copy of \p links which have been
+ filtered.
+
+ \return A color image. Non filtered links are drawn in
+ green. Others are drawn in red.
+ */
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ alignment_decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links,
+ const Alignment& alignment);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+ template <typename L>
+ mln::util::couple<mln_site(L),mln_site(L)>
+ find_anchors(const object_image(L)& objects,
+ unsigned i,
+ unsigned link_i,
+ const Alignment& alignment)
+ {
+ mln_site(L)
+ a1 = objects.bbox(i).center(),
+ a2 = objects.bbox(link_i).center();
+
+ switch (alignment)
+ {
+ case top:
+ a1.row() = objects.bbox(i).pmin().row();
+ a2.row() = objects.bbox(link_i).pmin().row();
+ break;
+
+ case center:
+ break;
+
+ case bottom:
+ a1.row() = objects.bbox(i).pmax().row();
+ a2.row() = objects.bbox(link_i).pmax().row();
+ break;
+
+ }
+ return make::couple(a1, a2);
+ }
+
+ }
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ alignment_decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links,
+ const Alignment& alignment)
+ {
+ trace::entering("scribo::debug::alignment_decision_image");
+ const I& input = exact(input_);
+
+ const object_image(L)& objects = links.object_image_();
+
+ mln_precondition(input.is_valid());
+ mln_precondition(links.is_valid());
+ mln_precondition(filtered_links.is_valid());
+ mln_precondition(links.size() == filtered_links.size());
+ mln_precondition(links.object_image_() != filtered_links.object_image_());
+ /// Fixme: check that objects has been computed from input.
+
+ image2d<value::rgb8>
+ decision_image = data::convert(value::rgb8(), input);
+
+ for_all_components(i, objects.bboxes())
+ mln::draw::box(decision_image, objects.bbox(i), literal::blue);
+
+ typedef mln_site(L) P;
+
+ for (unsigned i = 1; i < links.size(); ++i)
+ {
+
+ if (links[i] != i)
+ {
+ value::rgb8 value = literal::green;
+ if (links[i] != filtered_links[i])
+ value = literal::red;
+
+ mln::util::couple<P,P>
+ anchors = internal::find_anchors(objects, i, links[i], alignment);
+ mln::draw::line(decision_image,
+ anchors.first(),
+ anchors.second(),
+ value);
+ }
+ }
+
+ trace::exiting("scribo::debug::alignment_decision_image");
+ return decision_image;
+ }
+
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::debug
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEBUG_ALIGNMENT_DECISION_IMAGE_HH
diff --git a/scribo/debug/links_decision_image.hh b/scribo/debug/links_decision_image.hh
new file mode 100644
index 0000000..368d9b7
--- /dev/null
+++ b/scribo/debug/links_decision_image.hh
@@ -0,0 +1,127 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEBUG_LINKS_DECISION_IMAGE_HH
+# define SCRIBO_DEBUG_LINKS_DECISION_IMAGE_HH
+
+/// \file
+///
+/// Save a color image showing the difference between to object groups.
+
+# include <mln/core/concept/image.hh>
+# include <mln/accu/center.hh>
+# include <mln/data/convert.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/literal/colors.hh>
+# include <mln/util/array.hh>
+
+# include <scribo/core/object_groups.hh>
+# include <scribo/draw/bounding_boxes.hh>
+
+
+namespace scribo
+{
+
+ namespace debug
+ {
+
+ using namespace mln;
+
+ /// FIXME: DOC!
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ links_decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ links_decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links)
+ {
+ trace::entering("scribo::debug::links_decision_image");
+ const I& input = exact(input_);
+
+ const object_image(L)& objects = links.object_image_();
+
+ mln_precondition(input.is_valid());
+ mln_precondition(objects.is_valid());
+ mln_precondition(links.is_valid());
+ mln_precondition(filtered_links.is_valid());
+ mln_precondition(links.size() == filtered_links.size());
+ mln_precondition(links.object_image_() != filtered_links.object_image_());
+ /// Fixme: check that objects has been computed from input.
+
+ image2d<value::rgb8>
+ links_decision_image = data::convert(value::rgb8(), input);
+
+ for_all_components(i, objects.bboxes())
+ mln::draw::box(links_decision_image, objects.bbox(i), literal::blue);
+
+ // Computing mass centers.
+ mln::util::array<mln_result(accu::center<mln_psite(I)>)>
+ mass_centers = labeling::compute(accu::meta::center(),
+ objects, objects.nlabels());
+
+ for (unsigned i = 1; i < links.size(); ++i)
+ {
+
+ if (links[i] != i)
+ {
+ value::rgb8 value = literal::green;
+ if (links[i] != filtered_links[i])
+ value = literal::red;
+
+ mln_site(I)
+ p1 = mass_centers[i],
+ p2 = p1 + mln::right; // FIXME: not generic
+
+ while (objects(p2) != links[i] && objects.domain().has(p2))
+ ++p2.col();
+
+ mln::draw::line(links_decision_image,
+ p1,
+ p2,
+ value);
+ }
+ }
+
+ trace::exiting("scribo::debug::links_decision_image");
+ return links_decision_image;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::debug
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEBUG_LINKS_DECISION_IMAGE_HH
diff --git a/scribo/debug/save_object_diff.hh b/scribo/debug/save_object_diff.hh
new file mode 100644
index 0000000..e4f49f4
--- /dev/null
+++ b/scribo/debug/save_object_diff.hh
@@ -0,0 +1,98 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEBUG_SAVE_OBJECT_DIFF_HH
+# define SCRIBO_DEBUG_SAVE_OBJECT_DIFF_HH
+
+/// \file
+///
+/// Show the difference between two object images.
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/concept/image.hh>
+# include <mln/data/fill.hh>
+# include <mln/labeling/colorize.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/io/ppm/save.hh>
+# include <mln/literal/black.hh>
+# include <mln/literal/colors.hh>
+# include <mln/pw/all.hh>
+# include <mln/core/image/dmorph/image_if.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_image.hh>
+
+namespace scribo
+{
+
+ namespace debug
+ {
+
+ using namespace mln;
+
+ /*! \brief Show the difference between two object images.
+
+ \param[in] lbl An object image.
+ \param[in] lbl_2 Another object image.
+ \param[in] filename The output filename.
+
+ */
+ template <typename L, typename L2>
+ void
+ save_object_diff(const object_image(L)& lbl, const object_image(L2)& lbl_2,
+ const std::string& filename);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L, typename L2>
+ void
+ save_object_diff(const object_image(L)& lbl, const object_image(L2)& lbl_2,
+ const std::string& filename)
+ {
+ image2d<value::rgb8> output;
+ initialize(output, lbl_2);
+
+ data::fill(output, literal::black);
+
+ for_all_components(i, lbl.bboxes())
+ data::fill(((output | lbl.bbox(i)).rw() | (pw::value(lbl) == i)).rw(), literal::red);
+
+ for_all_components(i, lbl_2.bboxes())
+ data::fill(((output | lbl_2.bbox(i)).rw() | (pw::value(lbl_2) == i)).rw(), literal::green);
+
+ io::ppm::save(output, filename);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::debug
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_DEBUG_SAVE_OBJECT_DIFF_HH
diff --git a/scribo/debug/several_links_decision_image.hh b/scribo/debug/several_links_decision_image.hh
new file mode 100644
index 0000000..ca70d44
--- /dev/null
+++ b/scribo/debug/several_links_decision_image.hh
@@ -0,0 +1,185 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEBUG_SEVERAL_LINKS_DECISION_IMAGE_HH
+# define SCRIBO_DEBUG_SEVERAL_LINKS_DECISION_IMAGE_HH
+
+/// \file
+///
+/// Save a color image showing the difference between to object groups.
+
+# include <mln/core/concept/image.hh>
+# include <mln/accu/center.hh>
+# include <mln/data/convert.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/literal/colors.hh>
+# include <mln/util/array.hh>
+
+# include <scribo/core/object_groups.hh>
+# include <scribo/draw/bounding_boxes.hh>
+
+
+namespace scribo
+{
+
+ namespace debug
+ {
+
+ using namespace mln;
+
+ /// FIXME: DOC!
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ several_links_decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+
+ namespace internal
+ {
+
+ template <typename L, typename I>
+ bool
+ draw_line(const L& objects, I& output,
+ unsigned link,
+ const mln_site(L)& p1, const mln_site(L)& p2,
+ const mln_value(I)& value)
+ {
+
+ if (objects.domain().has(p2))
+ if (objects(p2) == link)
+ {
+ mln::draw::line(output, p1, p2, value);
+ return true;
+ }
+ return false;
+ }
+
+ }
+
+
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ several_links_decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links)
+ {
+ trace::entering("scribo::debug::several_links_decision_image");
+ const I& input = exact(input_);
+
+ const object_image(L)& objects = links.object_image_();
+
+ mln_precondition(input.is_valid());
+ mln_precondition(objects.is_valid());
+ mln_precondition(links.is_valid());
+ mln_precondition(filtered_links.is_valid());
+ mln_precondition(links.size() == filtered_links.size());
+ mln_precondition(links.object_image_() != filtered_links.object_image_());
+ /// Fixme: check that objects has been computed from input.
+
+ image2d<value::rgb8>
+ links_decision_image = data::convert(value::rgb8(), input);
+
+ for_all_components(i, objects.bboxes())
+ mln::draw::box(links_decision_image, objects.bbox(i), literal::blue);
+
+ // Computing mass centers.
+ mln::util::array<mln_result(accu::center<mln_psite(I)>)>
+ mass_centers = labeling::compute(accu::meta::center(),
+ objects, objects.nlabels());
+
+ for (unsigned i = 1; i < links.size(); ++i)
+ {
+
+ if (links[i] != i)
+ {
+ value::rgb8 value = literal::green;
+ if (links[i] != filtered_links[i])
+ value = literal::red;
+
+ mln_site(L) c = objects.bbox(i).center();
+
+ // Right link from the top anchor.
+ mln_site(L) a1 = c;
+ a1.row() = objects.bbox(i).pmin().row()
+ + (c.row() - objects.bbox(i).pmin().row()) / 4;
+
+ // Right link from the central site
+ mln_site(I) p1 = mass_centers[i];
+
+ // Right link from the bottom anchor.
+ mln_site(L) a2 = c;
+ a2.row() = objects.bbox(i).pmax().row()
+ - (c.row() - objects.bbox(i).pmin().row()) / 4;
+
+ mln_site(L)
+ a1_bak = a1,
+ a2_bak = a2;
+
+ mln_site(L) tmp;
+ while(objects.domain().has(a1)
+ || objects.domain().has(a2)
+ || objects.domain().has(p1))
+ {
+ if (internal::draw_line(objects, links_decision_image, links[i],
+ a1_bak, a1, value))
+ break;
+ else
+ ++a1.col();
+
+ if (internal::draw_line(objects, links_decision_image, links[i],
+ mass_centers[i], p1, value))
+ break;
+ else
+ ++p1.col();
+
+ if (internal::draw_line(objects, links_decision_image, links[i],
+ a2_bak, a2, value))
+ break;
+ else
+ ++a2.col();
+
+ }
+ }
+ }
+
+ trace::exiting("scribo::debug::several_links_decision_image");
+ return links_decision_image;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::debug
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEBUG_SEVERAL_LINKS_DECISION_IMAGE_HH
--
1.5.6.5
1
0
* binarization/sauvola.hh: Revamp and now returns a threshold
image. Move parts...
* binarization/sauvola_threshold.hh: ... here. New file.
* binarization/binarize.hh: New routine.
---
scribo/ChangeLog | 11 +
scribo/binarization/binarize.hh | 180 +++++++++++
scribo/binarization/sauvola.hh | 307 ++++++--------------
scribo/binarization/sauvola_threshold.hh | 478 ++++++++++++++++++++++++++++++
4 files changed, 753 insertions(+), 223 deletions(-)
create mode 100644 scribo/binarization/binarize.hh
create mode 100644 scribo/binarization/sauvola_threshold.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index f397523..deee412 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,14 @@
+2009-10-22 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Revamp Sauvola binarization.
+
+ * binarization/sauvola.hh: Revamp and now returns a threshold
+ image. Move parts...
+
+ * binarization/sauvola_threshold.hh: ... here. New file.
+
+ * binarization/binarize.hh: New routine.
+
2009-10-12 Roland Levillain <roland(a)lrde.epita.fr>
* headers.mk, tests/unit_test/unit-tests.mk: Regen.
diff --git a/scribo/binarization/binarize.hh b/scribo/binarization/binarize.hh
new file mode 100644
index 0000000..0f323bb
--- /dev/null
+++ b/scribo/binarization/binarize.hh
@@ -0,0 +1,180 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_BINARIZATION_BINARIZE_HH
+# define SCRIBO_BINARIZATION_BINARIZE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/value/concept/vectorial.hh>
+
+/// \file
+///
+/// Binarize an image from a threshold image.
+
+namespace scribo
+{
+
+ using namespace mln;
+
+
+ namespace binarization
+ {
+
+ namespace internal
+ {
+
+ template <typename I, typename T>
+ void
+ binarize_tests(const Image<I>& input, const Image<T>& threshold)
+ {
+ mln_precondition(exact(input).is_valid());
+ mln_precondition(exact(threshold).is_valid());
+ mln_precondition(exact(input).domain() == exact(threshold).domain());
+ mlc_is_not_a(mln_value(I), value::Vectorial)::check();
+ (void) input;
+ (void) threshold;
+ }
+
+ } // end of namespace scribo::binarization::internal
+
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I, typename T>
+ mln_ch_value(I, bool)
+ binarize(const Image<I>& input_, const Image<T>& threshold_)
+ {
+ trace::entering("scribo::binarization::impl::generic::binarize");
+
+ internal::binarize_tests(input_, threshold_);
+
+ const I& input = exact(input_);
+ const T& threshold = exact(threshold_);
+
+ mln_ch_value(I, bool) output;
+ initialize(output, input);
+
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ output(p) = (input(p) <= threshold(p));
+
+
+ trace::exiting("scribo::binarization::impl::generic::binarize");
+ return output;
+ }
+
+
+ } // end of namespace scribo::binarization::impl::generic
+
+
+ template <typename I, typename T>
+ mln_ch_value(I, bool)
+ binarize_fastest(const Image<I>& input_, const Image<T>& threshold_)
+ {
+ trace::entering("scribo::binarization::impl::generic::binarize_fastest");
+ internal::binarize_tests(input_, threshold_);
+
+ const I& input = exact(input_);
+ const T& threshold = exact(threshold_);
+
+ typedef mln_ch_value(I, bool) O;
+ O output;
+ initialize(output, input);
+
+ mln_pixter(const I) pi(input);
+ mln_pixter(const T) pt(threshold);
+ mln_pixter(O) po(output);
+ for_all_3(pi, pt, po)
+ po.val() = pi.val() <= pt.val();
+
+ trace::exiting("scribo::binarization::impl::generic::binarize_fastest");
+ return output;
+ }
+
+
+
+ } // end of namespace scribo::binarization::impl
+
+
+ namespace internal
+ {
+
+ template <typename I, typename T>
+ mln_ch_value(I, bool)
+ binarize_dispatch(trait::image::value_alignment::any,
+ trait::image::speed::any,
+ const Image<I>& input, const Image<T>& threshold)
+ {
+ return impl::generic::binarize(input, threshold);
+ }
+
+
+ template <typename I, typename T>
+ mln_ch_value(I, bool)
+ binarize_dispatch(trait::image::value_alignment::with_grid,
+ trait::image::speed::fastest,
+ const Image<I>& input, const Image<T>& threshold)
+ {
+ return impl::binarize_fastest(input, threshold);
+ }
+
+ template <typename I, typename T>
+ mln_ch_value(I, bool)
+ binarize_dispatch(const Image<I>& input, const Image<T>& threshold)
+ {
+ return binarize_dispatch(mln_trait_image_value_alignment(I)(),
+ mln_trait_image_speed(I)(),
+ exact(input), exact(threshold));
+ }
+
+ } // end of namespace scribo::binarization::internal
+
+
+ template <typename I, typename T>
+ mln_ch_value(I, bool)
+ binarize(const Image<I>& input, const Image<T>& threshold)
+ {
+ trace::entering("scribo::binarization::binarize");
+
+ internal::binarize_tests(input, threshold);
+
+ mln_ch_value(I, bool)
+ output = internal::binarize_dispatch(input, threshold);
+
+ trace::exiting("scribo::binarization::binarize");
+ return output;
+ }
+
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_BINARIZATION_BINARIZE_HH
diff --git a/scribo/binarization/sauvola.hh b/scribo/binarization/sauvola.hh
index b9f78f8..5323847 100644
--- a/scribo/binarization/sauvola.hh
+++ b/scribo/binarization/sauvola.hh
@@ -28,21 +28,15 @@
/// \file
///
-/// Convert an image into a binary image.
-
-# include <algorithm>
-# include <cmath>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/value/rgb8.hh>
-# include <mln/value/int_u.hh>
-# include <mln/value/int_u8.hh>
+///
+# include <mln/core/concept/image.hh>
# include <mln/data/transform.hh>
-# include <mln/pw/all.hh>
-# include <mln/core/routine/duplicate.hh>
-
+# include <mln/value/int_u8.hh>
+# include <mln/value/rgb8.hh>
+# include <scribo/binarization/sauvola_threshold.hh>
+# include <scribo/binarization/binarize.hh>
namespace scribo
@@ -53,104 +47,31 @@ namespace scribo
using namespace mln;
+
/*! \brief Convert an image into a binary image.
- \input[in] An image.
+ \input[in] input An image.
+ \input[in] window_size The window size.
\return A binary image.
*/
template <typename I>
- mln_ch_value(I,bool)
- sauvola(const Image<I>& input);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-
- namespace internal
- {
-
- template <typename T>
- class integral_image
- {
- public:
-
- template<class F>
- integral_image(const image2d<T>& i, F func)
- : img_(0),
- nrows_(i.nrows()),
- ncols_(i.ncols())
- {
- img_ = (unsigned long long**)malloc(sizeof(unsigned long long*) * nrows_);
- for (int n = 0; n < nrows_; ++n)
- img_[n] = (unsigned long long*)malloc(sizeof(unsigned long long) * ncols_);
-
- img_[0][0] = func(i.at_(0, 0));
-
- for (int row = 1; row < nrows_; ++row)
- img_[row][0] = (*this)(row - 1, 0) + func(i.at_(row, 0));
-
- for (int col = 1; col < ncols_; ++col)
- img_[0][col] = (*this)(0, col - 1)
- + func(i.at_(0, col));
-
- for (int row = 1; row < nrows_; ++row)
- for (int col = 1; col < ncols_; ++col)
- img_[row][col] = (*this)(row - 1, col)
- + (*this)(row, col - 1)
- - (*this)(row - 1, col - 1)
- + func(i.at_(row, col));
- }
-
- ~integral_image()
- {
- for (int n = 0; n < nrows_; ++n)
- free(img_[n]);
- free(img_);
- }
-
- unsigned long long operator()(int row, int col) const
- {
- return img_[row][col];
- }
-
- private:
- unsigned long long** img_;
- int nrows_;
- int ncols_;
- };
-
-
- struct rgb8_to_int_u8 : Function_v2v< rgb8_to_int_u8 >
- {
- typedef value::int_u8 result;
- result operator()(const value::rgb8& c) const
- {
- return (c.red() + c.green() + c.blue()) / 3;
- }
- };
-
-
- unsigned long long square_(const value::int_u8& val)
- {
- unsigned long long v = static_cast<unsigned long long>(val);
- return v * v;
- }
-
- unsigned long long identity_(const value::int_u8& val)
- {
- return static_cast<unsigned long long>(val);
- }
-
- } // end of namespace scribo::binarization::internal
+ mln_ch_value(I, bool)
+ sauvola(const Image<I>& input, unsigned window_size);
+ /// \overload
+ /// The window size is set to 11.
+ //
+ template <typename I>
+ mln_ch_value(I, bool)
+ sauvola(const Image<I>& input);
- // Implementation
+# ifndef MLN_INCLUDE_ONLY
+ // Implementations.
namespace impl
{
@@ -159,73 +80,16 @@ namespace scribo
{
template <typename I>
- inline
mln_ch_value(I, bool)
- sauvola(const I& input)
+ sauvola(const Image<I>& input, unsigned window_size)
{
trace::entering("scribo::binarization::impl::generic::sauvola");
+ mln_precondition(exact(input).is_valid());
- typedef mln_value(I) V;
-
- // Value of the window size
- const unsigned int w = 11;
-
- // Control the threshold value in the local window
- // The higher, the lower the threshold form the local
- // mean m(x, y). Badekas et al. said 0.34 was best.
- const double k = 0.34;
-
- // Maximum value of the standard deviation (128 for
- // grayscale documents).
- const double R = 128;
-
- // Compute the sum of all intensities of input
- internal::integral_image<V> simple(input, internal::identity_);
-
- // Compute the sum of all squared intensities of input
- internal::integral_image<V> squared(input, internal::square_);
-
- int w_2 = w >> 1;
-
- // Savaula Algorithm with I.I.
-
- image2d<bool> output;
- initialize(output, input);
-
- const def::coord nrows = static_cast<def::coord>(input.nrows());
- const def::coord ncols = static_cast<def::coord>(input.ncols());
-
- for(def::coord row = 0; row < nrows; ++row)
- for(def::coord col = 0; col < ncols; ++col)
- {
- int row_min = std::max(0, row - w_2);
- int col_min = std::max(0, col - w_2);
- int row_max = std::min(nrows - 1, row + w_2);
- int col_max = std::min(ncols - 1, col + w_2);
-
- double wh = (row_max - row_min + 1) * (col_max - col_min + 1);
-
- // Mean.
- double m_x_y_tmp = (simple(row_max, col_max)
- + simple(row_min, col_min)
- - simple(row_max, col_min)
- - simple(row_min, col_max));
-
- double m_x_y = m_x_y_tmp / wh;
-
- // Standard deviation.
- double s_x_y_tmp = (squared(row_max, col_max)
- + squared(row_min, col_min)
- - squared(row_max, col_min)
- - squared(row_min, col_max));
-
- double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f));
-
- // Thresholding.
- double t_x_y = m_x_y * (1.0 + k * ((s_x_y / R) - 1.0));
-
- output.at_(row, col) = (input.at_(row, col) < t_x_y);
- }
+ mln_ch_value(I, bool)
+ output = binarize(input,
+ binarization::sauvola_threshold(input,
+ window_size));
trace::exiting("scribo::binarization::impl::generic::sauvola");
return output;
@@ -234,98 +98,95 @@ namespace scribo
} // end of namespace scribo::binarization::impl::generic
- template <typename I>
- inline
- mln_ch_value(I, bool)
- sauvola_gl(const I& input)
- {
- return impl::generic::sauvola(input);
- }
+ template <typename I>
+ mln_ch_value(I, bool)
+ sauvola_rgb8(const Image<I>& input, unsigned window_size)
+ {
+ trace::entering("scribo::binarization::impl::generic::sauvola");
+ mln_precondition(exact(input).is_valid());
+ mln_ch_value(I, value::int_u8) gima;
+ gima = data::transform(input, internal::rgb8_to_int_u8());
- template <typename I>
- inline
mln_ch_value(I, bool)
- sauvola_rgb8(const I& input)
- {
- trace::entering("scribo::binarization::impl::sauvola_rgb8");
+ output = binarize(gima,
+ binarization::sauvola_threshold(gima,
+ window_size));
- mln_ch_value(I, value::int_u8) gima;
- gima = data::transform(input,
- internal::rgb8_to_int_u8());
+ trace::exiting("scribo::binarization::impl::generic::sauvola");
+ return output;
+ }
- mln_ch_value(I, bool) output = impl::generic::sauvola(gima);
+ } // end of namespace scribo::binarization::impl
- trace::exiting("scribo::binarization::impl::sauvola_rgb8");
- return output;
- }
- } // end of namespace scribo::binarization::impl
+ // Dispatch
+ namespace internal
+ {
+ template <typename I>
+ mln_ch_value(I, bool)
+ sauvola_dispatch(const mln_value(I)&,
+ const Image<I>& input, unsigned window_size)
+ {
+ return impl::generic::sauvola(input, window_size);
+ }
+ template <typename I>
+ mln_ch_value(I, bool)
+ sauvola_dispatch(const value::rgb8&,
+ const Image<I>& input, unsigned window_size)
+ {
+ return impl::sauvola_rgb8(input, window_size);
+ }
- // Dispatch
- namespace internal
+ template <typename I>
+ mln_ch_value(I, bool)
+ sauvola_dispatch(const Image<I>& input, unsigned window_size)
{
+ typedef mln_value(I) V;
+ return sauvola_dispatch(V(), input, window_size);
+ }
- template <typename I, unsigned n>
- inline
- mln_ch_value(I, bool)
- sauvola_dispatch(const value::int_u<n>&, const I& input)
- {
- return impl::sauvola_gl(input);
- }
-
- template <typename I>
- inline
- mln_ch_value(I, bool)
- sauvola_dispatch(const value::rgb8&, const I& input)
- {
- return impl::sauvola_rgb8(input);
- }
+ } // end of namespace scribo::binarization::internal
- template <typename I>
- inline
- mln_ch_value(I, bool)
- sauvola_dispatch(const mln_value(I)&, const I& input)
- {
- // No dispatch for this kind of value type.
- mlc_abort(I)::check();
- typedef mln_ch_value(I,bool) output_t;
- return output_t();
- }
+ // Facades
- } // end of namespace scribo::binarization::internal
+ template <typename I>
+ mln_ch_value(I, bool)
+ sauvola(const Image<I>& input, unsigned window_size)
+ {
+ trace::entering("scribo::binarization::sauvola");
+ mln_precondition(exact(input).is_valid());
- template <typename I>
- inline
mln_ch_value(I, bool)
- sauvola(const Image<I>& input)
- {
- trace::entering("scribo::binarization::sauvola");
+ output = internal::sauvola_dispatch(input, window_size);
- mln_precondition(mln_site_(I)::dim == 2);
- mln_precondition(exact(input).is_valid());
+ trace::exiting("scribo::binarization::sauvola");
+ return output;
+ }
- typedef mln_value(I) value_t;
- mln_ch_value(I, bool)
- output = internal::sauvola_dispatch(value_t(), exact(input));
- trace::exiting("scribo::text::ppm2pbm");
- return output;
- }
+ template <typename I>
+ mln_ch_value(I, bool)
+ sauvola(const Image<I>& input)
+ {
+ return sauvola(input, 11);
+ }
+
# endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace scribo::binarization
} // end of namespace scribo
-#endif // ! SCRIBO_TEXT_PPM2PBM_HH
+#endif // ! SCRIBO_BINARIZATION_SAUVOLA_HH
diff --git a/scribo/binarization/sauvola_threshold.hh b/scribo/binarization/sauvola_threshold.hh
new file mode 100644
index 0000000..9a9e439
--- /dev/null
+++ b/scribo/binarization/sauvola_threshold.hh
@@ -0,0 +1,478 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_HH
+# define SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_HH
+
+/// \file
+///
+/// Convert an image into a binary image.
+
+/// \fixme return type too restrictive!
+
+# include <algorithm>
+# include <cmath>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/value/int_u.hh>
+# include <mln/value/int_u8.hh>
+
+# include <mln/data/transform.hh>
+# include <mln/pw/all.hh>
+# include <mln/core/routine/duplicate.hh>
+
+
+// Forward declaration.
+namespace mln { template <typename T> class integral_image; }
+
+
+namespace scribo
+{
+
+ namespace binarization
+ {
+
+ using namespace mln;
+
+ /*! \brief Compute a threshold image with Sauvola's algorithm.
+
+ \input[in] input An image.
+ \input[in] window_size The window size.x
+ \input[out] simple The sum of all intensities of \p input.
+ \input[out] squared The sum of all squared intensities of \p
+ input.
+
+ \return An image of local thresholds.
+
+ */
+ template <typename I, typename T>
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input, unsigned window_size,
+ integral_image<T>& simple,
+ integral_image<T>& squared);
+
+
+ /// \overload
+ template <typename I>
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input, unsigned window_size);
+
+
+ /// \overload
+ /// The window size is set to 11.
+ //
+ template <typename I>
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+ struct rgb8_to_int_u8 : Function_v2v< rgb8_to_int_u8 >
+ {
+ typedef value::int_u8 result;
+ result operator()(const value::rgb8& c) const
+ {
+ return (c.red() + c.green() + c.blue()) / 3;
+ }
+ };
+
+
+ unsigned long long square_(const value::int_u8& val)
+ {
+ unsigned long long v = static_cast<unsigned long long>(val);
+ return v * v;
+ }
+
+ unsigned long long identity_(const value::int_u8& val)
+ {
+ return static_cast<unsigned long long>(val);
+ }
+
+
+ /// \brief Compute a point wise threshold according Sauvola's
+ /// binarization.
+ ///
+ /// \param[in] p A site.
+ /// \param[in] simple An integral image of mean values.
+ /// \param[in] squared An integral image of squared mean values.
+ /// \param[in] win_width Window width.
+ /// \param[in] k Control the threshold value in the local
+ /// window. The higher, the lower the threshold
+ /// form the local mean m(x, y).
+ /// \param[in] R Maximum value of the standard deviation (128
+ /// for grayscale documents).
+
+ template <typename P, typename T>
+ double
+ compute_sauvola_threshold(const P& p,
+ const integral_image<T>& simple,
+ const integral_image<T>& squared,
+ int win_width, double k, double R)
+ {
+ mln_precondition(simple.nrows() == squared.nrows());
+ mln_precondition(simple.ncols() == squared.ncols());
+
+ // Window half width.
+ int w_2 = win_width >> 1;
+
+ int row_min = std::max(0, p.row() - w_2);
+ int col_min = std::max(0, p.col() - w_2);
+ int row_max = std::min(simple.nrows() - 1, p.row() + w_2);
+ int col_max = std::min(simple.ncols() - 1, p.col() + w_2);
+
+ double wh = (row_max - row_min + 1) * (col_max - col_min + 1);
+
+ // Mean.
+ double m_x_y_tmp = (simple(row_max, col_max)
+ + simple(row_min, col_min)
+ - simple(row_max, col_min)
+ - simple(row_min, col_max));
+
+ double m_x_y = m_x_y_tmp / wh;
+
+ // Standard deviation.
+ double s_x_y_tmp = (squared(row_max, col_max)
+ + squared(row_min, col_min)
+ - squared(row_max, col_min)
+ - squared(row_min, col_max));
+
+ double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f));
+
+ // Thresholding.
+ double t_x_y = m_x_y * (1.0 + k * ((s_x_y / R) - 1.0));
+
+ return t_x_y;
+ }
+
+
+ template <typename P, typename T>
+ double
+ compute_sauvola_threshold(const P& p,
+ const integral_image<T>& simple,
+ const integral_image<T>& squared,
+ int win_width)
+ {
+ // Badekas et al. said 0.34 was best.
+ const double k = 0.34;
+
+ // 128 is best for grayscale documents.
+ const double R = 128;
+
+ return compute_sauvola_threshold(p, simple, squared, win_width, k, R);
+ }
+
+
+ } // end of namespace scribo::binarization::internal
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+
+namespace mln
+{
+
+ template <typename T>
+ class integral_image
+ {
+ public:
+
+ integral_image()
+ : img_(0), nrows_(0), ncols_(0)
+ {}
+
+ template<class F>
+ integral_image(const image2d<T>& i, F func)
+ : img_(0),
+ nrows_(0),
+ ncols_(0)
+ {
+ init_(i, func);
+ }
+
+ template<class F>
+ void init_(const image2d<T>& i, F func)
+ {
+ nrows_ = i.nrows();
+ ncols_ = i.ncols();
+
+ img_ = (unsigned long long**)malloc(sizeof(unsigned long long*) * nrows_);
+ for (int n = 0; n < nrows_; ++n)
+ img_[n] = (unsigned long long*)malloc(sizeof(unsigned long long) * ncols_);
+
+ img_[0][0] = func(i.at_(0, 0));
+
+ for (int row = 1; row < nrows_; ++row)
+ img_[row][0] = (*this)(row - 1, 0) + func(i.at_(row, 0));
+
+ for (int col = 1; col < ncols_; ++col)
+ img_[0][col] = (*this)(0, col - 1)
+ + func(i.at_(0, col));
+
+ for (int row = 1; row < nrows_; ++row)
+ for (int col = 1; col < ncols_; ++col)
+ img_[row][col] = (*this)(row - 1, col)
+ + (*this)(row, col - 1)
+ - (*this)(row - 1, col - 1)
+ + func(i.at_(row, col));
+ }
+
+
+ ~integral_image()
+ {
+ for (int n = 0; n < nrows_; ++n)
+ free(img_[n]);
+ free(img_);
+ }
+
+ bool is_valid() const
+ {
+ return img_ != 0;
+ }
+
+ unsigned long long operator()(int row, int col) const
+ {
+ return img_[row][col];
+ }
+
+ int nrows() const
+ {
+ return nrows_;
+ }
+
+ int ncols() const
+ {
+ return ncols_;
+ }
+
+
+ private:
+ unsigned long long** img_;
+ int nrows_;
+ int ncols_;
+ };
+
+} // end of namespace mln
+
+
+
+namespace scribo
+{
+
+ namespace binarization
+ {
+
+ // Implementation
+
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I, typename T>
+ inline
+ mln_concrete(I)
+ sauvola_threshold(const I& input, unsigned window_size,
+ integral_image<T>& simple,
+ integral_image<T>& squared)
+ {
+ trace::entering("scribo::binarization::impl::generic::sauvola_threshold");
+
+ typedef mln_value(I) V;
+ typedef mln_site(I) P;
+
+ // Compute the sum of all intensities of input
+ simple.init_(input, internal::identity_);
+
+ // Compute the sum of all squared intensities of input
+ squared.init_(input, internal::square_);
+
+ // Savaula Algorithm with I.I.
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ const def::coord nrows = static_cast<def::coord>(input.nrows());
+ const def::coord ncols = static_cast<def::coord>(input.ncols());
+
+ for(def::coord row = 0; row < nrows; ++row)
+ for(def::coord col = 0; col < ncols; ++col)
+ output.at_(row, col)
+ = internal::compute_sauvola_threshold(P(row, col), simple,
+ squared, window_size);
+
+ trace::exiting("scribo::binarization::impl::generic::sauvola_threshold");
+ return output;
+ }
+
+ } // end of namespace scribo::binarization::impl::generic
+
+
+
+ template <typename I, typename T>
+ inline
+ mln_concrete(I)
+ sauvola_threshold_gl(const I& input, unsigned window_size,
+ integral_image<T>& simple,
+ integral_image<T>& squared)
+ {
+ return impl::generic::sauvola_threshold(input, window_size,
+ simple, squared);
+ }
+
+
+ template <typename I, typename T>
+ inline
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold_rgb8(const I& input, unsigned window_size,
+ integral_image<T>& simple,
+ integral_image<T>& squared)
+ {
+ trace::entering("scribo::binarization::impl::sauvola_threshold_rgb8");
+
+ mln_ch_value(I, value::int_u8) gima;
+ gima = data::transform(input,
+ internal::rgb8_to_int_u8());
+
+ mln_ch_value(I, value::int_u8)
+ output = impl::generic::sauvola_threshold(gima, window_size,
+ simple, squared);
+
+ trace::exiting("scribo::binarization::impl::sauvola_threshold_rgb8");
+ return output;
+ }
+
+
+ } // end of namespace scribo::binarization::impl
+
+
+
+
+ // Dispatch
+
+ namespace internal
+ {
+
+ template <unsigned n, typename I, typename T>
+ inline
+ mln_ch_value(I, value::int_u<n>)
+ sauvola_threshold_dispatch(const value::int_u<n>&, const I& input,
+ unsigned window_size,
+ integral_image<T>& simple,
+ integral_image<T>& squared)
+ {
+ return impl::sauvola_threshold_gl(input, window_size, simple, squared);
+ }
+
+ template <typename I, typename T>
+ inline
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold_dispatch(const value::rgb8&, const I& input,
+ unsigned window_size,
+ integral_image<T>& simple,
+ integral_image<T>& squared)
+ {
+ return impl::sauvola_threshold_rgb8(input, window_size,
+ simple, squared);
+ }
+
+ template <typename I, typename T>
+ inline
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold_dispatch(const mln_value(I)&, const I& input,
+ unsigned window_size,
+ integral_image<T>& simple,
+ integral_image<T>& squared)
+ {
+ // No dispatch for this kind of value type.
+ mlc_abort(I)::check();
+
+ typedef mln_ch_value(I,bool) output_t;
+ return output_t();
+ }
+
+
+ } // end of namespace scribo::binarization::internal
+
+
+
+ template <typename I, typename T>
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input, unsigned window_size,
+ integral_image<T>& simple,
+ integral_image<T>& squared)
+ {
+ trace::entering("scribo::binarization::sauvola_threshold");
+
+ mln_precondition(mln_site_(I)::dim == 2);
+ mln_precondition(exact(input).is_valid());
+
+ typedef mln_value(I) value_t;
+ mln_ch_value(I, value::int_u8)
+ output = internal::sauvola_threshold_dispatch(value_t(), exact(input),
+ window_size, simple,
+ squared);
+
+ trace::exiting("scribo::text::ppm2pbm");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input, unsigned window_size)
+ {
+ mln::integral_image<value::int_u8> simple, squared;
+ return sauvola_threshold(input, window_size, simple, squared);
+ }
+
+
+ template <typename I>
+ inline
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input)
+ {
+ return sauvola_threshold(input, 11);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_HH
--
1.5.6.5
1
0