Milena (Olena)
User documentation 2.0a Id
|
00001 #include <mln/core/image/image2d.hh> 00002 #include <mln/core/alias/neighb2d.hh> 00003 #include <mln/core/var.hh> 00004 00005 #include <mln/value/int_u8.hh> 00006 #include <mln/value/label_16.hh> 00007 #include <mln/value/rgb8.hh> 00008 00009 #include <mln/io/pgm/all.hh> 00010 #include <mln/io/ppm/save.hh> 00011 00012 #include <mln/data/convert.hh> 00013 #include <mln/data/fill.hh> 00014 #include <mln/debug/int2rgb.hh> 00015 #include <mln/display/display_region.hh> 00016 #include <mln/literal/colors.hh> 00017 #include <mln/math/diff_abs.hh> 00018 #include <mln/morpho/closing/volume.hh> 00019 #include <mln/morpho/elementary/gradient.hh> 00020 #include <mln/morpho/watershed/flooding.hh> 00021 #include <mln/world/inter_pixel/compute.hh> 00022 #include <mln/world/inter_pixel/display_edge.hh> 00023 #include <mln/world/inter_pixel/display_region.hh> 00024 #include <mln/world/inter_pixel/immerse.hh> 00025 #include <mln/world/inter_pixel/is_pixel.hh> 00026 #include <mln/world/inter_pixel/is_separator.hh> 00027 #include <mln/world/inter_pixel/neighb2d.hh> 00028 00029 00030 using namespace mln; 00031 using value::int_u8; 00032 using value::label_16; 00033 using value::rgb8; 00034 00035 00036 struct dist_t : Function_vv2v<dist_t> 00037 { 00038 typedef int_u8 result; 00039 00040 template <typename V> 00041 int_u8 operator()(const V v1, const V v2) const 00042 { 00043 return math::diff_abs(v1, v2); 00044 } 00045 } dist; 00046 00047 00048 00049 int main(int argc, char* argv[]) 00050 { 00051 if (argc != 2) 00052 { 00053 std::cout << "Usage: " << argv[0] << " input.pgm" << std::endl; 00054 return 1; 00055 } 00056 00057 image2d<int_u8> input; 00058 io::pgm::load(input, argv[1]); 00059 00060 // Gradient. 00061 image2d<int_u8> grad = morpho::elementary::gradient(input, c4()); 00062 io::pgm::save(grad, "gradient.pgm"); 00063 00064 label_16 nbasins; 00065 00066 // Normal watershed. 00067 image2d<label_16> normal_wst = morpho::watershed::flooding(input, c4(), nbasins); 00068 io::ppm::save(display::display_region(input, normal_wst, literal::red), "normal_watershed.ppm"); 00069 00070 00071 00072 // Distance on edges. 00073 typedef image_if<image2d<int_u8>, world::inter_pixel::is_pixel> Ix; 00074 Ix imax = world::inter_pixel::immerse(input); 00075 image_if<image2d<int_u8>, world::inter_pixel::is_separator> edges; 00076 edges = world::inter_pixel::compute(imax, dist); 00077 00078 io::pgm::save(world::inter_pixel::display_edge(edges.unmorph_(), 0, 3), "edge_dist.pgm"); 00079 00080 // Color on edge image. 00081 image2d<rgb8> edge_color = data::convert(rgb8(), edges.unmorph_()); 00082 mln_piter_(image2d<int_u8>) p(input.domain()); 00083 for_all(p) 00084 convert::from_to(input(p), opt::at(edge_color, p.row() * 2, p.col() * 2)); 00085 data::fill((edge_color | world::inter_pixel::is_separator()).rw(), literal::green); 00086 data::fill((edge_color | world::inter_pixel::is_zero_face()).rw(), literal::blue); 00087 io::ppm::save(edge_color, "edge_color.ppm"); 00088 00089 // Color on stretched edge image. 00090 box2d b = edge_color.bbox(); 00091 image2d<rgb8> edge_stretch(make::box2d(((b.pmin()[0] + 1) / 2) * 4, ((b.pmin()[1] + 1) / 2) * 4, 00092 ((b.pmax()[0] + 1) / 2 + 1) * 4 - 2, ((b.pmax()[1] + 1) / 2 + 1) * 4 - 2)); 00093 typedef image_if<image2d<rgb8>, world::inter_pixel::is_separator> edge_t; 00094 edge_t edge_sep = edge_color | world::inter_pixel::is_separator(); 00095 mln_piter_(edge_t) q(edge_sep.domain()); 00096 for_all(q) 00097 if (q.row() % 2) // horizontal edge 00098 { 00099 unsigned row = (q.row() / 2 + 1) * 4 - 1; 00100 unsigned col = (q.col() / 2) * 4; 00101 for (unsigned i = 0; i < 3; ++i) 00102 opt::at(edge_stretch, row, col + i) = literal::green; 00103 } 00104 else // vertical edge 00105 { 00106 unsigned row = (q.row() / 2) * 4; 00107 unsigned col = (q.col() / 2 + 1) * 4 - 1; 00108 for (unsigned i = 0; i < 3; ++i) 00109 opt::at(edge_stretch, row + i, col) = literal::green; 00110 } 00111 mln_VAR(edge_zero, edge_color | world::inter_pixel::is_zero_face()); 00112 mln_piter_(edge_zero_t) ez(edge_zero.domain()); 00113 for_all(ez) 00114 opt::at(edge_stretch, ((ez.row() + 1) / 2) * 4 - 1, ((ez.col() + 1) / 2) * 4 - 1) = literal::blue; 00115 mln_VAR(edge_pix, edge_color | world::inter_pixel::is_pixel()); 00116 mln_piter_(edge_pix_t) ex(edge_pix.domain()); 00117 for_all(ex) 00118 for (int i = 0; i < 3; ++i) 00119 for (int j = 0; j < 3; ++j) 00120 opt::at(edge_stretch, (ex.row() / 2) * 4 + i, (ex.col() / 2) * 4 + j) = edge_color(ex); 00121 io::ppm::save(edge_stretch, "edge_stretch.ppm"); 00122 00123 00124 // On edges watershed. 00125 mln_VAR(edge_clo, morpho::closing::volume(edges, world::inter_pixel::e2e(), 25)); 00126 mln_VAR(edge_wst, morpho::watershed::flooding(edge_clo, world::inter_pixel::e2e(), nbasins)); 00127 io::ppm::save(world::inter_pixel::display_region(input, edge_wst.unmorph_(), literal::red), "edge_watershed.ppm"); 00128 00129 return 0; 00130 }