00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00049 #include <mln/core/image/image2d.hh>
00050 #include <mln/core/alias/point2d.hh>
00051 #include <mln/core/alias/window2d.hh>
00052 #include <mln/core/alias/neighb2d.hh>
00053 
00055 #include <mln/core/image/edge_image.hh>
00056 #include <mln/pw/all.hh>
00057 #include <mln/fun/i2v/array.hh>
00058 #include <mln/util/graph.hh>
00059 
00060 #include <mln/morpho/line_gradient.hh>
00061 #include <mln/morpho/closing/area_on_vertices.hh>
00062 #include <mln/morpho/meyer_wst.hh>
00063 #include <mln/data/stretch.hh>
00064 
00065 #include <mln/value/int_u8.hh>
00066 #include <mln/value/int_u16.hh>
00067 #include <mln/value/rgb8.hh>
00068 #include <mln/literal/black.hh>
00069 #include <mln/literal/colors.hh>
00070 
00071 #include <mln/io/pgm/load.hh>
00072 #include <mln/io/pgm/save.hh>
00073 #include <mln/io/ppm/save.hh>
00074 
00075 #include <mln/math/max.hh>
00076 #include <mln/math/abs.hh>
00077 
00078 #include <mln/opt/at.hh>
00079 
00080 #include "tests/data.hh"
00081 
00082 
00083 
00084 int main()
00085 {
00086   using namespace mln;
00087   using value::int_u8;
00088   using value::int_u16;
00089   using value::rgb8;
00090 
00091   
00092 
00093 
00094 
00095   
00096   const unsigned nrows = 100;
00097   const unsigned ncols = 100;
00098   const unsigned square_length = 3;
00099   typedef int_u8 input_val_t;
00100   
00101   image2d<input_val_t> input (nrows, ncols);
00102   for (unsigned  r = 0; r < nrows; ++r)
00103     for (unsigned c = 0; c < ncols; ++c)
00104       opt::at(input, r,c) =
00105         ((r / square_length) % 2 == (c / square_length) % 2)
00106         ? mln_min(input_val_t)
00107         : mln_max(input_val_t);
00108   mln_assertion((nrows * ncols) == 10000);
00109   mln_assertion((2 * nrows * ncols - (nrows + ncols)) == 19800);
00110 
00111   
00112 
00113 
00114 
00115   
00116   typedef edge_image<util::site_pair<point2d>, input_val_t, util::graph> lg_ima_t;
00117   lg_ima_t lg_ima = morpho::line_gradient(input);
00118 
00119   
00120 
00121 
00122 
00123   typedef lg_ima_t::nbh_t nbh_t;
00124   nbh_t nbh;
00125 
00126   
00127   typedef edge_image<util::site_pair<point2d>, unsigned, util::graph> wshed_t;
00128   unsigned nbasins;
00129   wshed_t wshed = morpho::meyer_wst(lg_ima, nbh, nbasins);
00130   mln_assertion(nbasins == 1155);
00131 
00132   
00133 
00134 
00135 
00136   
00137 
00138   
00139 
00140   
00141   typedef rgb8 output_val_t;
00142   typedef image2d<output_val_t> output_t;
00143   point2d output_pmin = input.domain().pmin();
00144   point2d output_pmax(input.domain().pmax()[0] * 2,
00145                       input.domain().pmax()[1] * 2);
00146   output_t output(box2d(output_pmin, output_pmax));
00147   data::fill(output, literal::black);
00148   mln_fwd_piter_(image2d<input_val_t>) p(input.domain());
00149   for_all(p)
00150   {
00151     
00152     point2d q(p[0] * 2, p[1] * 2);
00153     input_val_t v = input(p);
00154     
00155 
00156     output(q) = output_val_t(v, v, v);
00157   }
00158   
00159   mln_piter_(output_t) p_out(output.domain());
00160   for_all(p_out)
00161   {
00162     
00163     if (p_out[0] % 2 == 0 && p_out[1] % 2 == 1)
00164       output(p_out) = (output(p_out + left) + output(p_out + right)) / 2;
00165     
00166     if (p_out[0] % 2 == 1 && p_out[1] % 2 == 0)
00167       output(p_out) = (output(p_out + up) + output(p_out + down)) / 2;
00168     
00169     if (p_out[0] % 2 == 1 && p_out[1] % 2 == 1)
00170       output(p_out) =
00171         (output(p_out + dpoint2d(-1, -1)) +
00172          output(p_out + dpoint2d(-1, +1)) +
00173          output(p_out + dpoint2d(+1, -1)) +
00174          output(p_out + dpoint2d(+1, +1))) / 4;
00175   }
00176   
00177   
00178 
00179 
00180   mln_piter_(wshed_t) pw(wshed.domain());
00181   for_all(pw)
00182   {
00183     if (wshed(pw) == 0)
00184       {
00185         mln_psite_(lg_ima_t) pp(pw);
00186         
00187         int row1 = pp.first()[0] * 2;
00188         int col1 = pp.first()[1] * 2;
00189         int row2 = pp.second()[0] * 2;
00190         int col2 = pp.second()[1] * 2;
00191         point2d q((row1 + row2) / 2, (col1 + col2) / 2);
00192         
00193         output(q) = literal::red;
00194       }
00195   }
00196   
00197   
00198 
00199 
00200 
00201 
00202 
00203 
00204   
00205   for_all (p_out)
00206     
00207     if (p_out[0] % 2 == 1 && p_out[1] % 2 == 1)
00208   {
00209     
00210     
00211     
00212 
00213     unsigned nwsheds =
00214       (output.has(p_out + up   ) && output(p_out + up   ) == literal::red) +
00215       (output.has(p_out + down ) && output(p_out + down ) == literal::red) +
00216       (output.has(p_out + left ) && output(p_out + right) == literal::red) +
00217       (output.has(p_out + right) && output(p_out + left ) == literal::red);
00218     if (nwsheds >= 2)
00219       output(p_out) = literal::red;
00220   }
00221   io::ppm::save(output, "artificial_line_graph_image_wst-out.ppm");
00222 }