Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 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 00026 #ifndef APPS_GRAPH_MORPHO_CONVERT_HH 00027 # define APPS_GRAPH_MORPHO_CONVERT_HH 00028 00031 00032 # include <mln/core/alias/complex_image.hh> 00033 # include <mln/core/image/image2d.hh> 00034 00035 # include <mln/math/abs.hh> 00036 00037 # include "apps/graph-morpho/make.hh" 00038 00039 00040 namespace convert 00041 { 00042 00044 inline 00045 mln::image2d<bool> 00046 to_image2d(const mln::bin_1complex_image2d& input) 00047 { 00048 using namespace mln; 00049 00050 const unsigned dim = 1; 00051 typedef geom::complex_geometry<dim, point2d> geom_t; 00052 00053 // Compute the bounding box of the domain of FROM. 00054 accu::shape::bbox<point2d> bbox; 00055 p_n_faces_fwd_piter<dim, geom_t> v(input.domain(), 0); 00056 for_all(v) 00057 { 00058 mln_site_(geom_t) s(v); 00059 // Site S is point2d multi-site and should be a singleton (since V 00060 // iterates on vertices). 00061 mln_invariant(s.size() == 1); 00062 point2d p = s.front(); 00063 bbox.take(p); 00064 } 00065 mln::box2d support = bbox; 00066 00067 point2d box_p_min(support.pmin().row() * 2, support.pmin().col() * 2); 00068 point2d box_p_max(support.pmax().row() * 2, support.pmax().col() * 2); 00069 image2d<bool> output(box2d(box_p_min, box_p_max)); 00070 data::fill(output, false); 00071 00072 // Iterate on vertices. 00073 for_all(v) 00074 { 00075 mln_site_(geom_t) s(v); 00076 // Site S is point2d multi-site and should be a singleton (since V 00077 // iterates on vertices). 00078 mln_invariant(s.size() == 1); 00079 point2d p_in = s.front(); 00080 point2d p_out(p_in.row() * 2, p_in.col() * 2); 00081 output(p_out) = input(v); 00082 } 00083 00084 // Iterate on edges. 00085 p_n_faces_fwd_piter<dim, geom_t> e(input.domain(), 1); 00086 for_all(e) 00087 { 00088 mln_site_(geom_t) s(e); 00089 // Site S is point2d multi-site and should be a pair (since E 00090 // iterates on vertices). 00091 mln_invariant(s.size() == 2); 00092 point2d p1 = s[0]; 00093 point2d p2 = s[1]; 00094 if (p1.row() == p2.row()) 00095 { 00096 // Horizontal edge. 00097 point2d p_out(p1.row() * 2, 00098 p1.col() + p2.col()); 00099 output(p_out) = input(e); 00100 } 00101 else if (p1.col() == p2.col()) 00102 { 00103 // Vertical edge. 00104 point2d p_out(p1.row() + p2.row(), 00105 p1.col() * 2); 00106 output(p_out) = input(e); 00107 } 00108 else 00109 { 00110 // Edge not fitting in the 2D regular grid canvas, aborting. 00111 abort(); 00112 } 00113 } 00114 return output; 00115 } 00116 00117 00119 inline 00120 mln::bin_1complex_image2d 00121 to_complex_image(const mln::image2d<bool>& input) 00122 { 00123 using namespace mln; 00124 00125 const box2d& input_box = input.domain(); 00126 // The input image must have an odd number of rows and columns. 00127 mln_precondition(input_box.nrows() % 2 == 1); 00128 mln_precondition(input_box.ncols() % 2 == 1); 00129 00130 // The domain of the graph image is twice as small, since we 00131 // consider only vertices (edges are set ``between'' vertices). 00132 box2d output_box(input_box.nrows() / 2 + 1, 00133 input_box.ncols() / 2 + 1); 00134 bin_1complex_image2d output = ::make::complex1d_image<bool>(output_box); 00135 00136 const unsigned dim = 1; 00137 typedef geom::complex_geometry<dim, point2d> geom_t; 00138 00139 // Add values on vertices. 00140 p_n_faces_fwd_piter<dim, geom_t> v(output.domain(), 0); 00141 for_all(v) 00142 { 00143 mln_site_(geom_t) s(v); 00144 // Site S is point2d multi-site and should be a singleton (since V 00145 // iterates on vertices). 00146 mln_invariant(s.size() == 1); 00147 point2d p = s.front(); 00148 point2d q(p.row() * 2, p.col() * 2); 00149 output(v) = input(q); 00150 } 00151 00152 // Add values on edges. 00153 p_n_faces_fwd_piter<dim, geom_t> e(output.domain(), 1); 00154 for_all(e) 00155 { 00156 mln_site_(geom_t) s(e); 00157 // Site S is point2d multi-site and should be a pair (since E 00158 // iterates on vertices). 00159 mln_invariant(s.size() == 2); 00160 point2d p1 = s[0]; 00161 point2d p2 = s[1]; 00162 mln_invariant(math::abs(p1.row() - p2.row()) == 1 00163 || math::abs(p1.col() - p2.col()) == 1); 00164 point2d q (p1.row() + p2.row(), p1.col() + p2.col()); 00165 output(e) = input(q); 00166 } 00167 00168 return output; 00169 } 00170 00171 } // end of namespace convert 00172 00173 00174 #endif // ! APPS_GRAPH_MORPHO_CONVERT_HH