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