Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of Olena. 00004 // 00005 // Olena is free software: you can redistribute it and/or modify it under 00006 // the terms of the GNU General Public License as published by the Free 00007 // Software Foundation, version 2 of the License. 00008 // 00009 // Olena is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 // As a special exception, you may use this file as part of a free 00018 // software project without restriction. Specifically, if other files 00019 // instantiate templates or use macros or inline functions from this 00020 // file, or you compile this file and link it with other files to produce 00021 // an executable, this file does not by itself cause the resulting 00022 // executable to be covered by the GNU General Public License. This 00023 // exception does not however invalidate any other reasons why the 00024 // executable file might be covered by the GNU General Public License. 00025 00030 00031 #include <cstdlib> 00032 #include <cmath> 00033 00034 #include <utility> 00035 #include <iostream> 00036 00037 #include <mln/core/image/complex_image.hh> 00038 #include <mln/core/image/complex_neighborhoods.hh> 00039 00040 #include <mln/morpho/closing/area.hh> 00041 #include <mln/morpho/meyer_wst.hh> 00042 00043 #include <mln/literal/white.hh> 00044 00045 #include <mln/io/off/load.hh> 00046 #include <mln/io/off/save.hh> 00047 00048 00049 00050 int main(int argc, char* argv[]) 00051 { 00052 if (argc != 4) 00053 { 00054 std::cerr << "usage: " << argv[0] << " input.off lambda output.off" 00055 << std::endl; 00056 std::exit(1); 00057 } 00058 00059 std::string input_filename = argv[1]; 00060 unsigned lambda = atoi(argv[2]); 00061 std::string output_filename = argv[3]; 00062 00063 /*----------------. 00064 | Complex image. | 00065 `----------------*/ 00066 00067 // Image type. 00068 typedef mln::float_2complex_image3df ima_t; 00069 // Dimension of the image (and therefore of the complex). 00070 static const unsigned D = ima_t::dim; 00071 // Geometry of the image. 00072 typedef mln_geom_(ima_t) G; 00073 00074 ima_t input; 00075 mln::io::off::load(input, input_filename); 00076 00077 // Values on edges. 00078 mln::p_n_faces_fwd_piter<D, G> e(input.domain(), 1); 00079 typedef mln::complex_higher_neighborhood<D, G> adj_polygons_nbh_t; 00080 adj_polygons_nbh_t adj_polygons_nbh; 00081 mln_niter_(adj_polygons_nbh_t) adj_p(adj_polygons_nbh, e); 00082 // Iterate on edges (1-faces). 00083 for_all(e) 00084 { 00085 float s = 0.0f; 00086 unsigned n = 0; 00087 for_all(adj_p) 00088 { 00089 s += input(adj_p); 00090 ++n; 00091 } 00092 input(e) = s / n; 00093 // An edge should be adjacent to two polygons at most. 00094 mln_invariant(n <= 2); 00095 } 00096 00097 /*-----------------. 00098 | Simplification. | 00099 `-----------------*/ 00100 00102 typedef 00103 mln::complex_higher_dim_connected_n_face_neighborhood<D, G> 00104 adj_edges_nbh_t; 00105 adj_edges_nbh_t adj_edges_nbh; 00106 00107 ima_t closed_input = mln::morpho::closing::area(input, adj_edges_nbh, lambda); 00108 00109 /*------. 00110 | WST. | 00111 `------*/ 00112 00113 /* FIXME: Note that the WST is doing too much work, since we have 00114 not constrained the domain of the image to 1-faces only. 00115 It would be great if we could use something like this: 00116 00117 closed_input | mln::p_faces<1, D, G>(closed_input.domain()) 00118 00119 as input of the WST. */ 00120 00121 // Compute the WST on edges. 00122 typedef unsigned wst_val_t; 00123 wst_val_t nbasins; 00124 typedef mln::unsigned_2complex_image3df wst_ima_t; 00125 wst_ima_t wshed = 00126 mln::morpho::meyer_wst(closed_input, adj_edges_nbh, nbasins); 00127 std::cout << "nbasins = " << nbasins << std::endl; 00128 00129 // Label polygons (i.e., propagate labels from edges to polygons). 00130 for_all(e) 00131 if (wshed(e) != 0) 00132 for_all(adj_p) 00133 wshed(adj_p) = wshed(e); 00134 00135 /*---------. 00136 | Output. | 00137 `---------*/ 00138 00139 mln::rgb8_2complex_image3df output(wshed.domain()); 00140 mln::data::fill(output, mln::literal::white); 00141 00142 // FIXME: Use a colorize functor instead. 00143 // Choose random colors for each basin number. 00144 std::vector<mln::value::rgb8> basin_color (nbasins + 1); 00145 for (unsigned i = 0; i <= nbasins; ++i) 00146 basin_color[i] = mln::value::rgb8(random() % 256, 00147 random() % 256, 00148 random() % 256); 00149 mln_piter_(ima_t) f(wshed.domain()); 00150 for_all(f) 00151 output(f) = basin_color[wshed(f)]; 00152 00153 mln::io::off::save(output, output_filename); 00154 }