URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-06-12 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Implement visualization routine for regions.
* fabien/igr/wst_edges.cc: Add call to display_region().
* fabien/mln/world/inter_pixel/display_region.hh:
Implement routine for visualization of regions after a watershed call
[Draft, non functional].
---
igr/wst_edges.cc | 6 ++
mln/world/inter_pixel/display_region.hh | 84 ++++++++++++++++----------------
2 files changed, 50 insertions(+), 40 deletions(-)
Index: trunk/milena/sandbox/fabien/igr/wst_edges.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/wst_edges.cc (revision 4126)
+++ trunk/milena/sandbox/fabien/igr/wst_edges.cc (revision 4127)
@@ -34,6 +34,7 @@
#include <mln/data/compute.hh>
#include <mln/data/convert.hh>
#include <mln/data/stretch.hh>
+#include <mln/literal/colors.hh>
#include <mln/make/image2d.hh>
#include <mln/make/w_window1d.hh>
#include <mln/math/diff_abs.hh>
@@ -57,11 +58,14 @@
#include "plot_points/int2rgb.hh"
+#include <mln/world/inter_pixel/display_region.hh>
+
using namespace mln;
using value::int_u8;
using value::int_u12;
using value::label_16;
+using value::rgb8;
const float saturation = 1.0;
@@ -138,6 +142,8 @@
io::dump::save(w_all, "watershed.dump");
io::ppm::save(debug::int2rgb(w_all), "watershed.ppm");
+ io::ppm::save(world::inter_pixel::display_region(data::stretch(int_u8(), input), w_all,
literal::red), "regions.ppm");
+
return 0;
}
Index: trunk/milena/sandbox/fabien/mln/world/inter_pixel/display_region.hh
===================================================================
--- trunk/milena/sandbox/fabien/mln/world/inter_pixel/display_region.hh (revision 4126)
+++ trunk/milena/sandbox/fabien/mln/world/inter_pixel/display_region.hh (revision 4127)
@@ -31,15 +31,18 @@
/// Create an image for visualizing the different regions of a labeled
/// inter_pixel image.
+# include <mln/core/concept/image.hh>
# include <mln/core/image/image2d.hh>
# include <mln/core/image/dmorph/image_if.hh>
+# include <mln/core/routine/extend.hh>
+# include <mln/convert/from_to.hh>
# include <mln/data/paste.hh>
# include <mln/world/inter_pixel/is_pixel.hh>
# include <mln/world/inter_pixel/is_separator.hh>
# include <mln/opt/at.hh>
# include <mln/value/rgb8.hh>
-# include "is_zero_face.hh"
+# include <mln/world/inter_pixel/is_zero_face.hh>
namespace mln
@@ -58,72 +61,73 @@
/// \param[in] edge_color The color (in rgb8) for the watershed line.
/// \return FIXME
///
+ /// \pre \p input has to be an 8 bits image.
/// \pre \p wst has to be an unmorphed image.
/// \warning This implementation only works for 2D images.
///
template <typename I, typename L>
inline
mln_ch_value(I, value::rgb8)
- display_region(const I& input, const mln_ch_value(I, L)& wst, value::rbg8
edge_color);
+ display_region(const Image<I>& input, const Image<L>& wst,
value::rgb8 edge_color);
# ifndef MLN_INCLUDE_ONLY
- template <typename I>
+ template <typename I, typename L>
inline
mln_ch_value(I, value::rgb8)
- display_region(const I& input, const mln_ch_value(I, L)& wst, value::rbg8
edge_color)
+ display_region(const Image<I>& input_, const Image<L>& wst_,
value::rgb8 edge_color)
{
- mln_precondition((2 * input.bbox()) == wst.unmorph_().bbox());
+ // TODO: We should check that wst.bbox () == 2 * input.bbox() - 1.
+ // TODO: We must check that dim(I) == dim(L).
+ //mln_precondition((2 * input.bbox()) == wst.bbox());
+
+ const I& input = exact(input_);
+ const L& wst = exact(wst_);
- mln_ch_value(I, value::rgb8) output;
+ typedef mln_ch_value(I, value::rgb8) output_t;
+ output_t output;
initialize(output, wst);
// Pixel.
mln_piter(I) p_input(input.domain());
- for_all(p)
- opt::at(output, p.to_vec[0] * 2, p.to_vec[1] * 2) = input(p);
+ for_all(p_input)
+ convert::from_to(input(p_input), opt::at(output, p_input.row() * 2, p_input.col() *
2));
// Separator.
- typedef image_if<const mln_ch_value(I, L)&, is_separator> separator_t;
- separator_t edge = wst | is_separator();
- mln_piter(edge_t) p(edge.domain());
+ typedef image_if<output_t, is_separator> separator_t;
+ separator_t sep = output | is_separator();
+ mln_piter(separator_t) p(sep.domain());
for_all(p)
{
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * 2 - 1;
- unsigned col = p.col();
- opt::at(output, row, col) = input(p);
- }
- else // vertical edge
- {
unsigned row = p.row();
- unsigned col = (p.col() / 2 + 1) * 2 - 1;
- opt::at(output, row, col) = input(p);
- }
- }
-
- // Point (dimension 0).
- typedef image_if<const mln_ch_value(I, L)&, is_zero_face> zero_face_t;
- zero_face_t edge = wst | is_zero_face();
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- {
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * 2 - 1;
unsigned col = p.col();
- opt::at(output, row, col) = input(p);
- }
+ if (p.row() % 2) // horizontal edge
+ output(p) = (opt::at(output, row + 1, col) +
+ opt::at(output, row - 1, col)) / 2;
else // vertical edge
- {
- unsigned row = p.row();
- unsigned col = (p.col() / 2 + 1) * 2 - 1;
- opt::at(output, row, col) = input(p);
- }
+ output(p) = (opt::at(output, row, col + 1) +
+ opt::at(output, row, col - 1)) / 2;
}
+ // Zero-face (dimension 0).
+ typedef image_if<output_t, is_zero_face> zero_face_t;
+ zero_face_t zero = output | is_zero_face();
+ mln_piter(zero_face_t) q(zero.domain());
+ for_all(q)
+ {
+ unsigned row = q.row();
+ unsigned col = q.col();
+ output(q) = (opt::at(output, row + 1, col) +
+ opt::at(output, row, col + 1) +
+ opt::at(output, row - 1, col) +
+ opt::at(output, row, col - 1)) / 4;
+ }
+
+ // Watershed lines.
+ data::fill((output | pw::value(wst) == pw::cst(0)).rw(), edge_color);
+ //FIXME: Fill intersections.
+
return output;
# endif // ! MLN_INCLUDE_ONLY