$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
inter_pixel.cc
1 // Copyright (C) 2009, 2013 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #include <mln/core/image/image2d.hh>
27 #include <mln/core/alias/neighb2d.hh>
28 #include <mln/core/var.hh>
29 
30 #include <mln/value/int_u8.hh>
31 #include <mln/value/label_16.hh>
32 #include <mln/value/rgb8.hh>
33 
34 #include <mln/io/pgm/all.hh>
35 #include <mln/io/ppm/save.hh>
36 
37 #include <mln/data/convert.hh>
38 #include <mln/data/fill.hh>
39 #include <mln/debug/int2rgb.hh>
40 #include <mln/display/display_region.hh>
41 #include <mln/literal/colors.hh>
42 #include <mln/math/diff_abs.hh>
43 #include <mln/morpho/closing/volume.hh>
44 #include <mln/morpho/elementary/gradient.hh>
45 #include <mln/morpho/watershed/flooding.hh>
46 #include <mln/world/inter_pixel/compute.hh>
47 #include <mln/world/inter_pixel/display_edge.hh>
48 #include <mln/world/inter_pixel/display_region.hh>
49 #include <mln/world/inter_pixel/immerse.hh>
50 #include <mln/world/inter_pixel/is_pixel.hh>
51 #include <mln/world/inter_pixel/is_separator.hh>
52 #include <mln/world/inter_pixel/neighb2d.hh>
53 
54 
55 using namespace mln;
56 using value::int_u8;
57 using value::label_16;
58 using value::rgb8;
59 
60 
61 struct dist_t : Function_vv2v<dist_t>
62 {
63  typedef int_u8 result;
64 
65  template <typename V>
66  int_u8 operator()(const V v1, const V v2) const
67  {
68  return math::diff_abs(v1, v2);
69  }
70 } dist;
71 
72 
73 
74 int main(int argc, char* argv[])
75 {
76  if (argc != 2)
77  {
78  std::cout << "Usage: " << argv[0] << " input.pgm" << std::endl;
79  return 1;
80  }
81 
82  image2d<int_u8> input;
83  io::pgm::load(input, argv[1]);
84 
85  // Gradient.
87  io::pgm::save(grad, "gradient.pgm");
88 
89  label_16 nbasins;
90 
91  // Normal watershed.
92  image2d<label_16> normal_wst = morpho::watershed::flooding(input, c4(), nbasins);
93  io::ppm::save(display::display_region(input, normal_wst, literal::red), "normal_watershed.ppm");
94 
95 
96 
97  // Distance on edges.
99  Ix imax = world::inter_pixel::immerse(input);
100  image_if<image2d<int_u8>, world::inter_pixel::is_separator> edges;
101  edges = world::inter_pixel::compute(imax, dist);
102 
103  io::pgm::save(world::inter_pixel::display_edge(edges.unmorph_(), 0, 3), "edge_dist.pgm");
104 
105  // Color on edge image.
106  image2d<rgb8> edge_color = data::convert(rgb8(), edges.unmorph_());
107  mln_piter_(image2d<int_u8>) p(input.domain());
108  for_all(p)
109  convert::from_to(input(p), opt::at(edge_color, p.row() * 2, p.col() * 2));
110  data::fill((edge_color | world::inter_pixel::is_separator()).rw(), literal::green);
111  data::fill((edge_color | world::inter_pixel::is_zero_face()).rw(), literal::blue);
112  io::ppm::save(edge_color, "edge_color.ppm");
113 
114  // Color on stretched edge image.
115  box2d b = edge_color.bbox();
116  image2d<rgb8> edge_stretch(make::box2d(((b.pmin()[0] + 1) / 2) * 4, ((b.pmin()[1] + 1) / 2) * 4,
117  ((b.pmax()[0] + 1) / 2 + 1) * 4 - 2, ((b.pmax()[1] + 1) / 2 + 1) * 4 - 2));
118  typedef image_if<image2d<rgb8>, world::inter_pixel::is_separator> edge_t;
119  edge_t edge_sep = edge_color | world::inter_pixel::is_separator();
120  mln_piter_(edge_t) q(edge_sep.domain());
121  for_all(q)
122  if (q.row() % 2) // horizontal edge
123  {
124  unsigned row = (q.row() / 2 + 1) * 4 - 1;
125  unsigned col = (q.col() / 2) * 4;
126  for (unsigned i = 0; i < 3; ++i)
127  opt::at(edge_stretch, row, col + i) = literal::green;
128  }
129  else // vertical edge
130  {
131  unsigned row = (q.row() / 2) * 4;
132  unsigned col = (q.col() / 2 + 1) * 4 - 1;
133  for (unsigned i = 0; i < 3; ++i)
134  opt::at(edge_stretch, row + i, col) = literal::green;
135  }
136  mln_VAR(edge_zero, edge_color | world::inter_pixel::is_zero_face());
137  mln_piter_(edge_zero_t) ez(edge_zero.domain());
138  for_all(ez)
139  opt::at(edge_stretch, ((ez.row() + 1) / 2) * 4 - 1, ((ez.col() + 1) / 2) * 4 - 1) = literal::blue;
140  mln_VAR(edge_pix, edge_color | world::inter_pixel::is_pixel());
141  mln_piter_(edge_pix_t) ex(edge_pix.domain());
142  for_all(ex)
143  for (int i = 0; i < 3; ++i)
144  for (int j = 0; j < 3; ++j)
145  opt::at(edge_stretch, (ex.row() / 2) * 4 + i, (ex.col() / 2) * 4 + j) = edge_color(ex);
146  io::ppm::save(edge_stretch, "edge_stretch.ppm");
147 
148 
149  // On edges watershed.
150  mln_VAR(edge_clo, morpho::closing::volume(edges, world::inter_pixel::e2e(), 25));
151  mln_VAR(edge_wst, morpho::watershed::flooding(edge_clo, world::inter_pixel::e2e(), nbasins));
152  io::ppm::save(world::inter_pixel::display_region(input, edge_wst.unmorph_(), literal::red), "edge_watershed.ppm");
153 }