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 00026 #ifndef MLN_MORPHO_MEYER_WST_HH 00027 # define MLN_MORPHO_MEYER_WST_HH 00028 00041 /* FIXME: This file is outdated. Compare this file with 00042 mln/morpho/watershed/flooding.hh, and remove the former when 00043 00044 1. it is entirely covered by the latter; 00045 2. clients (including tests and Milena) are updated to use 00046 mln::morpho::watershed::flooding. */ 00047 00048 00049 # include <mln/trait/ch_value.hh> 00050 00051 // FIXME: See below. 00052 # include <mln/util/greater_psite.hh> 00053 # include <mln/morpho/includes.hh> 00054 # include <mln/literal/zero.hh> 00055 # include <mln/labeling/regional_minima.hh> 00056 00057 # include <mln/core/site_set/p_queue_fast.hh> 00058 # include <mln/core/site_set/p_priority.hh> 00059 00060 00061 namespace mln 00062 { 00063 00064 namespace morpho 00065 { 00077 template <typename L, typename I, typename N> 00078 mln_ch_value(I, L) 00079 meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh, 00080 L& nbasins); 00081 00098 template <typename L, typename I, typename N> 00099 mln_ch_value(I, L) 00100 meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh); 00101 00102 00103 00104 # ifndef MLN_INCLUDE_ONLY 00105 00106 template <typename L, typename I, typename N> 00107 mln_ch_value(I, L) 00108 meyer_wst(const Image<I>& input_, const Neighborhood<N>& nbh_, 00109 L& nbasins) 00110 { 00111 trace::entering("morpho::meyer_wst"); 00112 /* FIXME: Ensure the input image has scalar values. */ 00113 00114 const I input = exact(input_); 00115 const N nbh = exact(nbh_); 00116 00117 typedef L marker; 00118 const marker unmarked = literal::zero; 00119 00120 typedef mln_value(I) V; 00121 const V max = mln_max(V); 00122 00123 // Initialize the output with the markers (minima components). 00124 mln_ch_value(I, marker) output = 00125 labeling::regional_minima (input, nbh, nbasins); 00126 00127 typedef mln_psite(I) psite; 00128 00129 // Ordered queue. 00130 typedef p_queue_fast<psite> Q; 00131 p_priority<V, Q> queue; 00132 00133 // In_queue structure to avoid processing sites several times. 00134 mln_ch_value(I, bool) in_queue; 00135 initialize(in_queue, input); 00136 data::fill(in_queue, false); 00137 00138 // Insert every neighbor P of every marked area in a 00139 // hierarchical queue, with a priority level corresponding to 00140 // the grey level input(P). 00141 mln_piter(I) p(output.domain()); 00142 mln_niter(N) n(nbh, p); 00143 for_all (p) 00144 if (output(p) == unmarked) 00145 for_all(n) 00146 if (output.domain().has(n) && output(n) != unmarked) 00147 { 00148 queue.push(max - input(p), p); 00149 in_queue(p) = true; 00150 break; 00151 } 00152 00153 /* Until the queue is empty, extract a psite P from the 00154 hierarchical queue, at the highest priority level, that is, 00155 the lowest level. */ 00156 while (! queue.is_empty()) 00157 { 00158 psite p = queue.front(); 00159 queue.pop(); 00160 // Last seen marker adjacent to P. 00161 marker adjacent_marker = unmarked; 00162 // Has P a single adjacent marker? 00163 bool single_adjacent_marker_p = true; 00164 mln_niter(N) n(nbh, p); 00165 for_all(n) 00166 if (output.domain().has(n) && output(n) != unmarked) 00167 { 00168 if (adjacent_marker == unmarked) 00169 { 00170 adjacent_marker = output(n); 00171 single_adjacent_marker_p = true; 00172 } 00173 else 00174 if (adjacent_marker != output(n)) 00175 { 00176 single_adjacent_marker_p = false; 00177 break; 00178 } 00179 } 00180 /* If the neighborhood of P contains only psites with the 00181 same label, then P is marked with this label, and its 00182 neighbors that are not yet marked are put into the 00183 hierarchical queue. */ 00184 if (single_adjacent_marker_p) 00185 { 00186 output(p) = adjacent_marker; 00187 for_all(n) 00188 if (output.domain().has(n) && output(n) == unmarked 00189 && ! in_queue(n)) 00190 { 00191 queue.push(max - input(n), n); 00192 in_queue(n) = true; 00193 } 00194 } 00195 } 00196 trace::exiting("morpho::meyer_wst"); 00197 return output; 00198 } 00199 00200 template <typename L, typename I, typename N> 00201 mln_ch_value(I, L) 00202 meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh) 00203 { 00204 L nbasins; 00205 return meyer_wst<L>(input, nbh, nbasins); 00206 } 00207 00208 # endif // ! MLN_INCLUDE_ONLY 00209 00210 } // end of namespace mln::morpho 00211 00212 } // end of namespace mln 00213 00214 00215 #endif // ! MLN_MORPHO_MEYER_WST_HH