• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

was.median.hh

00001 // Copyright (C) 2007, 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_DATA_WAS_MEDIAN_HH
00027 # define MLN_DATA_WAS_MEDIAN_HH
00028 
00034 # include <mln/win/shift.hh>
00035 # include <mln/core/alias/window2d.hh>
00036 
00037 # include <mln/geom/min_col.hh>
00038 # include <mln/geom/max_col.hh>
00039 # include <mln/geom/max_row.hh>
00040 # include <mln/geom/min_row.hh>
00041 
00042 # include <mln/win/diff.hh>
00043 # include <mln/win/shift.hh>
00044 
00045 # include <mln/data/median.hh>
00046 # include <mln/win/hline2d.hh>
00047 
00048 # include <mln/opt/at.hh>
00049 
00050 namespace mln
00051 {
00052 
00053   namespace data
00054   {
00055 
00056     namespace impl
00057     {
00058 
00059 
00060       // prefer using a canvas
00061 
00062       template <typename I, typename W, typename O>
00063       void median_as_procedure(const I& input,
00064                                const W& win,
00065                                O& output)
00066       {
00067         mln_precondition(input.is_valid());
00068         mln_precondition(output.is_valid());
00069 
00070         int
00071           min_row = geom::min_row(input), max_row = geom::max_row(input),
00072           min_col = geom::min_col(input), max_col = geom::max_col(input);
00073 
00074         window2d
00075           win_fwd_plus  = win - win::shift(win, left),
00076           win_fwd_minus = win::shift(win, left)  - win,
00077           win_bkd_plus  = win - win::shift(win, right),
00078           win_bkd_minus = win::shift(win, right) - win,
00079           win_bot       = win - win::shift(win, up),
00080           win_top       = win::shift(win, up)    - win;
00081 
00082         point2d p;
00083         mln_qiter(W)
00084           q_fp(win_fwd_plus, p), q_fm(win_fwd_minus, p),
00085           q_bp(win_bkd_plus, p), q_bm(win_bkd_minus, p),
00086           q_top(win_top, p), q_bot(win_bot, p);
00087 
00088         accu::stat::median_h<mln_vset(I)> med(input.values());
00089 
00090         // initialization
00091 
00092         p = input.bbox().pmin() + up;
00093         med.init();
00094         {
00095           mln_qiter(W) q(win, p);
00096           for_all(q) if (input.has(q))
00097             med.take(input(q));
00098         }
00099 
00100         int& row = p.row();
00101         int& col = p.col();
00102         bool fwd = true;
00103 
00104         mln_assertion(p.col() == min_col);
00105         mln_assertion(p.row() == min_row - 1);
00106 
00107         for (row = min_row; row <= max_row; ++row)
00108           {
00109             // "go down"
00110             for_all(q_top) if (input.has(q_top))
00111               med.untake(input(q_top));
00112             for_all(q_bot) if (input.has(q_bot))
00113               med.take(input(q_bot));
00114             output(p) = med;
00115 
00116             if (fwd)
00117               // browse line fwd
00118               while (col < max_col)
00119                 {
00120                   ++col;
00121                   for_all(q_fm) if (input.has(q_fm))
00122                     med.untake(input(q_fm));
00123                   for_all(q_fp) if (input.has(q_fp))
00124                     med.take(input(q_fp));
00125                   output(p) = med;
00126                 }
00127             else
00128               // browse line bkd
00129               while (col > min_col)
00130                 {
00131                   --col;
00132                   for_all(q_bm) if (input.has(q_bm))
00133                     med.untake(input(q_bm));
00134                   for_all(q_bp) if (input.has(q_bp))
00135                     med.take(input(q_bp));
00136                   output(p) = med;
00137                 }
00138 
00139             // change browsing
00140             fwd = ! fwd;
00141           }
00142       }
00143 
00144 
00145 
00146       // horizontal median
00147 
00148       template <typename I, typename O>
00149       void hmedian(const I& input, const win::hline2d& win, O& output)
00150       {
00151 
00152         const int
00153           min_row = geom::min_row(input), max_row = geom::max_row(input),
00154           min_col = geom::min_col(input), max_col = geom::max_col(input);
00155         const unsigned half = win.length() / 2;
00156 
00157         point2d p;
00158         int& row = p.row();
00159         int& col = p.col();
00160 
00161         accu::stat::median_h<mln_vset(I)> med(input.values());
00162 
00163         for (row = min_row; row <= max_row; ++row)
00164           {
00165             int ct, cu;
00166 
00167             // initialization (before first point of the row)
00168             med.init();
00169             for (ct = min_col; ct < min_col + half; ++ct)
00170               med.take(opt::at(input, row, ct));
00171 
00172             // left columns (just take new points)
00173             for (col = min_col; col <= min_col + half; ++col, ++ct)
00174               {
00175                 med.take(opt::at(input, row, ct));
00176                 output(p) = med;
00177               }
00178 
00179             // middle columns (both take and untake)
00180             cu = min_col;
00181             for (; col <= max_col - half; ++cu, ++col, ++ct)
00182               {
00183                 med.take(opt::at(input, row, ct));
00184                 med.untake(opt::at(input, row, cu));
00185                 output(p) = med;
00186               }
00187 
00188             // right columns (now just untake old points)
00189             for (; col <= max_col; ++cu, ++col)
00190               {
00191                 med.untake(opt::at(input, row, cu));
00192                 output(p) = med;
00193               }
00194           }
00195 
00196       } // end of hmedian
00197 
00198 
00199 
00200     } // end of namespace mln::data::impl
00201 
00202   } // end of namespace mln::data
00203 
00204 } // end of namespace mln
00205 
00206 
00207 #endif // ! MLN_DATA_WAS_MEDIAN_HH

Generated on Tue Oct 4 2011 15:25:09 for Milena (Olena) by  doxygen 1.7.1