It seems ESIEE's mail server is preventing me from sending this
message today. So I'm sending it by hand. Hope it won't look too
much ugly, given the fact I'm sending it with Apple Mail (no troll
intended).
Hope ESIEE's mail server will return to a sound behavior soon, too...
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add a new test on WST-based segmentation on a line graph image.
* tests/core/lena_line_graph_image_wst.cc: Rename and move...
* tests/morpho/lena_line_graph_image_wst1.cc: ...here.
Add more documentation.
Remove dead code.
* tests/morpho/lena_line_graph_image_wst2.cc: New test.
Based on tests/morpho/lena_line_graph_image_wst1.cc.
* tests/core/Makefile.am (check_PROGRAMS): Remove
lena_line_graph_image_wst.
(lena_line_graph_image_wst_SOURCES)
(lena_line_graph_image_wst_CXXFLAGS):
Remove.
* tests/morpho/Makefile.am (check_PROGRAMS): Add
lena_line_graph_image_wst1 and lena_line_graph_image_wst2.
(CXXFLAGS_SPEED): New.
Use it...
(meyer_wst_long_CXXFLAGS): ...here.
(lena_line_graph_image_wst1_SOURCES)
(lena_line_graph_image_wst1_CXXFLAGS)
(lena_line_graph_image_wst2_SOURCES)
(lena_line_graph_image_wst2_CXXFLAGS):
New.
* mln/core/line_graph_image.hh: More FIXME.
* tests/morpho/hit_or_miss.cc, tests/morpho/meyer_wst_long.cc:
Remove unnecessary #include's.
mln/core/line_graph_image.hh | 4 +
tests/core/Makefile.am | 5 -
tests/morpho/Makefile.am | 13 +++-
tests/morpho/hit_or_miss.cc | 1
tests/morpho/lena_line_graph_image_wst1.cc | 28 ++++++---
tests/morpho/lena_line_graph_image_wst2.cc | 84 +++++++++++++++++++
+---------
tests/morpho/meyer_wst_long.cc | 2
7 files changed, 94 insertions(+), 43 deletions(-)
Index: tests/morpho/lena_line_graph_image_wst1.cc
--- tests/morpho/lena_line_graph_image_wst1.cc (revision 1736)
+++ tests/morpho/lena_line_graph_image_wst1.cc (working copy)
@@ -25,8 +25,26 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/// \file tests/core/line_graph_image.cc
-/// \brief Tests on the Watershed Transform on a mln::line_graph_image.
+/* FIXME: We should factor as much things as possible between
+ tests/core/lena_line_graph_image_wst1.cc and
+ tests/core/lena_line_graph_image_wst2.cc, starting from conversion
+ routines. */
+
+/** \file tests/core/lena_line_graph_image_wst1.cc
+ \brief Tests on the Watershed Transform (WST) on a
mln::line_graph_image.
+
+ The scenario is as follows:
+ \li load a 2-D, gray-level image from a PGM file;
+ \li compute a morphological gradient of this image;
+ \li simplify the image to reduce the number of local minima;
+ \li convert this 2-D image into a line graph-based one, where
values
+ on edges are computed as the maxmimum of the values on the
nodes
+ adjacent to the edge;
+ \li perform a WST on the line graph image;
+ \li create an 2-D, color output image with height and width double
+ the size the original one, and copy the data of the input image
+ in it, interpolating inter-pixel points;
+ \li print the watershed on lines into that same image, and save
it. */
#include <vector>
@@ -44,7 +62,6 @@
#include <mln/morpho/meyer_wst.hh>
#include <mln/value/int_u8.hh>
-// #include <mln/value/int_u16.hh>
#include <mln/value/rgb8.hh>
#include <mln/literal/black.hh>
#include <mln/literal/colors.hh>
@@ -63,7 +80,6 @@
{
using namespace mln;
using value::int_u8;
-// using value::int_u16;
using value::rgb8;
/*--------.
@@ -72,7 +88,6 @@
typedef int_u8 input_val_t;
image2d<input_val_t> input;
-// io::pgm::load(input, MLN_IMG_DIR "/small.pgm");
io::pgm::load(input, MLN_IMG_DIR "/tiny.pgm");
/* FIXME: Don't compute a gradient on the image2d input. Instead,
@@ -85,7 +100,6 @@
// Simplify the input image.
image2d<input_val_t> work(input.domain());
-// morpho::closing_area(gradient, c4(), 50, work);
morpho::closing_area(gradient, c4(), 10, work);
/*-------------.
@@ -128,7 +142,6 @@
if (work.has(q))
{
g.add_edge(points[p], points[q]);
- // FIXME: Keep this valuation function?
edge_values.push_back(math::max(work(p), work(q)));
}
@@ -183,7 +196,6 @@
}
// Interpolate missing points in OUTPUT.
mln_piter_(output_t) p_out(output.domain());
-// mln_niter_(neighb2d) n_out(c4(), p_out);
for_all(p_out)
{
// Process points on even rows and odd columns
Index: tests/morpho/lena_line_graph_image_wst2.cc
--- tests/morpho/lena_line_graph_image_wst2.cc (revision 1736)
+++ tests/morpho/lena_line_graph_image_wst2.cc (working copy)
@@ -25,8 +25,32 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/// \file tests/core/line_graph_image.cc
-/// \brief Tests on the Watershed Transform on a mln::line_graph_image.
+/* FIXME: We should factor as much things as possible between
+ tests/core/lena_line_graph_image_wst1.cc and
+ tests/core/lena_line_graph_image_wst2.cc, starting from conversion
+ routines. */
+
+/** \file tests/core/lena_line_graph_image_wst2.cc
+ \brief More tests on the Watershed Transform (WST) on a
+ mln::line_graph_image.
+
+
+ The scenario is as follows:
+ \li load a 2-D, gray-level image from a PGM file;
+ \li simplify the image to reduce the number of local minima;
+ \li convert this 2-D image into a line graph-based one, where
values
+ on edges are computed as the absolute value f the difference
+ between the values on the nodes adjacent to the edge, so as to
+ create a (norm of the gradient) ``between the pixels'' of the
+ input image;
+ \li (insert an minima-killer pass here, as soon as it works on
+ graph-based images);
+ \li perform a WST on the line graph image;
+ \li reduce the quantification of the result of the WST;
+ \li create an 2-D, color output image with height and width double
+ the size the original one, and copy the data of the input image
+ in it, interpolating inter-pixel points;
+ \li print the watershed on lines into that same image, and save
it. */
#include <vector>
@@ -42,9 +66,10 @@
#include <mln/morpho/gradient.hh>
#include <mln/morpho/closing_area.hh>
#include <mln/morpho/meyer_wst.hh>
+#include <mln/level/stretch.hh>
#include <mln/value/int_u8.hh>
-// #include <mln/value/int_u16.hh>
+#include <mln/value/int_u16.hh>
#include <mln/value/rgb8.hh>
#include <mln/literal/black.hh>
#include <mln/literal/colors.hh>
@@ -63,7 +88,7 @@
{
using namespace mln;
using value::int_u8;
-// using value::int_u16;
+ using value::int_u16;
using value::rgb8;
/*--------.
@@ -72,21 +97,15 @@
typedef int_u8 input_val_t;
image2d<input_val_t> input;
-// io::pgm::load(input, MLN_IMG_DIR "/small.pgm");
- io::pgm::load(input, MLN_IMG_DIR "/tiny.pgm");
+ io::pgm::load(input, MLN_IMG_DIR "/small.pgm");
- /* FIXME: Don't compute a gradient on the image2d input. Instead,
- have the values of the line graph image /behaves/ as the gradient
- of the input, i.e., edges should hold the absolute difference
- between gray levels.
- */
- image2d<input_val_t> gradient =
- morpho::gradient (input, convert::to_window(c4()));
+ /* FIXME: In fact, we'd probably want to compute the gradient
+ /before/ simplfying the image, but as the area closing doesn't
+ work (yet) on graph images, hence we cannot do this yet. */
// Simplify the input image.
image2d<input_val_t> work(input.domain());
-// morpho::closing_area(gradient, c4(), 50, work);
- morpho::closing_area(gradient, c4(), 10, work);
+ morpho::closing_area(input, c8(), 500, work);
/*-------------.
| Line graph. |
@@ -105,7 +124,7 @@
util::node_id id = 0;
// Nodes.
- std::vector<int> node_values;
+ std::vector<input_val_t> node_values;
mln_fwd_piter_(image2d<input_val_t>) p(work.domain());
for_all (p)
{
@@ -121,26 +140,32 @@
// Edges.
window2d next_c4_win;
next_c4_win.insert(0, 1).insert(1, 0);
- std::vector<int> edge_values;
+ std::vector<input_val_t> edge_values;
mln_fwd_qiter_(window2d) q(next_c4_win, p);
for_all (p)
for_all (q)
if (work.has(q))
{
g.add_edge(points[p], points[q]);
- // FIXME: Keep this valuation function?
- edge_values.push_back(math::max(work(p), work(q)));
+ // The computed value is a kind of norm of the gradient
+ // bewteen P and Q.
+ edge_values.push_back(math::abs(work(p) - work(q)));
}
// Line graph point set.
p_line_graph<point2d> plg(g);
// Line graph image.
- /* FIXME: Shouldn't we use `input_val_t' instead of plain `int' as
value
- type here? */
- typedef line_graph_image<point2d, int> ima_t;
+ typedef line_graph_image<point2d, input_val_t> ima_t;
ima_t lg_ima(plg, node_values, edge_values);
+ /*-----------------.
+ | Simplification. |
+ `-----------------*/
+
+ // FIXME: Adjust the area closing filter, so that we can apply it on
+ // graph images.
+
/*------.
| WST. |
`------*/
@@ -149,11 +174,20 @@
nbh_t nbh;
// Perform a Watershed Transform.
+ typedef int_u16 wst_full_val_t;
+ wst_full_val_t nbasins;
+ typedef line_graph_image<point2d, wst_full_val_t> wst_full_ima_t;
+ wst_full_ima_t wshed_full = morpho::meyer_wst(lg_ima, nbh, nbasins);
+ std::cout << "nbasins = " << nbasins << std::endl;
+
+ // Reduce the value set to 8-bit.
typedef int_u8 wst_val_t;
- wst_val_t nbasins;
typedef line_graph_image<point2d, wst_val_t> wst_ima_t;
- wst_ima_t wshed = morpho::meyer_wst(lg_ima, nbh, nbasins);
- std::cout << "nbasins = " << nbasins << std::endl;
+ // FIXME: Initializations should not be that complicated.
+ wst_ima_t wshed (plg,
+ std::vector<wst_val_t>(node_values.size()),
+ std::vector<wst_val_t>(edge_values.size()));
+ level::stretch(wshed_full, wshed);
/*---------.
| Output. |
Index: tests/core/Makefile.am
--- tests/core/Makefile.am (revision 1736)
+++ tests/core/Makefile.am (working copy)
@@ -10,7 +10,6 @@
initialize \
graph_elt_window \
graph_image \
- lena_line_graph_image_wst \
line_graph_elt_window \
line_graph_image \
line_graph_image_wst \
@@ -52,8 +51,4 @@
t_image_SOURCES = t_image.cc
tr_image_SOURCES = tr_image.cc
-# FIXME: We should isolate this test, as it takes a long time.
-lena_line_graph_image_wst_SOURCES = lena_line_graph_image_wst.cc
-lena_line_graph_image_wst_CXXFLAGS = -O3 -ggdb
-
TESTS = $(check_PROGRAMS)
Index: tests/morpho/Makefile.am
--- tests/morpho/Makefile.am (revision 1736)
+++ tests/morpho/Makefile.am (working copy)
@@ -12,6 +12,8 @@
gradient \
hit_or_miss \
laplacian \
+ lena_line_graph_image_wst1 \
+ lena_line_graph_image_wst2 \
meyer_wst \
meyer_wst_long \
opening_area \
@@ -33,8 +35,15 @@
thinning_SOURCES = thinning.cc
meyer_wst_SOURCES = meyer_wst.cc
-# FIXME: We should isolate this test, as it takes a long time.
+
+# FIXME: We should isolate those tests, as they take a long time to
+# execute.
+CXXFLAGS_SPEED = -O3 -ggdb
+lena_line_graph_image_wst1_SOURCES = lena_line_graph_image_wst1.cc
+lena_line_graph_image_wst1_CXXFLAGS = $(CXXFLAGS_SPEED)
+lena_line_graph_image_wst2_SOURCES = lena_line_graph_image_wst2.cc
+lena_line_graph_image_wst2_CXXFLAGS = $(CXXFLAGS_SPEED)
meyer_wst_long_SOURCES = meyer_wst_long.cc
-meyer_wst_long_CXXFLAGS = -O3 -ggdb
+meyer_wst_long_CXXFLAGS = $(CXXFLAGS_SPEED)
TESTS = $(check_PROGRAMS)
Index: mln/core/line_graph_image.hh
--- mln/core/line_graph_image.hh (revision 1736)
+++ mln/core/line_graph_image.hh (working copy)
@@ -191,6 +191,10 @@
| Initialization. |
`-----------------*/
+ /* FIXME: We should check the expected behavior of init_ here. As
+ far as I (Roland) can recall, it was not meant to initialize
+ data/values. We should probably just create vectors of values of
+ the same size, not copy the values. */
template <typename P, typename V>
inline
void init_(tag::image_t,
Index: tests/morpho/hit_or_miss.cc
--- tests/morpho/hit_or_miss.cc (revision 1736)
+++ tests/morpho/hit_or_miss.cc (working copy)
@@ -41,7 +41,6 @@
#include <mln/io/pbm/load.hh>
#include <mln/io/pbm/save.hh>
#include <mln/level/fill.hh>
-#include <mln/level/stretch.hh>
#include <mln/morpho/hit_or_miss.hh>
Index: tests/morpho/meyer_wst_long.cc
--- tests/morpho/meyer_wst_long.cc (revision 1736)
+++ tests/morpho/meyer_wst_long.cc (working copy)
@@ -35,8 +35,6 @@
#include <mln/core/window2d.hh>
#include <mln/core/neighb2d.hh>
-#include <mln/level/stretch.hh>
-
#include <mln/value/int_u8.hh>
#include <mln/value/int_u16.hh>