Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Handle properly output in Laurent's method.
* laurent/ismm2009.cc: Sic.
ismm2009.cc | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
Index: laurent/ismm2009.cc
--- laurent/ismm2009.cc (revision 3186)
+++ laurent/ismm2009.cc (working copy)
@@ -16,6 +16,7 @@
# include <mln/core/site_set/p_queue.hh>
# include <mln/core/site_set/p_priority.hh>
+#include <mln/level/stretch.hh>
#include <mln/labeling/compute.hh>
#include <mln/accu/count.hh>
@@ -478,9 +479,10 @@
compute_wst_g_from_f(f, g, e2p(), e2e(), n_basins, echo) );
+ std::cout << "n basins = " << n_basins << std::endl;
+
if (echo)
{
- std::cout << "n basins = " << n_basins << std::endl;
debug::println("g:", g);
debug::println("wst(g):", wst_g);
}
@@ -970,6 +972,8 @@
mln_VAR(aa_line, aa | is_line);
+ A aa_max = 0;
+
{
{
@@ -990,6 +994,8 @@
// The attribute value propagates from the lca to the current edge
// of the line:
aa(e) = aa(e_);
+ if (aa(e) > aa_max)
+ aa_max = aa(e);
}
if (echo)
@@ -1069,14 +1075,38 @@
// Output is salency map.
+
{
+ if (aa_max < 256)
+ {
image2d<int_u8> output(f_.domain());
data::fill(output, 0);
data::paste(aa_line, output);
io::pgm::save(output, argv[3]);
}
+ else
+ {
+ std::cerr << "warning: stretching [0," << aa_max << "] to int_u8" << std::endl;
+
+ image2d<A> output(f_.domain());
+ data::fill(output, 0);
+ data::paste(aa_line, output);
+ io::pgm::save(level::stretch(int_u8(), output),
+ argv[3]);
+// image2d<int_u8> output(f_.domain());
+// data::fill(output, 0);
+// A threshold = aa_max - 255;
+// mln_piter(aa_line_t) e(aa_line.domain());
+// for_all(e)
+// if (aa_line(e) <= threshold)
+// output(e) = 1;
+// else
+// output(e) = aa_line(e) - threshold;
+// io::pgm::save(output, argv[3]);
+ }
+ }
} // end of main
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Add important comment to bilinear.hh.
* mln/fun/x2v/bilinear.hh: Add comment.
bilinear.hh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: mln/fun/x2v/bilinear.hh
--- mln/fun/x2v/bilinear.hh (revision 3185)
+++ mln/fun/x2v/bilinear.hh (working copy)
@@ -97,7 +97,7 @@
double y1 = std::floor(v[1]);
double y2 = std::floor(v[1]) + 1;
- //if (not ima.has(point2d(x1, y1))) return mln_value(I)();
+ //Following access are supposed valid.
vsum q11 = ima(point2d(static_cast<unsigned>(x1), static_cast<unsigned>(y1)));
vsum q12 = ima(point2d(static_cast<unsigned>(x1), static_cast<unsigned>(y2)));
vsum q21 = ima(point2d(static_cast<unsigned>(x2), static_cast<unsigned>(y1)));
1
0
21 Jan '09
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Move INIM related projects into the appropriate directory.
* garrigues/ocr: Move directory...
* inim/ocr: ...here.
* ballas/color: Move directory...
* inim/color: ...here.
* nature: Move directory...
* inim/nature: ...here.
ballas/color/README | 83 ---
ballas/color/laplacien.cc | 130 -----
ballas/color/min_tree_area_filter.cc | 515 ---------------------
ballas/color/min_tree_color.cc | 536 ----------------------
ballas/color/min_tree_color_v2.cc | 533 ----------------------
ballas/color/min_tree_height_filter.cc | 553 -----------------------
ballas/color/min_tree_volume_filter.cc | 551 -----------------------
ballas/color/reference.cc | 557 -----------------------
ballas/color/reference2.cc | 408 -----------------
ballas/color/src/convert.hh | 37 -
ballas/color/src/distance.hh | 52 --
ballas/color/src/graph.hh | 62 --
ballas/color/src/io.hh | 57 --
garrigues/ocr/Makefile | 26 -
garrigues/ocr/check.sh | 31 -
garrigues/ocr/check_simple_point.cc | 61 --
garrigues/ocr/compute_local_configurations.cc | 74 ---
garrigues/ocr/enlarge.hh | 202 --------
garrigues/ocr/ocr_with_preprocess.cc | 170 -------
garrigues/ocr/ocr_without_preprocess.cc | 90 ---
garrigues/ocr/resize.hh | 96 ----
garrigues/ocr/simple_point.cc | 39 -
garrigues/ocr/simple_point.hh | 206 --------
garrigues/ocr/skeleton.hh | 200 --------
garrigues/ocr/skeleton.old.cc | 30 -
garrigues/ocr/skeleton.old.hh | 612 --------------------------
garrigues/ocr/tesseract_wrap.hh | 91 ---
nature/Makefile | 24 -
nature/closing.cc | 59 --
nature/co_occurence.hh | 77 ---
nature/erosion.cc | 60 --
nature/fft.cc | 61 --
nature/gradient.cc | 60 --
nature/histo_hsi.cc | 181 -------
nature/hom.cc | 84 ---
nature/mco.cc | 48 --
nature/nature.cc | 498 ---------------------
nature/opening.cc | 59 --
nature/proj.cc | 68 --
nature/proj.hh | 64 --
nature/test.sh | 11
41 files changed, 7356 deletions(-)
Index: garrigues/ocr/resize.hh
--- garrigues/ocr/resize.hh (revision 3184)
+++ garrigues/ocr/resize.hh (working copy)
@@ -1,96 +0,0 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef MLN_GEOM_RESIZE_HH
-# define MLN_GEOM_RESIZE_HH
-
-# include <mln/win/rectangle2d.hh>
-
-namespace mln
-{
-
- namespace geom
- {
-
-
- /*!
- * \brief Resize an image \p input_ with \p ratio.
- *
- * \param[in] input_ The image to resize.
- * \param[in] ratio The ratio of the resize image.
- *
- * \pre \p input_ has to be initialized.
- * \pre \p ratio >= 1.
- *
- * \return The resized image.
- */
- template <typename I>
- mln_concrete(I)
- resize(const Image<I>& input_, const unsigned ratio);
-
-# ifndef MLN_INCLUDE_ONLY
-
-
- template <typename I>
- mln_concrete(I)
- resize(const Image<I>& input_, const unsigned ratio)
- {
- trace::entering("mln::geom::resize");
-
- typedef mln_concrete(I) O;
-
- const I input = exact (input_);
-
- std::size_t rows = input.domain().len(0);
- std::size_t cols = input.domain().len(1);
- std::size_t new_rows = ratio * rows;
- std::size_t new_cols = ratio * cols;
-
- O output(new_rows, new_cols);
-
- mln_piter(O) p(output.domain());
-
- for_all(p)
- {
- output(p) = input(point2d(p[0] / ratio, p[1] / ratio)) ? 255 : 0;
- }
-
- trace::exiting("mln::geom::resize");
- return output;
-
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-
- } // end of namespace mln::geom
-
-} // end of namespace mln
-
-
-
-#endif // ! MLN_GEOM_RESIZE_HH
Index: garrigues/ocr/ocr_without_preprocess.cc
--- garrigues/ocr/ocr_without_preprocess.cc (revision 3184)
+++ garrigues/ocr/ocr_without_preprocess.cc (working copy)
@@ -1,90 +0,0 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/window2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/core/image/cast_image.hh>
-
-#include <mln/value/int_u8.hh>
-
-#include "resize.hh"
-#include "enlarge.hh"
-//#include "skeleton.hh"
-#include <mln/linear/gaussian.hh>
-
-#include <mln/trace/all.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/pbm/load.hh>
-#include <mln/io/pbm/save.hh>
-#include <mln/core/alias/w_window2d_float.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/geom/chamfer.hh>
-#include <mln/make/win_chamfer.hh>
-#include <mln/labeling/regional_maxima.hh>
-#include <mln/morpho/dilation.hh>
-
-#include "tesseract_wrap.hh"
-
-// _COMPILATION_
-// g++ -DNDEBUG -O3 -I../../.. ocr.cc -L/usr/lib -ltesseract_full -lpthread
-
-
-// Call tesseract
-// lang: expected language
-
-int main(int argc, char** argv)
-{
- using namespace mln;
- using value::int_u8;
-
- image2d<bool> input;
-
- if (argc < 2)
- {
- std::cerr << "Usage: " << argv[0] << " in.pbm" << std::endl;
- return 1;
- }
-
- mln::border::thickness = 0;
-
- io::pbm::load(input, argv[1]);
-
- {
- image2d<int_u8> tmp = duplicate(cast_image<int_u8>(input));
- float score = 0;
- char* s = tesseract("fra", tmp, &score);
- std::cerr << "Tesseract result: (score " << score << ")" << std::endl;
- std::cout << s;
- delete[] s;
- }
-}
Index: garrigues/ocr/skeleton.old.hh
--- garrigues/ocr/skeleton.old.hh (revision 3184)
+++ garrigues/ocr/skeleton.old.hh (working copy)
@@ -1,612 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-#ifndef SKELETON_HH
-# define SKELETON_HH
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <sandbox/aroumougame/skeleton/sedt.hh>
-
-#include <mln/core/site_set/p_set.hh>
-#include <mln/math/sqrt.hh>
-#include <mln/opt/at.hh>
-
-namespace mln
-{
-
-
-template <typename P>
- std::vector< std::pair< double, P > > remove(std::vector< std::pair< double, P > > Q, P p)
-{
- typename std::vector<std::pair< double, P > >::iterator it;
-
- for(it = Q.begin(); it!=Q.end(); it++)
- {
- if((*it).second==p)
- {
- it = Q.erase(it);
- break;
- }
- }
- return Q;
-}
-template <typename N>
- double distance(N a, N b, N c, N d)
-{
- double dist = sqrt((a-c)*(a-c)+(b-d)*(b-d));
- return dist;
-}
-template <typename P>
- std::vector< std::pair< double, P > > insertDicho(std::vector< std::pair< double, P > > Q, std::pair< double, P> p)
-{
- int indMin, indMax, indMid;
-
- indMin = 0;
- indMax = Q.size();
-
- if(indMax==0 || Q[indMax-1].first <= p.first)
- Q.push_back(p);
- else
- {
- while(indMax > indMin)
- {
- indMid = int(indMin + (indMax-indMin)/2);
- if(Q[indMid].first < p.first)
- {
- indMin = indMid+1;
- if(Q[indMin].first > p.first)
- {
- indMax = indMid;
- }
- }
- else
- {
- indMax = indMid-1;
- if(Q[indMax].first < p.first)
- {
- indMin = indMid;
- }
- }
- }
-
- typename std::vector< std::pair< double, P > >::iterator it=Q.begin();
- it = Q.insert ( it+indMin, p);
- }
-
- return Q;
-}
-
-
-const neighb2d& complement_neighborhood(const Neighborhood<neighb2d>& nbh)
-{
- if(&nbh == &c4())
- return c8();
- return c4();
-}
-
-template <typename N>
- int nb_composant_connexe(p_set< mln_psite(N) > X_full,const Neighborhood<N>& nbh_,const mln_psite(N)& p_ref, bool local)
-{
- N nbh = exact(nbh_);
- p_set< mln_psite(N) > X;
- if(local)
- {
- mln_niter(N) n(max_neighborhood(nbh), p_ref);
-
- for_all(n)
- {
- if (X_full.has(n))
- X.insert(n);
- }
- }
- else
- {
- X = X_full;
- }
-
- int T;
- p_set< mln_psite(N) > done;
- p_set< mln_psite(N) > neighbors;
- p_set< mln_psite(N) > composant;
-
- done.insert(p_ref);
- mln_niter(N) q(nbh, p_ref);
- for_all(q)
- {
- if (X.has(q)&&!done.has(q))
- {
- neighbors.insert(q);
- }
- }
-// std::cout << "nb_composant_connexe: neighbors " << neighbors.nsites() <<std::endl;
- if(neighbors.nsites()<=1)
- {
- return neighbors.nsites();
- }
- else
- T=0;
-
- while(neighbors.nsites()!=0)
- {
- T++;
- done.insert(neighbors[0]);
- mln_niter(N) t(nbh, neighbors[0]);
- neighbors.remove(neighbors[0]);
- for_all(t)
- {
- if (X.has(t)&&!done.has(t))
- {
- composant.insert(t);
- }
- }
-
- while(composant.nsites()!=0)
- {
- done.insert(composant[0]);
- if(neighbors.has(composant[0]))
- {
- neighbors.remove(composant[0]);
- if(neighbors.nsites()==0)
- return T;
- }
-
- mln_niter(N) r(nbh, composant[0]);
- composant.remove(composant[0]);
- for_all(r)
- {
- if (X.has(r) && !done.has(r))
- {
- composant.insert(r);
- }
- }
- }
- }
- return T;
-}
-
-template <typename N>
- bool simple_point(p_set< mln_psite(N) > X,const Neighborhood<N>& nbh, p_set< mln_psite(N) > X_complement, const mln_psite(N)& p_ref, bool local)
-{
- int nX = nb_composant_connexe(X,exact(nbh),p_ref,local);
- int nX_complement = nb_composant_connexe(X_complement,complement_neighborhood(exact(nbh)),p_ref,local);
-
- if((nX_complement == 1)&&(nX == 1))
- return true;
- return false;
-}
-
-
- template <typename N>
- p_set<mln_psite(N)> euclideanSkeleton(p_set<mln_psite(N)> X, p_set<mln_psite(N)> X_complement, image2d<value::int_u8> dt, p_set<mln_psite(N)>& Y, const Neighborhood<N>& nbh_, bool local)
- {
- std::vector< std::pair< double, mln::point2d> > Q;
- std::vector< std::pair< double, mln::point2d> > R;
- N nbh = exact(nbh_);
-
- // fill Q
- for (uint i = 0; i < X.nsites(); i++)
- {
- if (!Y.has(X[i]))
- {
- std::pair<double, mln_psite(N)> p(math::sqrt(double(dt(X[i]))),X[i]);
- Q = insertDicho(Q,p);
- }
- }
-
- // fill R
- for (uint i = 0; i < X.nsites(); i++)
- {
- if (!Y.has(X[i]))
- {
- double min = 1023.99;
- mln_niter(N) r(nbh, X[i]);
- for_all(r)
- {
- if (Y.has(r))
- {
- double tmp = distance(r[0], r[1], X[i][0], X[i][1]);
- double d = math::sqrt(double(dt(r)))+(math::sqrt(double(dt(X[i])))-math::sqrt(double(dt(r))))/tmp;
- min = math::min(min,d);
- }
- }
- if (min!=1023.99)
- {
- std::pair<double, mln_psite(N)> p(min,X[i]);
- R = insertDicho(R, p);
- }
- }
- }
-
- while (!Q.empty() || !R.empty())
- {
- mln_psite(N) tmp;
- if (Q[0].first < R[0].first)
- {
- tmp = Q[0].second;
- }
- else
- {
- tmp = R[0].second;
- }
-
- Q = remove(Q, tmp);
- R = remove(R, tmp);
-
- if (!Y.has(tmp) && X.has(tmp))
- {
- if (simple_point(X, nbh, X_complement, tmp, local))
- {
- X.remove(tmp);
- X_complement.insert(tmp);
- }
- else
- {
- Y.insert(tmp);
- mln_niter(N) r(nbh, tmp);
- for_all(r)
- {
- if (!Y.has(r) && X.has(r))
- {
- double dist = distance(r[0], r[1], tmp[0], tmp[1]);
- double d = math::sqrt(double(dt(tmp)))+(math::sqrt(double(dt(r)))-math::sqrt(double(dt(tmp))))/dist;
- std::pair<double, mln_psite(N)> p(d,r);
- R = insertDicho(R, p);
- }
- }
-
- }
- }
-
- }
- return X;
- }
-
-
- p_set<point2d> EP(image2d<value::int_u8> dt, point2d x, std::vector< std::vector<std::pair< int, int> > > lut, const neighb2d& nbh)
- {
- p_set<point2d> EP;
- p_set<point2d> tmp;
- int w = geom::ncols(dt);
- int h = geom::nrows(dt);
-
-
- mln_niter_(neighb2d) r(nbh, x);
- for_all(r)
- {
- if (dt(r) <= dt(x))
- {
- for (uint i=0; i<lut[dt(r)].size(); i++)
- {
- if ((r[0]+lut[dt(r)][i].first < h) && (r[1]+lut[dt(r)][i].second < w))
- {
- if (!dt(r+dpoint2d(lut[dt(r)][i].first, lut[dt(r)][i].second)))
- EP.insert(r+dpoint2d(lut[dt(r)][i].first, lut[dt(r)][i].second));
- }
- if ((r[0]-lut[dt(r)][i].first >= 0) && (r[1]-lut[dt(r)][i].second >= 0))
- {
- if (!dt(r+dpoint2d(-lut[dt(r)][i].first, -lut[dt(r)][i].second)))
- EP.insert(r+dpoint2d(-lut[dt(r)][i].first, -lut[dt(r)][i].second));
- }
- if ((r[0]+lut[dt(r)][i].first < h) && (r[1]-lut[dt(r)][i].second >= 0))
- {
- if (!dt(r+dpoint2d(lut[dt(r)][i].first, -lut[dt(r)][i].second)))
- EP.insert(r+dpoint2d(lut[dt(r)][i].first, -lut[dt(r)][i].second));
- }
- if ((r[0]-lut[dt(r)][i].first >= 0) && (r[1]+lut[dt(r)][i].second < w))
- {
- if (!dt(r+dpoint2d(-lut[dt(r)][i].first, lut[dt(r)][i].second)))
- EP.insert(r+dpoint2d(-lut[dt(r)][i].first, lut[dt(r)][i].second));
- }
- if ((r[0]+lut[dt(r)][i].second < h) && (r[1]+lut[dt(r)][i].first < w))
- {
- if (!dt(r+dpoint2d(lut[dt(r)][i].second, lut[dt(r)][i].first)))
- EP.insert(r+dpoint2d(lut[dt(r)][i].second, lut[dt(r)][i].first));
- }
- if ((r[0]-lut[dt(r)][i].second >= 0) && (r[1]-lut[dt(r)][i].first >= 0))
- {
- if (!dt(r+dpoint2d(-lut[dt(r)][i].second, -lut[dt(r)][i].first)))
- EP.insert(r+dpoint2d(-lut[dt(r)][i].second, -lut[dt(r)][i].first));
- }
- if ((r[0]+lut[dt(r)][i].second < h) && (r[1]-lut[dt(r)][i].first >= 0))
- {
- if (!dt(r+dpoint2d(lut[dt(r)][i].second, -lut[dt(r)][i].first)))
- EP.insert(r+dpoint2d(lut[dt(r)][i].second, -lut[dt(r)][i].first));
- }
- if ((r[0]-lut[dt(r)][i].second >= 0) && (r[1]+lut[dt(r)][i].first < w))
- {
- if (!dt(r+dpoint2d(-lut[dt(r)][i].second, lut[dt(r)][i].first)))
- EP.insert(r+dpoint2d(-lut[dt(r)][i].second, lut[dt(r)][i].first));
- }
- }
- }
- }
-
- return EP;
- }
-
- std::vector< std::vector<std::pair< int, int> > > Lut2d(int N)
- {
- int n = int(sqrt(N))+1;
- int i=0;
- std::vector< std::vector<std::pair< int, int> > > lut;
-
- for(i = 0; i <= N; i++)
- {
- std::vector<std::pair< int, int> > vect;
- lut.push_back(vect);
- }
-
- for(int x = 0; x <= n; x++)
- {
- for(int y = 0; y <= x; y++)
- {
- i=x*x+y*y;
- if(i<=N)
- {
- std::pair<int,int> p(x,y);
- lut[i].push_back(p);
- }
- }
- }
-
- return lut;
-}
-
- image2d<value::int_u8> DiscreteBisector(image2d<value::int_u8> dt, p_set<point2d> Y, const neighb2d& nbh, int N)
- {
- int w = geom::ncols(dt);
- int h = geom::nrows(dt);
-
- int ux,uy,vx,vy, produit, angle, max;
- double cos, normu, normv;
-
- std::vector< std::vector<std::pair< int, int> > > lut;
- lut = Lut2d(N);
-
- p_set<point2d> proj;
-
- image2d<value::int_u8> bisector(h, w);
- data::fill(bisector, 0);
-
- for (uint i=0; i<Y.nsites(); i++)
- {
- proj = EP(dt, Y[i], lut, nbh);
-
- int n=proj.nsites();
-
- if (n>1)
- {
- max = 0;
- for (int y=0; y<n; y++)
- {
- for (int z=0; z<y; z++)
- {
- ux = proj[y][0]-Y[i][0];
- uy = proj[y][1]-Y[i][1];
- vx = proj[z][0]-Y[i][0];
- vy = proj[z][1]-Y[i][1];
-
- produit = ux * vx + uy * vy;
-
- normu = sqrt(ux*ux + uy*uy);
- normv = sqrt(vx*vx + vy*vy);
-
- cos = produit/(normu*normv);
- angle = int(acos(cos)*180.0/3.1415);
-
- max = math::max(max, angle);
- }
- }
- bisector(Y[i]) = max;
- }
-
- }
-
- return bisector;
-
- }
-
-
-
-const neighb2d& max_neighborhood(const Neighborhood<neighb2d>& nbh)
-{
- return c8();
-}
-template <typename N>
- p_set<mln_psite(N)> ultimateSkeleton(p_set<mln_psite(N)> X, p_set<mln_psite(N)> X_complement, image2d<value::int_u8> dt, p_set<mln_psite(N)> Y, const Neighborhood<N>& nbh_, bool local)
-{
- std::vector< std::pair< double, mln::point2d> > Q;
-
- N nbh = exact(nbh_);
- // fill Q
- for(uint i = 0; i < X.nsites(); i++)
- {
- if (!Y.has(X[i]))
- {
- std::pair<double, mln_psite(N)> p(dt(X[i]),X[i]);
- Q = insertDicho(Q,p);
- }
- }
-
-
- while(!Q.empty())
- {
- mln_psite(N) tmp = Q[0].second;
-
- Q = remove(Q, tmp);
-
- if(simple_point(X, nbh, X_complement, tmp, local))
- {
- X.remove(tmp);
- X_complement.insert(tmp);
- mln_niter(N) r(nbh, tmp);
- for_all(r)
- {
- if(!Y.has(r) && X.has(r))
- {
- std::pair<double, mln_psite(N)> p(dt(r),r);
- Q = insertDicho(Q, p);
- }
- }
- }
-
- }
- return X;
-}
-
- image2d<value::int_u8> intImage(image2d<bool> pic)
-{
- int w = geom::ncols(pic);
- int h = geom::nrows(pic);
-
- image2d<value::int_u8> out(h,w);
- for(int i=0; i<w; i++)
- for(int j=0; j<h; j++)
- {
- if(opt::at(pic, j,i))
- opt::at(out, j,i) = 1;
- else
- opt::at(out, j,i) = 0;
- }
- return out;
-}
- image2d<bool> filteredSkeleton(image2d<bool> pic, const neighb2d& nbh, uint r, uint alpha, bool local)
- {
- using value::int_u8;
-
- typedef image2d<bool> I;
- typedef p_set<point2d> S;
-
- image2d<value::int_u8> pic1 = intImage(pic);
- image2d<value::int_u8> dt = sedt(pic1);
-
- mln::io::pgm::save(dt, "dt.pgm");
-
- int w = geom::ncols(pic);
- int h = geom::nrows(pic);
- int l= math::min(w, h);
- uint rmax = getRMax(dt);
- uint rknown = 0;
- p_set<point2d> X,Y,Z;
- p_set<point2d> X_complement, Z_complement;
-
- image2d<value::int_u8> DTg(l,l,0);
- std::vector< std::vector<int> > Mgl;
- std::vector< std::vector<int> > Lut;
-
- Mgl = CompLutMask (DTg,Mgl,Lut,l,0,rmax);
-
- rknown =rmax;
-
- mln_fwd_piter_(image2d<bool>) p(pic.domain());
-
- for_all(p)
- {
- if (pic(p)==1)
- {
- X.insert(p);
- }
- else
- {
- X_complement.insert(p);
- }
- }
- std::cout << " medial axis " << std::endl;
- pic = MA(pic, Mgl, dt, Lut);
-
- mln::io::pbm::save(pic, "ma.pbm");
-
- for_all(p)
- {
- if (pic(p)==1)
- {
- Y.insert(p);
- }
- }
-
- std::cout << " euclidean skeleton " << std::endl;
- Z = euclideanSkeleton(X, X_complement, dt, Y, nbh, local);
-
- sub_image<I, S> es = pic | Z;
- I es1(pic.domain());
- data::fill(es1, false);
-
- data::paste(es, es1);
-
- mln::io::pbm::save(es1, "euclidean.pbm");
-
- for_all(p)
- {
- if (!Z.has(p))
- {
- Z_complement.insert(p);
- }
- }
- std::cout << " discrete bisector " << std::endl;
- pic1 = DiscreteBisector(dt, Y, nbh, rmax);
-
-
- mln::io::pgm::save(pic1, "bisector.pgm");
-
- uint cpt=0;
- while (cpt!=Y.nsites())
- {
- if (dt(Y[cpt])>=r && pic1(Y[cpt])>=alpha)
- {
- cpt++;
- }
- else
- {
- Y.remove(Y[cpt]);
- }
- }
-
-
- sub_image<I, S> skel = pic | Y;
- I test(pic.domain());
- data::fill(test, false);
-
- data::paste(skel, test);
-
- mln::io::pbm::save(test, "Y.pbm");
-
- std::cout << " ultimate skeleton " << std::endl;
- Z = ultimateSkeleton(Z, Z_complement, dt, Y, nbh, local);
-
-
-
- sub_image<I, S> skeleton = pic | Z;
- I output(pic.domain());
- data::fill(output, false);
-
- data::paste(skeleton, output);
-
- return output;
- }
-
-} // End of namespace mln
-#endif // ! SKELETON_HH
Index: garrigues/ocr/simple_point.hh
--- garrigues/ocr/simple_point.hh (revision 3184)
+++ garrigues/ocr/simple_point.hh (working copy)
@@ -1,206 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef MLN_SIMPLE_POINT_HH
-# define MLN_SIMPLE_POINT_HH
-
-/*! \file simple_point.hh
- *
- * \brief is_simple_point tell if a point is simple or not (Cf
- * bertrand.07.chap).
- *
- */
-
-#include <mln/core/alias/point2d.hh>
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-namespace mln
-{
-
-/*! Tell if a point is simple or not. A point of an object is simple
- * if in its c8 neiborhood, there is exactly one connected component of the
- * object, and only one connected component of the background
- * Examples : ( | == object, - = background)
- *
- * - - |
- * | P | Here p is simple in the c4 and c8 case.
- * | | |
- *
- * - | -
- * | P | Here p is never simple.
- * | | |
- *
- */
-
- bool is_simple_point(const image2d<bool>& ima, const neighb2d& nbh, const point2d& p);
-
- unsigned nb_connexity2d(const image2d<bool>& ima, const neighb2d& nbh, const point2d& p);
-
- bool is_curve_extremum(const image2d<bool>& ima, unsigned nbh, const point2d& p);
-
-# ifndef MLN_INCLUDE_ONLY
-
- static const unsigned char nb_connexity_c8[256] =
- {
- 0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1,
- 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1,
- 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
- 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1,
-
- 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
- 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
- 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2,
- 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1,
- 2, 3, 3, 3, 3, 4, 3, 3, 2, 2, 2, 2, 3, 3, 2, 2,
- 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1,
-
- 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
- 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
- 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
- };
-
- static const unsigned char nb_connexity_c4[256] =
- {
- 0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 2, 1,
- 1, 2, 2, 2, 1, 2, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
- 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 1,
- 2, 3, 3, 3, 2, 3, 2, 2, 2, 2, 3, 2, 2, 2, 2, 1,
-
- 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, 3, 3, 2,
- 2, 3, 3, 3, 2, 3, 2, 2, 3, 3, 4, 3, 3, 3, 3, 2,
- 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 1,
- 2, 3, 3, 3, 2, 3, 2, 2, 2, 2, 3, 2, 2, 2, 2, 1,
-
- 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, 3, 3, 2,
- 1, 2, 2, 2, 1, 2, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
- 2, 3, 3, 3, 3, 4, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2,
- 2, 3, 3, 3, 2, 3, 2, 2, 2, 2, 3, 2, 2, 2, 2, 1,
-
- 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, 3, 3, 2,
- 1, 2, 2, 2, 1, 2, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1,
- 1, 2, 2, 2, 2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 1,
- 1, 2, 2, 2, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1
- };
-
- neighb2d int_to_neighb(unsigned i)
- {
- if (i == 8)
- return c8();
- if (i == 4)
- return c4();
- mln_assertion(0);
- return c4();
- }
-
- unsigned complement_neighb(unsigned i)
- {
- if (i == 8)
- return 4;
- if (i == 4)
- return 8;
- mln_assertion(0);
- return 0;
- }
-
- unsigned nb_connexity2d(const image2d<bool>& ima, unsigned nbh, const point2d& p, bool object)
- {
- unsigned res = 0;
-
- mln_bkd_niter_(neighb2d) n(c8() , p);
- for_all(n)
- {
- res = (res << 1);
- if (ima.domain().has(n) && ima(n) == object)
- res = res | 1;
- }
-
- if (nbh == 8)
- return nb_connexity_c8[res];
- else
- {
- mln_assertion(nbh == 4);
- return nb_connexity_c4[res];
- }
- }
-
- bool is_curve_extremum(const image2d<bool>& ima, unsigned nbh_i, const point2d& p_, unsigned deep)
- {
-// return false;
- unsigned cpt = 0;
- mln_site_(image2d<bool>) next = p_;
- mln_site_(image2d<bool>) p = next;
- mln_niter_(neighb2d) n(int_to_neighb(nbh_i) , p);
-
- p = next;
- for_all(n)
- {
- if (ima.domain().has(n) && ima(n) == true)
- {
- next = n;
- cpt++;
- }
- }
- if (cpt != 1)
- return false;
-
- for (unsigned i = 0; i < deep - 1; i++)
- {
- cpt = 0;
- p = next;
- for_all(n)
- {
- if (ima.domain().has(n) && ima(n) == true)
- {
- next = n;
- cpt++;
- }
- }
- if (cpt != 2)
- return false;
- }
-
- return true;
- }
-
- bool is_simple_point2d(const image2d<bool>& ima, unsigned nbh, const point2d& p)
- {
- mln_assertion(nbh == 4 || nbh == 8);
-
- return (nb_connexity2d(ima, nbh, p, true) == 1) &&
- (nb_connexity2d(ima, complement_neighb(nbh), p, false) == 1);
- }
-
-# endif // MLN_INCLUDE_ONLY
-
-} // end of namespace mln
-
-#endif // ! MLN_SIMPLE_POINT_HH
Index: garrigues/ocr/skeleton.hh
--- garrigues/ocr/skeleton.hh (revision 3184)
+++ garrigues/ocr/skeleton.hh (working copy)
@@ -1,200 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef MLN_SKELETON_HH
-# define MLN_SKELETON_HH
-
-# include <iomanip>
-# include <iostream>
-# include <sstream>
-
-# include <mln/core/var.hh>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/cast_image.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/core/site_set/p_queue_fast.hh>
-# include <mln/core/site_set/p_priority.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/arith/revert.hh>
-# include <mln/transform/distance.hh>
-
-# include <mln/make/w_window2d_int.hh>
-
-# include <mln/data/fill.hh>
-
-# include <mln/debug/println.hh>
-
-# include <mln/logical/not.hh>
-
-# include "simple_point.hh"
-
-#include <mln/make/w_window2d_int.hh>
-
-# include <mln/io/pgm/save.hh>
-# include <mln/io/pbm/save.hh>
-
-namespace mln
-{
-
- template <typename V>
- void save_state(const image2d<V>& ima)
- {
- static int id = 0;
- std::stringstream filename;
-
- std::cout << id << std::endl;
- filename << "skel_trace_" << std::setw(5) << std::setfill('0')
- << std::right << id++ << ".ppm";
-
- io::pbm::save(ima, filename.str());
- }
-
- image2d<bool> crest(const image2d<bool>& input,
- const image2d<value::int_u8>& dist_map,
- const neighb2d& nbh)
- {
- image2d<bool> is_crest;
- initialize(is_crest, input);
- data::fill(is_crest, false);
-
- mln_piter_(image2d<bool>) p(input.domain());
- mln_niter_(neighb2d) n(nbh, p);
- for_all(p)
- {
- if (!input(p) || dist_map(p) < 0)
- continue;
-
- unsigned nb_eq = 0;
- unsigned nb_gt = 0;
- unsigned nb_lt = 0;
- for_all(n)
- if (input.domain().has(n))
- {
- if (dist_map(n) == dist_map(p))
- nb_eq++;
- else if (dist_map(n) > dist_map(p))
- nb_gt++;
- else
- nb_lt++;
- }
-
-
-// if ((nb_gt == 1 && nb_eq == 0) ||
-// (nb_gt == 0))
-
- if ((nb_lt + nb_eq) > 5) // Pixel Superiority index
- is_crest(p) = true;
- }
- return is_crest;
- }
-
-
- image2d<bool>
- skeleton_with_constraint(const image2d<bool>& input,
- unsigned nbh_i,
- const image2d<bool>& K,
- const image2d<value::int_u8>& priority)
- {
- mln_assertion(nbh_i == 4 || nbh_i == 8);
-
- neighb2d nbh = int_to_neighb(nbh_i);
- image2d<bool> output;
- initialize(output, input);
-
- typedef mln_site_(image2d<bool>) P;
- p_priority<value::int_u8, p_queue_fast<P> > q;
-
- // Initialization.
- {
- p_priority<value::int_u8, p_queue_fast<P> > q_tmp;
-
- data::fill(output, input);
- mln_piter_(image2d<bool>) p(input.domain());
- for_all(p)
- if (!input(p) &&
- is_simple_point2d(input, nbh_i, p)) // p is a simple point of background
- q.push(priority(p), p);
- }
-
- // Propagation.
- {
- P p;
- mln_niter_(neighb2d) n(nbh, p);
- while (! q.is_empty())
- {
- p = q.pop_front();
-
- for_all(n)
- if (output.domain().has(n) &&
- output(n) &&
- K(n) == false &&
- is_simple_point2d(output, nbh_i, n)
- // && // n is simple
- // !is_curve_extremum(output, nbh_i, n, 1)
- )
- {
- output(n) = false; // Remove n from object
- // save_state(output);
- q.push(priority(n), n);
- }
- }
- }
-
- return output;
- }
-
-
- image2d<bool>
- skeleton(const image2d<bool>& input, unsigned nbh_i)
- {
- mln_assertion(nbh_i == 4 || nbh_i == 8);
- neighb2d nbh = int_to_neighb(nbh_i);
-
- int vals[] = { 0, 9, 0, 9, 0,
- 9, 6, 4, 6, 9,
- 0, 4, 0, 4, 0, // Values of distances.
- 9, 6, 4, 6, 9,
- 0, 9, 0, 9, 0 };
-
- image2d<value::int_u8> dist_map_n = transform::distance(value::int_u8(), logical::not_(input), nbh, make::w_window2d_int(vals));
- image2d<value::int_u8> dist_map = arith::revert(dist_map_n);
-
- io::pgm::save(dist_map, "distance.pgm");
- io::pgm::save(dist_map_n, "distance_n.pgm");
-
- // Make K
- image2d<bool> K = crest(input, dist_map_n, nbh);
- io::pbm::save(K, "K.pbm");
-
- return skeleton_with_constraint(input, nbh_i, K, dist_map);
- }
-
-} // end of namespace mln
-
-#endif
Index: garrigues/ocr/check_simple_point.cc
--- garrigues/ocr/check_simple_point.cc (revision 3184)
+++ garrigues/ocr/check_simple_point.cc (working copy)
@@ -1,61 +0,0 @@
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/labeling/blobs.hh>
-#include <mln/data/fill.hh>
-#include <mln/debug/println.hh>
-#include "simple_point.hh"
-
-
-int main()
-{
- using namespace mln;
- using namespace mln::value;
-
- typedef image2d<bool> I;
- image2d<bool> ima(3,3);
- point2d p(1,1);
-
- std::cout << "----- Object in C8 ------" << std::endl;
-
- for (unsigned i = 0; i < 256; i++)
- {
- data::fill(ima, false);
- int_u8 tmp = i;
-
- mln_niter_(neighb2d) n(c8() , p);
- for_all(n)
- {
- if (tmp % 2)
- ima(n) = true;
- tmp = tmp >> 1;
- }
-
- unsigned x;
- labeling::blobs(ima, c8(), x);
-
- mln_assertion(nb_connexity2d(ima, 8, p, true) == x);
- }
-
- std::cout << "----- Object in C4 ------" << std::endl;
-
- for (unsigned i = 0; i < 256; i++)
- {
- data::fill(ima, false);
- int_u8 tmp = i;
-
- mln_niter_(neighb2d) n(c8() , p);
- for_all(n)
- {
- if (tmp % 2)
- ima(n) = true;
- tmp = tmp >> 1;
- }
-
-
- unsigned x;
- labeling::blobs(ima, c4(), x);
-
- mln_assertion(nb_connexity2d(ima, 4, p, true) == x);
- }
-}
Index: garrigues/ocr/compute_local_configurations.cc
--- garrigues/ocr/compute_local_configurations.cc (revision 3184)
+++ garrigues/ocr/compute_local_configurations.cc (working copy)
@@ -1,74 +0,0 @@
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/labeling/blobs.hh>
-#include <mln/data/fill.hh>
-#include <mln/debug/println.hh>
-#include <iomanip>
-
-
-int main()
-{
- using namespace mln;
- using value::int_u8;
-
- typedef image2d<bool> I;
-
- box2d b = make::box2d(-1,-1, 1,1);
- image2d<bool> ima(b, 0);
- point2d p(0, 0);
-
- std::vector<int_u8> x8(256), x4(256);
-
-
- for (unsigned i = 0; i < 256; i++)
- {
- data::fill(ima, false);
-
- int_u8 tmp = i;
- mln_fwd_niter_(neighb2d) n(c8(), p);
- for_all(n)
- {
- if (tmp % 2)
- ima(n) = true;
- tmp = tmp >> 1;
- }
-
- labeling::blobs(ima, c8(), x8[i]);
-
- {
- int_u8 nl;
- image2d<int_u8> lab = labeling::blobs(ima, c4(), nl);
- std::set<int_u8> s;
- mln_fwd_niter_(neighb2d) n(c4(), p);
- for_all(n)
- if (lab(n) != 0)
- s.insert(lab(n));
- x4[i] = s.size();
- }
- }
-
-
- // Now printing!
-
- std::cout << "----- Object in C8 ------" << std::endl;
-
- for (unsigned i = 0; i < 256; i++)
- {
- std::cout << std::setw(2) << x8[i] << ", ";
- if (! ((i + 1) % 4)) std::cout << " ";
- if (! ((i + 1) % 16)) std::cout << std::endl;
- if (! ((i + 1) % 64)) std::cout << std::endl;
- }
-
- std::cout << "----- Object in C4 ------" << std::endl;
-
- for (unsigned i = 0; i < 256; i++)
- {
- std::cout << std::setw(2) << x4[i] << ", ";
- if (! ((i + 1) % 4)) std::cout << " ";
- if (! ((i + 1) % 16)) std::cout << std::endl;
- if (! ((i + 1) % 64)) std::cout << std::endl;
- }
-
-}
Index: garrigues/ocr/tesseract_wrap.hh
--- garrigues/ocr/tesseract_wrap.hh (revision 3184)
+++ garrigues/ocr/tesseract_wrap.hh (working copy)
@@ -1,91 +0,0 @@
-#ifndef TESSERACT_WRAP_HH
-# define TESSERACT_WRAP_HH
-
-# include <cassert>
-
-# include <mln/core/image/image2d.hh>
-
-# include <tesseract/baseapi.h>
-
-struct TessWrap : public TessBaseAPI
-{
- static int InitWithLanguage(const char* datapath, const char* outputbase,
- const char* language, const char* configfile,
- bool numeric_mode, int argc, char* argv[])
- {
- return TessBaseAPI::InitWithLanguage(datapath, outputbase,
- language, configfile,
- numeric_mode, argc, argv);
- }
-
- static char* TesseractRect(const unsigned char* imagedata,
- int bytes_per_pixel,
- int bytes_per_line,
- int left, int top, int width, int height,
- float* score)
- {
- int kMinRectSize = 10; // Quick and dirty... (value imported from tesseract src)
- if (width < kMinRectSize || height < kMinRectSize)
- return NULL; // Nothing worth doing.
-
- // Copy/Threshold the image to the tesseract global page_image.
- CopyImageToTesseract(imagedata, bytes_per_pixel, bytes_per_line,
- left, top, width, height);
-
- { // RecognizeToString
- BLOCK_LIST* block_list = FindLinesCreateBlockList();
- PAGE_RES* page_res = Recognize(block_list, NULL);
-
- char* string;
- int* lengths;
- float* costs;
- int* x0;
- int* y0;
- int* x1;
- int* y1;
- // Retrieve Tesseract internal data to compute the quality score.
- int n = TessBaseAPI::TesseractExtractResult(&string, &lengths, &costs, &x0, &y0, &x1, &y1, page_res);
-
- float average_uncertainty = 0.f;
- for (int i = 0; i < n; ++i)
- average_uncertainty += costs[i];
-
- if (n)
- *score = average_uncertainty / n;
- else
- *score = -1;
-
- // Some memory cleanup
- delete[] string;
- delete[] lengths;
- delete[] costs;
- delete[] x0;
- delete[] y0;
- delete[] x1;
- delete[] y1;
-
- return TesseractToText(page_res);
- }
- }
-};
-
-// Call tesseract
-// lang: expected language
-template <typename T>
-char* tesseract(const char* lang, const mln::image2d<T>& input, float* score)
-{
- assert(score);
- TessWrap::InitWithLanguage(NULL, NULL, lang, NULL, false, 0, NULL);
- char* s = TessWrap::TesseractRect(
- (unsigned char*) input.buffer(),
- sizeof (T),
- input.ncols() * sizeof (T),
- 0, 0,
- input.ncols(),
- input.nrows(),
- score);
- return s;
-}
-
-
-#endif // ! TESSERACT_WRAP_HH
Index: garrigues/ocr/skeleton.old.cc
--- garrigues/ocr/skeleton.old.cc (revision 3184)
+++ garrigues/ocr/skeleton.old.cc (working copy)
@@ -1,30 +0,0 @@
-
-#include <mln/core/alias/point2d.hh>
-#include "skeleton.hh"
-#include <mln/data/paste.hh>
-#include <mln/data/fill.hh>
-#include <mln/core/image/sub_image.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/pbm/save.hh>
-#include <mln/io/pbm/load.hh>
-
-
-int main(int argc, char* argv[])
-{
- if(argc!=5)
- {
- std::cout << "arguments: filename voisinage R alpha" << std::endl;
- exit(1);
- }
- image2d<bool> output;
- std::string filename = argv[1];
- int r = atoi(argv[3]);
- int alpha = atoi(argv[4]);
-
- image2d<bool> pic = io::pbm::load(filename);
- if(atoi(argv[2])==4)
- output = filteredSkeleton( pic, c4(), r, alpha, true);
- else
- output = filteredSkeleton( pic, c8(), r, alpha, true);
- mln::io::pbm::save(output, "FS-"+std::string(argv[2])+"_"+std::string(argv[3])+"_"+std::string(argv[4])+"_"+filename);
-}
Index: garrigues/ocr/check.sh
--- garrigues/ocr/check.sh (revision 3184)
+++ garrigues/ocr/check.sh (working copy)
@@ -1,31 +0,0 @@
-output_dir=tmp/`date '+%y_%m_%d__%H_%M_%S'`
-mkdir $output_dir
-for i in input/*.pbm ; do
- echo "==========================================="
- echo "--------- $i"
- echo "==========================================="
-
- ref="$i.txt"
- echo "______________________________Reference"
- cat $ref
- sed -e 's/\(.\)/\1\n/g' $ref > tmp/ref
- total=`cat tmp/ref | wc -l `
-
- echo "______________________________without preprocessing"
- ./ocr_without_preprocess $i > tmp/without
- cat tmp/without
- cat tmp/without | sed -e 's/\(.\)/\1\n/g' > tmp/without
-
- echo "______________________________with preprocessing"
- ./ocr_with_preprocess $i $output_dir/`basename $i` > tmp/with
- cat tmp/with
- cat tmp/with | sed -e 's/\(.\)/\1\n/g' > tmp/with
-
-
- d_without=`diff ./tmp/without tmp/ref | diffstat | grep insert | sed -r 's/.*, ([0-9]+) insertion.*/\1/g'`
- echo "$(($d_without * 100 / $total))% missmatch without preprocessing"
-
- d_with=`diff ./tmp/with tmp/ref | diffstat | grep insert | sed -r 's/.*, ([0-9]+) insertion.*/\1/g'`
- echo "$(($d_with * 100 / $total))% missmatch with preprocessing"
- echo ""
-done
Index: garrigues/ocr/simple_point.cc
--- garrigues/ocr/simple_point.cc (revision 3184)
+++ garrigues/ocr/simple_point.cc (working copy)
@@ -1,39 +0,0 @@
-# include <mln/core/image/image2d.hh>
-# include <mln/io/pbm/load.hh>
-# include <mln/io/pbm/save.hh>
-# include <mln/data/fill.hh>
-
-# include "simple_point.hh"
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pbm output.pbm" << std::endl;
- abort();
-}
-
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc != 3)
- usage(argv);
-
- typedef image2d<bool> I;
- I input;
- io::pbm::load(input, argv[1]);
-
- I output;
- initialize(output, input);
- data::fill(output, false);
-
- mln_piter_(I) p(input.domain());
- for_all(p)
- if (input(p) && simple_point2d(input, 4, p))
- output(p) = true;
-
- io::pbm::save(output, argv[2]);
-}
Index: garrigues/ocr/ocr_with_preprocess.cc
--- garrigues/ocr/ocr_with_preprocess.cc (revision 3184)
+++ garrigues/ocr/ocr_with_preprocess.cc (working copy)
@@ -1,170 +0,0 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/window2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/core/image/cast_image.hh>
-
-#include <mln/value/int_u8.hh>
-
-#include "resize.hh"
-#include "enlarge.hh"
-#include "skeleton.hh"
-
-#include <mln/linear/gaussian.hh>
-
-#include <mln/trace/all.hh>
-
-#include <mln/fun/p2v/ternary.hh>
-#include <mln/pw/image.hh>
-
-#include <mln/debug/println.hh>
-#include <mln/labeling/regional_maxima.hh>
-#include <mln/morpho/dilation.hh>
-#include <mln/win/octagon2d.hh>
-#include <mln/border/resize.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/pbm/load.hh>
-#include <mln/io/pbm/save.hh>
-#include <mln/logical/not.hh>
-
-#include "tesseract_wrap.hh"
-#include <mln/subsampling/subsampling.hh>
-
-// _COMPILATION_
-// g++ -DNDEBUG -O3 -I../../.. ocr.cc -L/usr/lib -ltesseract_full -lpthread
-
-// image2d<int_u8> tmp = duplicate(cast_image<int_u8>(Var)); \
-
-#if 1
-# define OCR_TEST(Var) \
- { \
- float score = 0.f; \
- char* s = tesseract("fra", Var, &score); \
- std::cerr << #Var << ": " << score << std::endl << s; \
- delete[] s; \
- }
-#else
-# define OCR_TEST(Var)
-#endif
-
-
-int main(int argc, char** argv)
-{
- using namespace mln;
- using value::int_u8;
-
- image2d<bool> input;
-
- if (argc < 2)
- {
- std::cerr << "Usage: " << argv[0] << " in.pbm out.pbm" << std::endl;
- return 1;
- }
-
- mln::border::thickness = 0;
-
- io::pbm::load(input, argv[1]);
-
- // Resize
- image2d<int_u8> enlarged = enlarge(logical::not_(input), 2);
- image2d<bool> big = geom::resize(logical::not_(input), 4);
- io::pgm::save(enlarged, std::string(argv[2]) + "_1_enlarge.pgm");
- OCR_TEST(enlarged);
-
- // Blur.
- image2d<int_u8> blur = linear::gaussian(enlarged, 2);
- io::pgm::save(blur, std::string(argv[2]) + "_2_gaussian.pgm");
- OCR_TEST(blur);
-
-// // Threshold
-// image2d<bool> binary;
-// {
-// initialize(binary, blur);
-// mln_piter_(image2d<int_u8>) p(blur.domain());
-// for_all(p)
-// binary(p) = blur(p) > 100;
-
-// io::pbm::save(binary, std::string(argv[2]) + "_3_threshold.pbm");
-// OCR_TEST(binary);
-// }
-
-// // Skeleton
-// image2d<bool> skel = skeleton(binary, 4);
-// io::pbm::save(skel, std::string(argv[2]) + "_4_skeleton.pbm");
-// OCR_TEST(skel);
-
-// // Dilation
-// win::octagon2d oct(5);
-// image2d<bool> dilate = morpho::dilation(skel, oct);
-// border::resize(dilate, 0);
-// io::pbm::save(dilate, std::string(argv[2]) + "_5_dilation.pbm");
-// OCR_TEST(dilate);
-
-// // Subsampling
-// image2d<bool> subsampled = subsampling::subsampling(dilate, dpoint2d(1,1), 2);
-// io::pbm::save(subsampled, std::string(argv[2]) + "_6_subsampling.pbm");
-// OCR_TEST(subsampled);
-
-// io::pbm::save(subsampled, argv[2]);
-
-
- image2d<bool> K = crest(big, blur, c8());
- OCR_TEST(K);
- io::pbm::save(K, std::string(argv[2]) + "_6_K.pbm");
-
- image2d<bool> skel_on_gaussian = skeleton_with_constraint(big, 8, K, arith::revert(blur));
- OCR_TEST(skel_on_gaussian);
- io::pbm::save(skel_on_gaussian, std::string(argv[2]) + "_7_skeleton_on_gaussian.pbm");
-
- // Dilation
- win::octagon2d oct(5);
- image2d<bool> dilate_on_gaussian = morpho::dilation(skel_on_gaussian, oct);
- border::resize(dilate_on_gaussian, 0);
- io::pbm::save(dilate_on_gaussian, std::string(argv[2]) + "_8_dilation_on_gaussian.pbm");
- OCR_TEST(dilate_on_gaussian);
-
- // Subsampling
- image2d<bool> subsampled_on_gaussian = subsampling::subsampling(dilate_on_gaussian, dpoint2d(1,1), 2);
- io::pbm::save(subsampled_on_gaussian, std::string(argv[2]) + "_9_subsampling_on_gaussian.pbm");
- OCR_TEST(subsampled_on_gaussian);
-
- {
- float score = 0;
- char* s = tesseract("fra", subsampled_on_gaussian, &score);
- std::cerr << "Tesseract result: (score " << score << ")" << std::endl;
- std::cout << s;
- delete[] s;
- }
-
-}
Index: garrigues/ocr/enlarge.hh
--- garrigues/ocr/enlarge.hh (revision 3184)
+++ garrigues/ocr/enlarge.hh (working copy)
@@ -1,202 +0,0 @@
-# include <iostream>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/routine/initialize.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/fun/p2v/ternary.hh>
-
-# include <mln/pw/image.hh>
-# include <mln/pw/cst.hh>
-# include <mln/pw/value.hh>
-# include <mln/opt/at.hh>
-
-# include <mln/core/routine/duplicate.hh>
-
-
-float val(bool b) { return b ? 1 : 0; }
-
-int do_threshold(float value)
-{
- return 255.f * value;
-}
-
-namespace mln
-{
-
- image2d<value::int_u8>
- enlargex2(const image2d<bool>& input)
- {
- using value::int_u8;
-
- unsigned nrows, ncols;
-
- nrows = input.nrows();
- ncols = input.ncols();
-
- image2d<int_u8> output(2 * nrows, 2 * ncols);
- float value;
-
- // row 0
-
- opt::at(output, 0, 0) = do_threshold(opt::at(input, 0, 0));
-
- for (int col = 2; col < output.ncols(); col += 2)
- {
- value = val(opt::at(input, 0, col / 2));
- value += val(opt::at(input, 0, col / 2 - 1));
- opt::at(output, 0, col) = do_threshold(value / 2);
- }
-
- for (int col = 1; col < output.ncols(); col += 2)
- opt::at(output, 0, col) = do_threshold(opt::at(input, 0, col / 2));
-
- // col 0
-
- for (int row = 2; row < output.nrows(); row += 2)
- {
- value = val(opt::at(input, row / 2, 0));
- value += val(opt::at(input, row / 2 - 1, 0));
- opt::at(output, row, 0) = do_threshold(value / 2);
- }
-
- for (int row = 1; row < output.nrows(); row += 2)
- opt::at(output, row, 0) = do_threshold(opt::at(input, row / 2, 0));
-
- // others
-
- for (int row = 2; row < output.nrows(); row += 2)
- {
- for (int col = 2; col < output.ncols(); col += 2)
- {
- value = val(opt::at(input, row / 2, col / 2));
- value += val(opt::at(input, row / 2 - 1, col / 2));
- value += val(opt::at(input, row / 2, col / 2 - 1));
- value += val(opt::at(input, row / 2 - 1, col / 2 - 1));
- opt::at(output, row, col) = do_threshold(value / 4);
- }
- for (int col = 1; col < output.ncols(); col += 2)
- {
- value = val(opt::at(input, row / 2, col / 2));
- value += val(opt::at(input, row / 2 - 1, col / 2));
- opt::at(output, row, col) = do_threshold(value / 2);
- }
- }
-
- for (int row = 1; row < output.nrows(); row += 2)
- {
- for (int col = 2; col < output.ncols(); col += 2)
- {
- value = val(opt::at(input, row / 2, col / 2));
- value += val(opt::at(input, row / 2, col / 2 - 1));
- opt::at(output, row, col) = do_threshold(value / 2);
- }
- for (int col = 1; col < output.ncols(); col += 2)
- opt::at(output, row, col) = do_threshold(opt::at(input, row / 2, col / 2));
- }
-
- return output;
- }
-
-
-
- image2d<value::int_u8>
- enlargex2(const image2d<value::int_u8>& input)
- {
- using value::int_u8;
-
- unsigned nrows, ncols;
-
- nrows = input.nrows();
- ncols = input.ncols();
-
- image2d<int_u8> output(2 * nrows, 2 * ncols);
- unsigned value;
-
- // row 0
-
- opt::at(output, 0, 0) = (opt::at(input, 0, 0));
-
- for (int col = 2; col < output.ncols(); col += 2)
- {
- value = (opt::at(input, 0, col / 2));
- value += (opt::at(input, 0, col / 2 - 1));
- opt::at(output, 0, col) = (value / 2);
- }
-
- for (int col = 1; col < output.ncols(); col += 2)
- opt::at(output, 0, col) = (opt::at(input, 0, col / 2));
-
- // col 0
-
- for (int row = 2; row < output.nrows(); row += 2)
- {
- value = (opt::at(input, row / 2, 0));
- value += (opt::at(input, row / 2 - 1, 0));
- opt::at(output, row, 0) = (value / 2);
- }
-
- for (int row = 1; row < output.nrows(); row += 2)
- opt::at(output, row, 0) = (opt::at(input, row / 2, 0));
-
- // others
-
- for (int row = 2; row < output.nrows(); row += 2)
- {
- for (int col = 2; col < output.ncols(); col += 2)
- {
- value = (opt::at(input, row / 2, col / 2));
- value += (opt::at(input, row / 2 - 1, col / 2));
- value += (opt::at(input, row / 2, col / 2 - 1));
- value += (opt::at(input, row / 2 - 1, col / 2 - 1));
- opt::at(output, row, col) = ((unsigned(value)+2) / 4);
- }
- for (int col = 1; col < output.ncols(); col += 2)
- {
- value = (opt::at(input, row / 2, col / 2));
- value += (opt::at(input, row / 2 - 1, col / 2));
- opt::at(output, row, col) = (value / 2);
- }
- }
-
- for (int row = 1; row < output.nrows(); row += 2)
- {
- for (int col = 2; col < output.ncols(); col += 2)
- {
- value = (opt::at(input, row / 2, col / 2));
- value += (opt::at(input, row / 2, col / 2 - 1));
- opt::at(output, row, col) = (value / 2);
- }
- for (int col = 1; col < output.ncols(); col += 2)
- opt::at(output, row, col) = (opt::at(input, row / 2, col / 2));
- }
-
- return output;
- }
-
-
-
-
-
-
- // enlarge 2^n times
- image2d<value::int_u8>
- enlarge(const image2d<bool>& input, unsigned int n)
- {
- using value::int_u8;
-
- if (n == 0)
- return duplicate(fun::p2v::ternary(pw::value(input),
- pw::cst(int_u8(255)),
- pw::cst(int_u8(0)))
- | input.domain());
-
- image2d<int_u8> output = enlargex2(input);
-
- while (--n)
- output = enlargex2(output);
-
- return output;
- }
-
-} // mln
Index: garrigues/ocr/Makefile
--- garrigues/ocr/Makefile (revision 3184)
+++ garrigues/ocr/Makefile (working copy)
@@ -1,26 +0,0 @@
-CXXFLAGS=-I../../.. -I${HOME}/local/include
-LFLAGS=-L${HOME}/local/lib -ltesseract_full -lpthread
-
-all: ocr_without_preprocess ocr_with_preprocess
-
-ocr_without_preprocess: ocr_without_preprocess.cc
- g++ -DNDEBUG -O3 ${CXXFLAGS} $< ${LFLAGS} -o $@
-
-ocr_with_preprocess: ocr_with_preprocess.cc
- g++ -DNDEBUG -O3 ${CXXFLAGS} $< ${LFLAGS} -o $@
-clean:
- rm -f *.o ocr_without_preprocess ocr_with_preprocess
-
-logs:
- mkdir logs
-
-tmp:
- mkdir tmp
-
-check: logs tmp ocr_without_preprocess ocr_with_preprocess
- ./check.sh
-
-skeleton: skeleton.cc
- g++ -DNDEBUG -W -Wall -Wextra ${CXXFLAGS} $< -o $@
-
-.PHONY: skeleton
Property changes on: inim/ocr
___________________________________________________________________
Added: svn:mergeinfo
Property changes on: inim/color
___________________________________________________________________
Added: svn:mergeinfo
Property changes on: inim/nature
___________________________________________________________________
Added: svn:mergeinfo
Index: nature/gradient.cc
--- nature/gradient.cc (revision 3184)
+++ nature/gradient.cc (working copy)
@@ -1,60 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/win/rectangle2d.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/morpho/gradient.hh>
-
-
-int main(int argc, const char * argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc < 2) {
- std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
- return 1;
- }
-
- for (int i = 1; i < argc; ++i)
- {
- image2d<int_u8> ima;
- io::pgm::load(ima, argv[i]);
-
- win::rectangle2d rect(5, 5);
- border::thickness = 5;
-
- std::string name(argv[i]);
- name.erase(name.length() - 4);
- io::pgm::save(morpho::gradient(ima, rect), name.append("_grad.pgm"));
- }
-}
Index: nature/closing.cc
--- nature/closing.cc (revision 3184)
+++ nature/closing.cc (working copy)
@@ -1,59 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/win/rectangle2d.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/morpho/closing.hh>
-
-int main(int argc, const char * argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc < 2) {
- std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
- return 1;
- }
-
- for (int i = 1; i < argc; ++i)
- {
- image2d<int_u8> ima;
- io::pgm::load(ima, argv[i]);
-
- win::rectangle2d rect(5, 5);
- border::thickness = 11;
-
- std::string name(argv[i]);
- name.erase(name.length() - 4);
- io::pgm::save(morpho::closing(ima, rect), name.append("_closed.pgm"));
- }
-}
Index: nature/nature.cc
--- nature/nature.cc (revision 3184)
+++ nature/nature.cc (working copy)
@@ -1,498 +0,0 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/cast_image.hh>
-#include <mln/core/image/fun_image.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/io/ppm/load.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/pbm/save.hh>
-
-#include <mln/histo/compute.hh>
-
-#include <mln/level/transform.hh>
-#include <mln/data/paste.hh>
-#include <mln/level/to_enc.hh>
-
-#include <mln/value/rgb8.hh>
-#include <mln/value/hsi.hh>
-
-#include <mln/fun/v2v/rgb_to_hsi.hh>
-#include <mln/fun/meta/hue.hh>
-#include <mln/fun/meta/sat.hh>
-#include <mln/fun/meta/inty.hh>
-
-#include <mln/win/hline2d.hh>
-#include <mln/win/vline2d.hh>
-
-#include <mln/morpho/hit_or_miss.hh>
-#include <mln/morpho/gradient.hh>
-#include <mln/morpho/opening.hh>
-
-#include <mln/binarization/threshold.hh>
-
-#include <mln/estim/mean.hh>
-
-#include <mln/transform/fft.hh>
-
-#include <mln/opt/at.hh>
-
-#include "co_occurence.hh"
-
-#include <math.h>
-
-using namespace mln;
-using namespace value;
-
-enum doctype
- {
- TEXT,
- SCREENSHOT,
- PHOTO,
- DRAWING,
- NB_DOCTYPE
- };
-
-template <typename T>
-unsigned nb_peaks (histo::array<T> &h)
-{
- // First, we compute the maximum, ignoring the first column because it
- // contains nonsense points
-
- unsigned max = 0;
- mln_viter(mln::value::set<T>) v(h.vset());
-
- for_all(v)
- if (((T)v).to_enc() && (h(v) > max))
- max = h(v);
-
- // We take the first value into account
- if (h[0] / 6 > max)
- max = h[0] / 6;
-
- // Now we count the number of peaks over max / 4
- unsigned cpt = 0;
- for_all(v)
- if (h(v) >= max / 4)
- cpt ++;
-
- return cpt;
-}
-
-
-int main (int argc, const char * argv [])
-{
- if (argc != 2) {
- std::cerr << "usage: " << argv[0] << " in.pgm" << std::endl;
- return 1;
- }
-
- unsigned score[NB_DOCTYPE];
- for (unsigned i = 0; i < NB_DOCTYPE; ++i)
- score[i] = 0;
-
- border::thickness = 21;
-
- image2d<rgb8> input;
- io::ppm::load(input, argv[1]);
-
- // First, we get the HSI histograms and corresponding greyscale versions of the picture
-
- image2d<hsi_f> hsi = level::transform(input, fun::v2v::f_rgb_to_hsi_f);
-
- fun_image<mln::meta::hue<hsi_f>, image2d<hsi_f> > hue(hsi);
- fun_image<mln::meta::sat<hsi_f>, image2d<hsi_f> > sat(hsi);
- fun_image<mln::meta::inty<hsi_f>, image2d<hsi_f> > inty(hsi);
-
- cast_image_<float01_8, fun_image<mln::meta::hue<hsi_f>, image2d<hsi_f> > > qhue(hue); // quantified hue
- cast_image_<float01_8, fun_image<mln::meta::sat<hsi_f>, image2d<hsi_f> > > qsat(sat); // quantified sat
- cast_image_<float01_8, fun_image<mln::meta::inty<hsi_f>, image2d<hsi_f> > > qinty(inty); // quantified inty
-
- histo::array<float01_8> hhue = histo::compute(qhue);
- histo::array<float01_8> hsat = histo::compute(qsat);
- histo::array<float01_8> hinty = histo::compute(qinty);
-
-
- // Compute the number of peaks in the histogram to give a first intuition
-
- unsigned n = nb_peaks(hhue) * 3;
-
- if (n > 100)
- n = 100;
-
- score[PHOTO] += n;
- score[SCREENSHOT] += 20 + 80 - n * 80 / 100;
- score[TEXT] += 100 - n;
- score[DRAWING] += 20 + 80 - n * 80 / 100;
-
- std::cout << "Test 1 : peaks number[" << nb_peaks(hhue) << "]" << std::endl
- << "Photo : " << score[PHOTO] << std::endl
- << "Screenshot : " << score[SCREENSHOT] << std::endl
- << "Text : " << score[TEXT] << std::endl
- << "Drawing : " << score[DRAWING] << std::endl << std::endl;
-
-
- // Now we compute the co-occurence matrice
-
- dpoint2d d(0, 1);
- image2d<int_u8> uinty (qinty.domain());
- {
- image2d<unsigned char> tmp = level::transform(qinty, fun::v2v::enc< float01_8 >());
- data::paste(tmp, uinty);
- /* mln_piter_(image2d<unsigned char>) p(tmp.domain());
- for_all(p)
- uinty(p) = tmp(p);
- */
- }
-
- image2d<unsigned> mco (co_occurence(uinty, d));
-
- // If there is a plain background, there will be a massive peak in the diagonal of the matrix
- unsigned max = 0;
- for (unsigned i = 0; i < mco.nrows(); i++)
- if (opt::at(mco, i, i) > max)
- max = opt::at(mco, i, i);
-
- for (unsigned i = 0; i < mco.nrows() - 1; i++) {
- if (opt::at(mco, i + 1, i) > max)
- max = opt::at(mco, i + 1, i);
- if (opt::at(mco, i, i + 1) > max)
- max = opt::at(mco, i, i + 1);
- }
-
- max = max * 100 / input.nelements();
-
- score[PHOTO] += 100 - max;
- score[TEXT] += max * 2;
-
- score[SCREENSHOT] += 80 + max / 2;
- score[DRAWING] += 50 + max / 2;
-
- std::cout << "Test 2 : co-occurence matrix diag_max[" << max << "]" << std::endl
- << "Photo : +" << 100 - max << std::endl;
-
- std::cout << "Screenshot : +" << 80 + max / 2 << std::endl;
-
- std::cout << "Text : +" << max * 2 << std::endl;
-
- std::cout << "Drawing : +" << 80 + max / 2 << std::endl << std::endl;
-
-
-
-
- // A good way to detect screenshots : rectangle detection
-
- // First, we compute the gradient
-
- win::rectangle2d rect(5, 5);
- image2d<int_u8> grad = morpho::gradient(uinty, rect);
-
- // Then, we apply a lot of hit or miss filters !
-
- // Compute the mean
- int_u8 mean = estim::mean(grad);
-
- image2d<bool> imab = binarization::threshold(grad, 10);
-
- window2d winout;
- window2d winin;
-
- static const bool blmatout [] = {0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0};
-
- convert::from_to(blmatout, winout);
-
- static const bool blmatin [] = {0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 1, 1,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
- convert::from_to(blmatin, winin);
-
- image2d<bool> bottom_left = morpho::hit_or_miss(imab, winout, winin);
-
-
- static const bool brmatout [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0};
-
- static const bool brmatin [] = {0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 1, 1, 1, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
-
- convert::from_to(brmatout, winout);
- convert::from_to(brmatin, winin);
- image2d<bool> bottom_right = morpho::hit_or_miss(imab, winout, winin);
-
- static const bool urmatout [] = {0, 0, 0, 0, 0,
- 0, 1, 1, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0};
-
- static const bool urmatin [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 1, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0};
-
-
- convert::from_to(urmatout, winout);
- convert::from_to(urmatin, winin);
- image2d<bool> up_right = morpho::hit_or_miss(imab, winout, winin);
-
- static const bool ulmatout [] = {0, 0, 0, 0, 0,
- 0, 1, 1, 1, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
- static const bool ulmatin [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 1,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0};
-
-
- convert::from_to(ulmatout, winout);
- convert::from_to(ulmatin, winin);
- image2d<bool> up_left = morpho::hit_or_miss(imab, winout, winin);
-
-
- static const bool umatout [] = {0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
- static const bool umatin [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
-
- convert::from_to(umatout, winout);
- convert::from_to(umatin, winin);
- image2d<bool> up = morpho::hit_or_miss(imab, winout, winin);
-
-
- static const bool bmatout [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0};
-
- static const bool bmatin [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
-
- convert::from_to(bmatout, winout);
- convert::from_to(bmatin, winin);
- image2d<bool> bottom = morpho::hit_or_miss(imab, winout, winin);
-
-
- static const bool lmatout [] = {0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0};
-
- static const bool lmatin [] = {0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0};
-
-
- convert::from_to(lmatout, winout);
- convert::from_to(lmatin, winin);
- image2d<bool> left = morpho::hit_or_miss(imab, winout, winin);
-
-
- static const bool rmatout [] = {0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0};
-
- static const bool rmatin [] = {0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0};
-
-
- convert::from_to(rmatout, winout);
- convert::from_to(rmatin, winin);
- image2d<bool> right = morpho::hit_or_miss(imab, winout, winin);
-
- image2d<bool> inter (up_left + up_right + bottom_right + bottom_left + up + bottom + left + right);
-
- image2d<bool> final = morpho::opening(inter, win::hline2d(20));
- final += morpho::opening(inter, win::vline2d(20));
-
- // Now we count blank points in our result
-
- unsigned cpt = 0;
- mln_piter_(image2d<bool>) p (final.domain());
- for_all(p)
- cpt += final(p);
-
- // compute the percentage of blank points
-
- cpt = 1000 * cpt / final.domain().nsites();
-
- if (cpt > 50)
- cpt = 50;
-
- score[PHOTO] += 50 - cpt;
- score[SCREENSHOT] += cpt * 8;
- score[TEXT] += 50 + cpt * max / 3;
- score[DRAWING] += 2 * (60 - cpt);
-
- std::cout << "Test 3 : rectangle detection[" << cpt << "]" << std::endl
- << "Photo : +" << 50 - cpt << std::endl
- << "Screenshot : +" << cpt * 8 << std::endl
- << "Text : +" << 50 + cpt * max / 3 << std::endl
- << "Drawing : +" << 2 * (60 - cpt) << std::endl << std::endl;
-
-
- // Last but not least : text detection thanks to FFT
-
- transform::fft<double> fourier(morpho::opening(uinty, win::hline2d(20)));
- fourier.transform();
-
- std::string name(argv[1]);
- name.erase(name.length() - 4);
- image2d<int_u8> fft = fourier.transformed_image_log_magn<int_u8>(true);
- mln_piter_(image2d<int_u8>) q (fft.domain());
- max = 0;
- for_all(q)
- if (fft(q) > max)
- max = fft(q);
-
- image2d<bool> fftb = binarization::threshold(fft, max * 4 / 10);
-
- // Find the line that best fits the points
-
- unsigned
- center_r = fft.nrows() / 2,
- center_c = fft.ncols() / 2;
-
- double arg = 0, coeff = 0;
-
- for_all(q)
- if (fftb(q))
- {
- double dist =
- (center_c - q.col()) * (center_c - q.col()) +
- (center_r - q.row()) * (center_r - q.row());
-
- if (!dist)
- continue;
-
- double angle = acos (abs(center_r - q.row()) / sqrt(dist));
- while (angle > M_PI)
- angle -= M_PI;
- while (angle < 0)
- angle += M_PI;
-
- arg = (arg * coeff + dist * angle) / (coeff + dist);
-
- coeff += dist;
-
- }
-
- // std::cout << "arg : " << arg << " coeff : " << coeff << std::endl;
- double a = tan(arg);
-
- // Now compute the mean distance of the points to the line
-
- double b = center_c - a * center_r;
- double dist = 0;
- coeff = 0;
-
- for_all(q)
- if (fftb(q))
- {
- double d = abs(a * q.row() - q.col() + b) / sqrt(a * a + 1);
- dist += d * d;
- coeff ++;
- }
-
- dist /= coeff;
-
- dist = dist / (log(fftb.nelements()) / log(10));
-
- score[PHOTO] += dist * 25;
- score[SCREENSHOT] += dist * 50;
- score[TEXT] += (1 + abs(cos(arg))) * (4 - dist) * 40;
- score[DRAWING] += dist * 50;
-
- std::cout << "Test 4 : Fourier distance[" << dist << "]" << std::endl
- << "Photo : +" << dist * 25 << std::endl
- << "Screenshot : +" << dist * 50 << std::endl
- << "Text : +" << (1 + abs(cos(arg))) * (4 - dist) * 40 << std::endl
- << "Drawing : +" << dist * 50 << std::endl << std::endl;
-
-
- // io::pbm::save(binarization::threshold(fft, max * 4 / 10), name.append("_fft.pbm"));
-
- // Print the result !
-
- std::cout << "Photo : " << score[PHOTO] << std::endl
- << "Screenshot : " << score[SCREENSHOT] << std::endl
- << "Text : " << score[TEXT] << std::endl
- << "Drawing : " << score[DRAWING] << std::endl;
-
- max = 0;
- unsigned index = 0;
-
- for (unsigned i = 0; i < NB_DOCTYPE; ++i)
- if (score[i] > max)
- {
- max = score[i];
- index = i;
- }
-
- return index;
-}
Index: nature/opening.cc
--- nature/opening.cc (revision 3184)
+++ nature/opening.cc (working copy)
@@ -1,59 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/win/rectangle2d.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/morpho/opening.hh>
-
-int main(int argc, const char * argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc < 2) {
- std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
- return 1;
- }
-
- for (int i = 1; i < argc; ++i)
- {
- image2d<int_u8> ima;
- io::pgm::load(ima, argv[i]);
-
- win::rectangle2d rect(3, 3);
- border::thickness = 11;
-
- std::string name(argv[i]);
- name.erase(name.length() - 4);
- io::pgm::save(morpho::opening(ima, rect), name.append("_opened.pgm"));
- }
-}
Index: nature/co_occurence.hh
--- nature/co_occurence.hh (revision 3184)
+++ nature/co_occurence.hh (working copy)
@@ -1,77 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef MLN_CO_OCCURENCE_HH
-# define MLN_CO_OCCURENCE_HH
-
-/*! \file ??
- *
- * \brief FIXME
- */
-
-# include <mln/core/concept/image.hh>
-# include <mln/core/dpoint.hh>
-# include <mln/core/image/image2d.hh>
-# include <mln/data/fill.hh>
-# include <mln/opt/at.hh>
-
-
-namespace mln
-{
-
-
- template <typename I, typename D>
- // image2d<unsigned> co_occurence (const Image<I>&, const Dpoint<D>&);
- image2d<unsigned> co_occurence (const Image<I>&, const Gdpoint<D>&);
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <typename I, typename D>
- image2d<unsigned> co_occurence (const Image<I> &ima_, const Gdpoint<D> &dp_)
- {
- mln::metal::equal<mln_psite(I), mln_psite(D)>::check();
- // FIXME : check thaat Image<I> is quant low
-
- const I &ima = exact(ima_);
- const D &dp = exact(dp_);
- image2d<unsigned> mco(mln_card(mln_value(I)), mln_card(mln_value(I)), 0);
- data::fill(mco, 0);
-
-
- mln_piter(I) p(ima.domain());
- for_all(p)
- if (ima.domain().has(p + dp))
- opt::at(mco, ima(p), ima(p + dp))++;
-
- return mco;
- }
-
-#endif // MLN_INCLUDE_ONLY
-
-}
-
-#endif // MLN_CO_OCCURENCE_HH
Index: nature/test.sh
--- nature/test.sh (revision 3184)
+++ nature/test.sh (working copy)
@@ -1,11 +0,0 @@
-#! /bin/sh
-
-for i in $@;
-do
- echo $i;
- echo "";
- ./nature $i;
- echo "";
- echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
- echo "";
-done;
Index: nature/proj.cc
--- nature/proj.cc (revision 3184)
+++ nature/proj.cc (working copy)
@@ -1,68 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/image1d.hh>
-#include <mln/win/rectangle2d.hh>
-#include <mln/core/image/cast_image.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/morpho/opening.hh>
-
-#include "proj.hh"
-
-int main(int argc, const char * argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc < 2) {
- std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
- return 1;
- }
-
- for (int i = 1; i < argc; ++i)
- {
- image2d<int_u8> ima;
- io::pgm::load(ima, argv[i]);
-
- std::string name(argv[i]);
- name.erase(name.length() - 4);
- image1d<float> toto = proj_nat(ima);
- image2d<int_u8> tata (toto.domain().nsites(), 1);
- mln_piter_(image1d<int_u8>) p(toto.domain());
-
- for_all(p) {
- tata(point2d(p[0], 0)) = toto(p);
- }
-
- io::pgm::save(tata, name.append("_proj.pgm"));
- }
-}
Index: nature/erosion.cc
--- nature/erosion.cc (revision 3184)
+++ nature/erosion.cc (working copy)
@@ -1,60 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#include <mln/core/image/image2d.hh>
-#include <mln/win/rectangle2d.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/morpho/gradient.hh>
-
-
-int main(int argc, const char * argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc < 2) {
- std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
- return 1;
- }
-
- for (int i = 1; i < argc; ++i)
- {
- image2d<int_u8> ima;
- io::pgm::load(ima, argv[i]);
-
- win::hline2d f(31);
- border::thickness = 16;
-
- std::string name(argv[i]);
- name.erase(name.length() - 4);
- io::pgm::save(morpho::erosion(ima, f), name.append("_eroded.pgm"));
- }
-}
Index: nature/mco.cc
--- nature/mco.cc (revision 3184)
+++ nature/mco.cc (working copy)
@@ -1,48 +0,0 @@
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/cast_image.hh>
-#include <mln/value/int_u16.hh>
-#include "co_occurence.hh"
-#include <mln/core/alias/dpoint2d.hh>
-#include <mln/io/pgm/save.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/estim/min_max.hh>
-
-int main(int argc, const char * argv[])
-{
- using namespace mln;
- using namespace value;
-
- if (argc < 2) {
- std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
- return 1;
- }
-
- dpoint2d d(0, 1);
-
- for (int i = 1; i < argc; ++i)
- {
- image2d<int_u8> ima;
- io::pgm::load(ima, argv[i]);
-
- std::string name(argv[i]);
- name.erase(name.length() - 4);
-
- image2d<unsigned> co (co_occurence(ima, d));
-
- // Normalization
- unsigned m, M;
- estim::min_max(co, m, M);
- std::cout << "max : " << M << std::endl;
- double norm = 255./M;
- mln_piter_ (image2d<unsigned>) p (co.domain());
- for_all(p)
- {
- // std::cout << co(p) << " ; ";
- co(p) *= norm;
- }
-
- io::pgm::save(cast_image<int_u<8> >(co), name.append("_mco.pgm"));
- }
-}
Index: nature/fft.cc
--- nature/fft.cc (revision 3184)
+++ nature/fft.cc (working copy)
@@ -1,61 +0,0 @@
-// -*- c++ -*-
-// Copyright (C) 2004 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-// Boston, MA 02110-1301, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#include <mln/transform/fft.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
-using namespace mln;
-using namespace transform;
-using namespace value;
-
-int main(int argc, const char * argv[])
-{
- using namespace mln;
- using value::int_u8;
-
- if (argc < 2) {
- std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
- return 1;
- }
-
- for (int i = 1; i < argc; ++i)
- {
- image2d<int_u8> ima;
- io::pgm::load(ima, argv[i]);
-
- fft<double> fourier(ima);
-
- fourier.transform();
-
- std::string name(argv[i]);
- name.erase(name.length() - 4);
- io::pgm::save(fourier.transformed_image_log_magn<int_u8>(true), name.append("_fft.pgm"));
- }
-}
Index: nature/hom.cc
--- nature/hom.cc (revision 3184)
+++ nature/hom.cc (working copy)
@@ -1,84 +0,0 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-
-#include <mln/core/image/image2d.hh>
-
-#include <mln/win/rectangle2d.hh>
-
-#include <mln/io/pgm/load.hh>
-#include <mln/io/pbm/save.hh>
-
-#include <mln/value/int_u8.hh>
-#include <mln/value/int_u16.hh>
-
-# include <mln/core/alias/window2d.hh>
-
-#include <mln/level/transform.hh>
-#include <mln/binarization/threshold.hh>
-#include <mln/estim/mean.hh>
-#include <mln/morpho/hit_or_miss.hh>
-#include <mln/morpho/dilation.hh>
-#include <mln/morpho/opening.hh>
-
-#include <mln/win/all.hh>
-
-int main(int argc, const char * argv[])
-{
- using namespace mln;
- using namespace value;
-
- if (argc < 2) {
- std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
- return 1;
- }
-
- for (int i = 1; i < argc; ++i)
- {
- typedef int_u8 int_t;
-
- border::thickness = 21;
-
- image2d<int_t> ima;
- io::pgm::load(ima, argv[i]);
-
- // Compute the mean
- int_t mean = estim::mean(ima);
-
- image2d<bool> imab = binarization::threshold(ima, mean-10);
-
- io::pbm::save(imab, "hop.pbm");
-
- window2d out = win::disk2d(25) - win::disk2d(22);
- win::disk2d in(4);
-
-
- std::string name(argv[i]);
- name.erase(name.length() - 4);
- io::pbm::save(morpho::hit_or_miss(imab, in, out), name.append("_hom.pbm"));
- }
-}
Index: nature/proj.hh
--- nature/proj.hh (revision 3184)
+++ nature/proj.hh (working copy)
@@ -1,64 +0,0 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef MLN_PROJ_HH
-# define MLN_PROJ_HH
-
-#include <mln/io/pgm/save.hh>
-#include <mln/data/paste.hh>
-#include <mln/accu/mean.hh>
-#include <mln/literal/white.hh>
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/image1d.hh>
-#include <mln/data/fill.hh>
-#include <mln/opt/at.hh>
-
-namespace mln
-{
- template <typename T>
- image1d<float>
- proj_nat(const image2d<T>& input)
- {
- image1d<float> out(geom::nrows(input));
- data::fill(out, 0);
-
- mln_piter(image2d<T>) p(input.domain());
- for_all(p) // 2d
- opt::at(out, p.row()) += input(p);
-
- mln_piter(image1d<T>) p2(out.domain());
- unsigned count = geom::ncols(input);
- for_all(p2) {
- out(p2) /= count;
- }
- return out;
- }
-
-} // end of namespace mln
-
-#endif /* MLN_PROJ_HH */
-
Index: nature/Makefile
--- nature/Makefile (revision 3184)
+++ nature/Makefile (working copy)
@@ -1,24 +0,0 @@
-SRC=$(wildcard *.cc)
-OBJ=$(SRC:.cc=.o)
-EXEC=$(SRC:.cc=)
-CC=g++
-CXXFLAGS=-Wall -W -I ../abraham -I ../.. -O3 -DNDEBUG
-
-fft: fft.o
- $(CC) $(CXXFLAGS) $< -o $@ -l fftw3
-
-nature: nature.o
- $(CC) $(CXXFLAGS) $< -o $@ -l fftw3
-
-all: $(EXEC)
-
-clean:
- rm -rf *.o
- rm -rf *~
-
-distclean: clean
- rm -rf $(EXEC)
-
-proj: proj.cc proj.hh
-
-.PHONY: clean distclean
Index: nature/histo_hsi.cc
--- nature/histo_hsi.cc (revision 3184)
+++ nature/histo_hsi.cc (working copy)
@@ -1,181 +0,0 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library. This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License. This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#include <iterator>
-#include <string>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/cast_image.hh>
-#include <mln/core/image/thru.hh>
-#include <mln/core/alias/window2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/site_set/p_set.hh>
-
-#include <mln/value/rgb8.hh>
-#include <mln/value/hsi.hh>
-
-#include <mln/fun/v2v/rgb_to_hsi.hh>
-#include <mln/level/to_enc.hh>
-#include <mln/fun/meta/hue.hh>
-#include <mln/fun/meta/sat.hh>
-#include <mln/fun/meta/inty.hh>
-
-#include <mln/level/compare.hh>
-
-#include <mln/io/ppm/load.hh>
-#include <mln/io/pbm/save.hh>
-#include <mln/io/pgm/save.hh>
-
-#include <mln/accu/histo.hh>
-#include <mln/histo/compute.hh>
-#include <mln/level/transform.hh>
-#include <mln/data/fill.hh>
-
-using namespace mln;
-using namespace value;
-
-typedef int_u16 u_t;
-
-
-template <typename I>
-void save_histo(Image<I> &i, std::string &name)
-{
- I& ima = exact(i);
-
- histo::data<float01_8> h = histo::compute(ima);
-
- // Compute histo max
- unsigned max = 0;
- mln_viter(mln::value::set<float01_8>) v(h.vset());
-
- for_all(v)
- if (h(v) > max)
- max = h(v);
-
- std::cout << std::endl;
-
- image2d<bool> output(max, mln_card(float01_8), 0);
- std::cout << max << "x" << mln_card(float01_8) << std::endl;
- data::fill(output, true);
-
- for_all(v)
- for (size_t i = 0; i < h(v); ++i)
- {
- // std::cout << max - i - 1 << ", " << (unsigned) (((float01_8)v).to_enc()) << " ; " ;
- if (output.has(point2d(max - i - 1, ((float01_8)v).to_enc() )))
- output(point2d(max - i - 1, ((float01_8)v).to_enc() )) = false;
- }
-
- io::pbm::save(output, name);
-}
-
-int main (int argc, const char* argv [])
-{
- if (argc < 2) {
- std::cerr << "usage: " << argv[0] << " in.ppm [other_files.ppm]" << std::endl;
- return 1;
- }
-
- for (int i = 1; i < argc; ++i)
- {
-
- image2d<rgb8> input;
- io::ppm::load(input, argv[i]);
-
- image2d<hsi_f> hsi = level::transform(input, fun::v2v::f_rgb_to_hsi_f);
- thru<mln::meta::hue<hsi_f>, image2d<hsi_f> > h(hsi);
- cast_image_<float01_8, thru<mln::meta::hue<hsi_f>, image2d<hsi_f> > > hue(h);
-
- std::string n(argv[i]);
- n.erase(n.length() - 4);
- image2d<int_u8> henc;
- level::transform(hue, fun::v2v::enc< float01_8 >(), henc);
- io::pgm::save(henc, n.append("_hue.pgm"));
-
- image2d<hsi_f>::piter p(hsi.domain());
- float m = 0;
- for_all(p)
- {
- if (h(p) > m)
- m = h(p);
- }
- std::cout << std::endl << m << std::endl;
-
-
-
- std::string name(argv[i]);
- name.erase(name.length() - 4);
- save_histo(hue, name.append("_hue.pbm"));
-
-
- thru<mln::meta::sat<hsi_f>, image2d<hsi_f> > s(hsi);
- cast_image_<float01_8, thru<mln::meta::sat<hsi_f>, image2d<hsi_f> > > sat(s);
-
- n = argv[i];
- n.erase(n.length() - 4);
- image2d<int_u8> senc;
- level::transform(sat, fun::v2v::enc< float01_8 >(), senc);
- io::pgm::save(senc, n.append("_sat.pgm"));
-
- m = 0;
- for_all(p)
- {
- if (s(p) > m)
- m = s(p);
- }
- std::cout << std::endl << m << std::endl;
-
-
- name = argv[i];
- name.erase(name.length() - 4);
- save_histo(sat, name.append("_sat.pbm"));
-
- thru<mln::meta::inty<hsi_f>, image2d<hsi_f> > l(hsi);
- cast_image_<float01_8, thru<mln::meta::inty<hsi_f>, image2d<hsi_f> > > inty(l);
-
- n = argv[i];
- n.erase(n.length() - 4);
- image2d<int_u8> ienc;
- level::transform(inty, fun::v2v::enc< float01_8 >(), ienc);
- io::pgm::save(ienc, n.append("_inty.pgm"));
-
-
- m = 0;
- for_all(p)
- {
- if (l(p) > m)
- m = l(p);
- }
- std::cout << std::endl << m << std::endl;
-
-
- name = argv[i];
- name.erase(name.length() - 4);
- save_histo(inty, name.append("_inty.pbm"));
-
- }
-}
Index: ballas/color/min_tree_volume_filter.cc
--- ballas/color/min_tree_volume_filter.cc (revision 3184)
+++ ballas/color/min_tree_volume_filter.cc (working copy)
@@ -1,551 +0,0 @@
-# include <mln/core/var.hh>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image/extended.hh>
-# include <mln/core/routine/extend.hh>
-
-# include <mln/core/alias/window2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/make/double_neighb2d.hh>
-# include <mln/core/site_set/p_centered.hh>
-
-
-# include <mln/literal/black.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pgm/save.hh>
-
-# include <mln/value/rgb8.hh>
-# include <mln/io/ppm/load.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/accu/min_max.hh>
-
-# include <mln/fun/i2v/array.hh>
-# include <mln/fun/p2v/iota.hh>
-
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-# include <mln/level/transform.hh>
-# include <mln/extension/fill.hh>
-
-# include <mln/morpho/closing_area.hh>
-# include <mln/opt/at.hh>
-
-
-# include <mln/debug/println.hh>
-
-# include "src/distance.hh"
-
-
-namespace mln
-{
- template <typename I, typename N, typename Ic, typename Nc>
- struct min_tree_
- {
- typedef mln_site(I) point;
- typedef p_array<point> S;
-
- // in:
- const I& f;
- const N& nbh;
- const Ic& ref;
- const Nc& nbhc;
-
- // aux:
- S s;
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, point) parent;
- mln_ch_value(I, bool) resp;
- mln_ch_value(I, point) zpar;
-
- // attached data:
- int lambda;
- mln_ch_value(I, int) volume;
- mln_ch_value(Ic, value::rgb8) color;
-
-
- min_tree_(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
- int lambda)
- : f(f),
- nbh(nbh),
- ref(ref),
- nbhc(nbhc),
- lambda(lambda)
- {
- run();
- }
-
- void run()
- {
- // init
- {
- initialize(deja_vu, f);
- initialize(parent, f);
- initialize(resp, f);
- initialize(zpar, f);
- initialize(volume, f);
- initialize(color, f);
-
- mln::data::fill(deja_vu, false);
- mln::data::fill(color, value::rgb8(255, 255, 255));
- mln::data::fill(volume, 0);
-
- s = level::sort_psites_increasing(f);
- }
-
- // first pass
- {
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- make_set(p);
- for_all(n)
- if (f.has(n) && deja_vu(n))
- do_union(n, p);
- deja_vu(p) = true;
- }
- }
-
- // second pass: canonization
- {
- mln_bkd_piter(S) p(s);
- for_all(p)
- {
- point q = parent(p);
- if (f(parent(q)) == f(q))
- {
- parent(p) = parent(q);
- resp(q) = false;
- }
- }
- }
-
- // third pass: Merging region with volume < lambda
- {
- mln_fwd_piter(S) p(s);
- for_all(p)
- {
- if (resp(p) && (volume(p) < lambda))
- {
- resp(p) = false;
- update_data(parent(p), volume(p), color(p));
- }
- }
- }
-
- } // end of run()
-
- void make_set(const point& p)
- {
- parent(p) = p;
- zpar(p) = p;
- init_data(p);
- }
-
- void set_parent(const point& r, const point& p)
- {
- parent(r) = p;
- merge_data(r, p);
- }
-
- bool is_root(const point& p) const
- {
- return parent(p) == p;
- }
-
- bool is_node(const point& p) const
- {
- //return is_root(p) || f(parent(p)) != f(p);
- return (is_root(p) || resp(p));
- }
-
- point find_root(const point& x)
- {
- if (zpar(x) == x)
- return x;
- else
- return zpar(x) = find_root(zpar(x));
- }
-
- point find_representative(const point& x)
- {
- if (parent(x) == x || resp(x))
- return x;
- else
- return find_representative(parent(x));
- }
-
- void do_union(const point& n, const point& p)
- {
- point r = find_root(n);
- if (r != p)
- {
- set_parent(r, p);
- zpar(r) = p;
- }
- }
-
- void init_data(const point& p)
- {
- // init volume
- volume(p) = f(p);
-
-
- // init color
- int red =0, green = 0, blue = 0;
-
- mln_niter(Nc) n(nbhc, p);
- for_all(n)
- {
- red += ref(n).red();
- green += ref(n).green();
- blue += ref(n).blue();
- }
-
- red /= 2;
- green /= 2;
- blue /= 2;
-
- color(p).red() = red;
- color(p).green() = green;
- color(p).blue() = blue;
-
-
- resp(p) = true;
- }
-
- void merge_data(const point& r, const point& p)
- {
- if (f(p) == f(r))
- {
- resp(p) = false;
-
- // merge volume
- volume(r) += volume(p);
-
- // merge color
- color(r) = (color(r) + color(p)) / 2;
- }
- }
-
- void update_data(const point& p, int val, value::rgb8 c)
- {
- // update volume
- volume(p) += val;
- // update color
- color(p) = (color(p) + c) / 2;
-
- if (parent(p) != p && !resp(p))
- update_data(parent(p), val, color(p));
- }
-
- };
-}
-
-namespace mln
-{
- image2d<value::int_u16> convert_to_grey(const image2d<value::rgb8>& data)
- {
- image2d<value::int_u16> output(data.domain());
- mln_piter_(image2d<value::int_u16>) p(output.domain());
- for_all(p)
- output(p) = (int) (data(p).red() * 0.3 + data(p).green() * 0.58 + data(p).blue()) * 0.12;
- return output;
- }
-} // end of mln
-
-namespace mln
-{
-
- struct colorize : Function_v2v< colorize >
- {
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
- };
-
- template <typename I>
- I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
- data::fill(output, bg);
-
- mln_VAR(edge, ima | is_edge);
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-
- template <typename I>
- I display_edge(const I& ima, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
-
- mln_VAR( cell, ima | is_cell );
- mln_piter(cell_t) q(cell.domain());
- for_all(q)
- {
- unsigned row = (q.row() / 2) * (zoom + 1);
- unsigned col = (q.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- for (unsigned j = 0; j < zoom; ++j)
- opt::at(output, row + i, col + j) = ima(q);
- }
-
- mln_VAR( edge, ima | is_edge );
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-
- namespace morpho
- {
-
- template <typename I, typename N>
- mln_concrete(I)
- dilation(const I& input, const N& nbh)
- {
- typedef mln_value(I) V;
-
- mln_concrete(I) output;
- initialize(output, input);
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (input.has(n) && input(n) != value::rgb8(0,0,0))
- output(p) = input(n);
- }
- return output;
- }
- } // mln::morpho
-
-} // mln
-
-
-
-template <typename T>
-mln::image2d<T>
-image2cells(const mln::image2d<T>& input)
-{
- mln::image2d<T> output(2 * input.nrows() - 1,
- 2 * input.ncols() - 1);
- for (unsigned row = 0; row < input.nrows(); ++row)
- for (unsigned col = 0; col < input.ncols(); ++col)
- mln::opt::at(output, 2 * row, 2 * col) = mln::opt::at(input, row, col);
- return output;
-}
-
-
-template <typename T>
-mln::image2d<T>
-cells2image(const mln::image2d<T>& input)
-{
- mln::image2d<T> output((input.nrows() + 1) / 2,
- (input.ncols() + 1) / 2);
- for (unsigned row = 0; row < input.nrows(); row += 2)
- for (unsigned col = 0; col < input.ncols(); col += 2)
- mln::opt::at(output, row / 2, col / 2) = mln::opt::at(input, row, col);
- return output;
-}
-
-
-
-
-template <typename I, typename N, typename Ic, typename Nc>
-unsigned min_tree(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
- int lambda)
-{
- using namespace mln;
-
- min_tree_<I,N,Ic,Nc> run(f, nbh, ref, nbhc, lambda);
-
-
- mln_piter(I) p(f.domain());
- unsigned nnodes = 0;
- for_all(p)
- {
- if (run.is_node(p))
- ++nnodes;
- }
-
- colorize colors(nnodes);
- image2d<value::rgb8> tmp(ref.domain());
- data::fill(tmp, literal::black);
- image2d<value::rgb8> tmp2(ref.domain());
- data::fill(tmp, ref);
-
- mln_piter(I) q(f.domain());
- unsigned int i = 0;
- for_all(q)
- {
- if (run.is_node(q))
- {
- tmp(q) = run.color(q);
- tmp2(q) = colors(i);
- i++;
- }
- }
-
- mln_piter(I) r(f.domain());
- for_all(r)
- {
- if (!run.is_node(r))
- {
- tmp(r) = tmp(run.find_representative(r));
- tmp2(r) = tmp2(run.find_representative(r));
- }
- }
-
- image2d<value::rgb8> to_display(tmp.domain());
- image2d<value::rgb8> to_display2(tmp2.domain());
-
- data::fill(to_display, literal::black);
- data::paste((tmp | is_edge), to_display);
- data::paste(morpho::dilation(to_display, c4()), to_display);
-
- data::fill(to_display2, literal::black);
- data::paste((tmp2 | is_edge), to_display2);
- data::paste(morpho::dilation(to_display2, c4()), to_display2);
-
-
- io::ppm::save(display_edge(tmp, literal::black, 3), "edge.ppm");
- io::ppm::save(tmp, "full.ppm");
- io::ppm::save(cells2image(to_display), "colorize.ppm");
-
- io::ppm::save(display_edge(tmp2, literal::black, 3), "edge2.ppm");
- io::ppm::save(cells2image(to_display2), "colorize2.ppm");
-
- return nnodes;
-}
-
-
-
-template <typename I>
-I
-do_it(I& input, int lambda, unsigned& nbasins)
-{
- using namespace mln;
-
- /// Graph creation
- I graph;
- create_graph(input, graph, value::rgb8(0, 0, 0));
-
- // Initialization
- image2d<value::int_u16> ima = convert_to_grey(graph);
-
- // Neigbhorhood
- // e2c
- bool e2c_h[] = { 0, 1, 0,
- 0, 0, 0,
- 0, 1, 0 };
- bool e2c_v[] = { 0, 0, 0,
- 1, 0, 1,
- 0, 0, 0 };
-
- mln_VAR(e2c, make::double_neighb2d(is_row_odd, e2c_h, e2c_v));
-
- bool e2e_h[] = { 0, 0, 1, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 1, 0, 0 };
-
- bool e2e_v[] = { 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0 };
- mln_VAR(e2e, make::double_neighb2d(is_row_odd, e2e_h, e2e_v));
-
- // Algorithm
- distance(extend((graph | is_edge).rw(), pw::value(graph)), e2c, ima);
-
- io::pgm::save(ima, "edge.pgm");
-
- nbasins = min_tree((ima | is_edge), e2e, graph, e2c, lambda);
-
- return graph;
-}
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm lambda" << std::endl;
- std::cerr << " lambda >= 0" << std::endl;
- abort();
-}
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
-
- if (argc != 3)
- usage(argv);
-
- int lambda = atoi(argv[2]);
- if (lambda < 0)
- usage(argv);
-
- image2d<value::rgb8> ima;
- io::ppm::load(ima, argv[1]);
-
- unsigned nbasins;
- image2d<value::rgb8> output = do_it(ima, lambda, nbasins);
-
- //io::ppm::save(output, argv[3]);
-}
Index: ballas/color/reference.cc
--- ballas/color/reference.cc (revision 3184)
+++ ballas/color/reference.cc (working copy)
@@ -1,557 +0,0 @@
-# include <mln/core/var.hh>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image/extended.hh>
-# include <mln/core/routine/extend.hh>
-
-# include <mln/core/alias/window2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/make/double_neighb2d.hh>
-# include <mln/core/site_set/p_centered.hh>
-
-# include <mln/literal/origin.hh>
-# include <mln/literal/black.hh>
-# include <mln/literal/white.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pgm/save.hh>
-
-# include <mln/value/rgb8.hh>
-# include <mln/io/ppm/load.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/accu/min_max.hh>
-# include <mln/accu/mean.hh>
-
-# include <mln/fun/i2v/array.hh>
-# include <mln/fun/p2v/iota.hh>
-
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-# include <mln/level/transform.hh>
-# include <mln/extension/fill.hh>
-# include <mln/convert/to.hh>
-
-# include <mln/linear/gaussian.hh>
-
-# include <mln/morpho/meyer_wst.hh>
-# include <mln/morpho/closing_volume.hh>
-
-# include <mln/make/w_window2d.hh>
-# include <mln/opt/at.hh>
-
-# include <mln/debug/println.hh>
-
-// Laplacian method
-namespace mln
-{
- namespace linear
- {
- // required to deal with a input image that differ from the output since I
- //don't succeed in using a float image in entry.
- template <class I, class O>
- inline
- void
- gaussian_2nd_derivative(const Image<I>& input, float sigma, Image<O>& output)
- {
- mln_precondition(exact(input).is_valid());
-
- impl::recursivefilter_coef_
- coef(-1.331f, 3.661f,
- 1.24f, 1.314f,
- 0.3225f, -1.738f,
- 0.748f, 2.166f,
- sigma, impl::gaussian_2nd_deriv_coef_norm_);
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output);
- }
-
- template <class I, class O>
- inline
- void
- gaussian_1st_derivative(const Image<I>& input, float sigma, Image<O>& output)
- {
- mln_precondition(exact(input).is_valid());
-
- impl::recursivefilter_coef_
- coef(-0.6472f, -4.531f,
- 1.527f, 1.516f,
- 0.6494f, 0.9557f,
- 0.6719f, 2.072f,
- sigma, impl::gaussian_1st_deriv_coef_norm_);
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output);
- }
- }
-}
-
-// Gradient + watershed method
-namespace mln
-{
- namespace morpho
- {
- template <typename I, typename N>
- mln_concrete(I)
- closing_volume(const I& input, const Neighborhood<N>& nbh, std::size_t lambda)
- {
- mln_concrete(I) output;
- initialize(output, input);
- closing_volume(input, nbh, lambda, output);
- return output;
- }
- }
-} // !mln
-
-namespace mln
-{
- image2d<value::int_u8> convert_to_grey(const image2d<value::rgb8>& data)
- {
- image2d<value::int_u8> output(data.domain());
- mln_piter_(image2d<value::int_u8>) p(output.domain());
- for_all(p)
- output(p) = (int) (data(p).red() * 0.3 + data(p).green() * 0.58 + data(p).blue()) * 0.12;
- return output;
- }
-} // !mln
-
-// Functions
-
-inline
-bool is_row_odd(const mln::point2d& p)
-{
- return p.row() % 2;
-}
-
-inline
-bool is_cell(const mln::point2d& p)
-{
- return p.row() % 2 == 0 && p.col() % 2 == 0;
-}
-
-inline
-bool is_edge(const mln::point2d& p)
-{
- return p.row() % 2 + p.col() % 2 == 1;
-}
-
-inline
-bool is_point(const mln::point2d& p)
-{
- return p.row() % 2 && p.col() % 2;
-}
-
-inline
-bool is_not_edge(const mln::point2d& p)
-{
- return ! is_edge(p);
-}
-
-
-
-namespace mln
-{
-
- namespace border
- {
-
- template <typename I>
- void
- fill(I& ima, const mln_value(I)& v)
- {
- const int nrows = ima.nrows();
- const int ncols = ima.ncols();
- for (int r = -1; r <= nrows; ++r)
- {
- opt::at(ima, r, -1) = v;
- opt::at(ima, r, ncols) = v;
- }
- for (int c = -1; c <= ncols; ++c)
- {
- opt::at(ima, -1, c) = v;
- opt::at(ima, nrows, c) = v;
- }
- }
-
- } // mln::border
-
- namespace accu
- {
-
- template <typename I, typename L, typename A, typename V>
- inline
- void
- compute(const Image<I>& input_,
- const Image<L>& label_,
- const Accumulator<A>&,
- V& v)
- {
- trace::entering("accu::compute");
-
- const I& input = exact(input_);
- const L& label = exact(label_);
-
- const unsigned n = v.size();
- std::vector<A> a(n);
-
- mln_piter(I) p(input.domain());
- for_all(p)
- a[label(p)].take(input(p));
-
- for (unsigned l = 1; l < n; ++l)
- v(l) = a[l].to_result();
-
- trace::exiting("accu::compute");
- }
-
- } // mln::accu
-
- namespace morpho
- {
-
- template <typename I, typename N>
- mln_concrete(I)
- gradient(const I& input, const N& nbh)
- {
- mln_concrete(I) output;
- initialize(output, input);
- accu::min_max<mln_value(I)> mm;
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- mm.init();
- for_all(n) if (input.has(n))
- mm.take(input(n));
- output(p) = mm.second() - mm.first();
- }
- return output;
- }
-
- template <typename I, typename N>
- mln_concrete(I)
- dilation(const I& input, const N& nbh)
- {
- typedef mln_value(I) V;
-
- mln_concrete(I) output;
- initialize(output, input);
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (input.has(n) && input(n) != value::rgb8(0,0,0))
- output(p) = input(n);
- }
- return output;
- }
- } // mln::morpho
-
-
- struct colorize : Function_v2v< colorize >
- {
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
- };
-
-
- template <typename I>
- I display_edge_with_bg(const I& ima, unsigned zoom, mln_value(I) bg)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
- data::fill(output, bg);
- mln_VAR( edge, ima | is_edge );
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
- template <typename I>
- I display_edge(const I& ima, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
-
- mln_VAR( cell, ima | is_cell );
- mln_piter(cell_t) q(cell.domain());
- for_all(q)
- {
- unsigned row = (q.row() / 2) * (zoom + 1);
- unsigned col = (q.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- for (unsigned j = 0; j < zoom; ++j)
- opt::at(output, row + i, col + j) = ima(q);
- }
-
- mln_VAR( edge, ima | is_edge );
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-} // mln
-
-
-
-template <typename T>
-mln::image2d<T>
-image2cells(const mln::image2d<T>& input)
-{
- mln::image2d<T> output(2 * input.nrows() - 1,
- 2 * input.ncols() - 1);
- for (int row = 0; row < input.nrows(); ++row)
- for (int col = 0; col < input.ncols(); ++col)
- mln::opt::at(output, 2 * row, 2 * col) = mln::opt::at(input, row, col);
- return output;
-}
-
-namespace mln {
-
- template <typename I, typename N, typename M>
- mln_concrete(I)
- mean(const I& input, const N& nbh, const M& nbh2)
- {
- mln_concrete(I) output;
- initialize(output, input);
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- mln_niter(M) m(nbh2, p);
- for_all(p)
- {
- if (is_edge(p))
- {
- int nb = 0;
- int r = 0, g = 0, b = 0;
- for_all(n)
- {
- if (input.has(n))
- {
- r += input(n).red();
- g += input(n).green();
- b += input(n).blue();
- ++nb;
- }
- }
- output(p) = value::rgb8(r / nb, g / nb, b / nb);
- }
- if (is_point(p))
- {
- int nb = 0;
- int r = 0, g = 0, b = 0;
- for_all(m)
- {
- if (input.has(m))
- {
- r += input(m).red();
- g += input(m).green();
- b += input(m).blue();
- ++nb;
- }
- }
- output(p) = value::rgb8(r / nb, g / nb, b / nb);
- }
- if (is_cell(p))
- output(p) = input(p);
- }
- return output;
- }
-
-}
-
-template <typename T>
-mln::image2d<T>
-cells2image(const mln::image2d<T>& input)
-{
- mln::image2d<T> output((input.nrows() + 1) / 2,
- (input.ncols() + 1) / 2);
- for (int row = 0; row < input.nrows(); row += 2)
- for (int col = 0; col < input.ncols(); col += 2)
- mln::opt::at(output, row / 2, col / 2) = mln::opt::at(input, row, col);
- return output;
-}
-
-
-
-
-template <typename I>
-mln_concrete(I)
-do_it(I& input, float lambda, unsigned& nbasins)
-{
- using namespace mln;
-
- /**************************/
- /* Neighborhood defintion */
- /**************************/
-
- // e2c
- bool e2c_h[] = { 0, 1, 0,
- 0, 0, 0,
- 0, 1, 0 };
- bool e2c_v[] = { 0, 0, 0,
- 1, 0, 1,
- 0, 0, 0 };
- mln_VAR( e2c, make::double_neighb2d(is_row_odd, e2c_h, e2c_v) );
-
- // e2e
- bool e2e_h[] = { 0, 0, 1, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 1, 0, 0 };
- bool e2e_v[] = { 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0 };
- mln_VAR( e2e, make::double_neighb2d(is_row_odd, e2e_h, e2e_v) );
-
- // e2p
- bool e2p_h[] = { 1, 0, 1,
- 0, 0, 0,
- 1, 0, 1 };
- bool e2p_v[] = { 1, 0, 1,
- 0, 0, 0,
- 1, 0, 1 };
- mln_VAR( e2p, make::double_neighb2d(is_row_odd, e2p_h, e2p_v) );
-
- /******************/
- /* Initialisation */
- /******************/
-
- I output = mean(image2cells(input), e2c, e2p);
- io::ppm::save(output, "tmp_input.ppm");
- //image2d<value::int_u8> ima = convert_to_grey(output);
- image2d<value::int_u8> imau = convert_to_grey(output);
- io::pgm::save(imau, "tmp_grey_input.pgm");
-
- image2d<float> ima(exact(imau).domain());
-
- // cell
- mln_VAR(cell, imau | is_cell);
-
- // edge
- mln_VAR(edge, extend((imau | is_edge).rw(), pw::value(imau)));
-
- // FIXME until laplacian is working use gradient / closing_area / wst
-
- linear::gaussian_2nd_derivative(imau, lambda, ima);
-
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- {
- if (is_row_odd(p))
- {
- mln_value(image2d<float>) t = opt::at(ima, p.row() - 1, p.col());
- mln_value(image2d<float>) b = opt::at(ima, p.row() + 1, p.col());
- if ((t > 0 && b < 0) || (t < 0 && b > 0))
- output(p) = value::rgb8(255,0,0);
- }
- else
- {
- mln_value(image2d<float>) r = opt::at(ima, p.row(), p.col() - 1);
- mln_value(image2d<float>) d = opt::at(ima, p.row(), p.col() + 1);
- if ((r > 0 && d < 0) || (r < 0 && d > 0))
- output(p) = value::rgb8(255,0,0);
- }
- }
-
-#if 0
- data::paste(morpho::gradient(edge, e2c), edge);
- data::paste(morpho::closing_volume(edge, e2e, lambda), edge);
- data::fill(edge, morpho::meyer_wst(edge, e2e, nbasins));
-
- // Fill regions (with colorize) (won't work with laplacian...)
-
- colorize colors(nbasins);
-
- image2d<value::rgb8> cells(ima.domain());
- data::fill(cells, literal::white);
- data::paste(level::transform(edge, colors), cells);
- io::ppm::save(display_edge_with_bg(cells, 3, literal::white), "tmp_edge.ppm");
-
- // Move the color of an edge which is non black in the cell
- data::paste(morpho::dilation(cells, c4()), cells);
-#endif
-
- //cells = convert_to_rgb8(ima);
-
- return output;
-}
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm lambda output.ppm" << std::endl;
- std::cerr << " lambda >= 0" << std::endl;
- abort();
-}
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
-
- if (argc != 4)
- usage(argv);
-
- float lambda = atof(argv[2]);
- if (lambda < 0)
- usage(argv);
-
- image2d<value::rgb8> ima;
- io::ppm::load(ima, argv[1]);
-
- unsigned nbasins;
- image2d<value::rgb8> output = do_it(ima, lambda, nbasins);
-
- io::ppm::save(display_edge(output, 3), argv[3]);
-}
Index: ballas/color/min_tree_area_filter.cc
--- ballas/color/min_tree_area_filter.cc (revision 3184)
+++ ballas/color/min_tree_area_filter.cc (working copy)
@@ -1,515 +0,0 @@
-# include <mln/core/var.hh>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image/extended.hh>
-# include <mln/core/routine/extend.hh>
-
-# include <mln/core/alias/window2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/make/double_neighb2d.hh>
-# include <mln/core/site_set/p_centered.hh>
-
-# include <mln/literal/origin.hh>
-# include <mln/literal/black.hh>
-# include <mln/literal/white.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pgm/save.hh>
-
-# include <mln/value/rgb8.hh>
-# include <mln/io/ppm/load.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/accu/min_max.hh>
-
-# include <mln/fun/i2v/array.hh>
-# include <mln/fun/p2v/iota.hh>
-
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-# include <mln/level/transform.hh>
-# include <mln/extension/fill.hh>
-
-# include <mln/morpho/meyer_wst.hh>
-# include <mln/morpho/closing_area.hh>
-
-# include <mln/opt/at.hh>
-
-# include <mln/debug/println.hh>
-
-# if 0
-# include <mln/core/concept/image.hh>
-# include <mln/core/concept/neighborhood.hh>
-# include <mln/util/pix.hh>
-# include <mln/morpho/includes.hh>
-# include <mln/level/sort_psites.hh>
-#endif
-
-# include "src/distance.hh"
-
-namespace mln
-{
- template <typename I, typename N, typename Ic, typename Nc>
- struct min_tree_
- {
- typedef mln_site(I) point;
- typedef p_array<point> S;
-
- // in:
- const I& f;
- const N& nbh;
- const Ic& ref;
- const Nc& nbhc;
-
- // aux:
- S s;
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, point) parent;
- mln_ch_value(I, bool) resp;
- mln_ch_value(I, point) zpar;
-
- // attached data:
- int lambda;
- mln_ch_value(I, int) area;
- //mln_ch_value(Ic, value::rgb8) values;
- //initialize(values, ref);
- //mln_ch_value(I, int) comp;
-
- min_tree_(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
- int lambda)
- : f(f),
- nbh(nbh),
- ref(ref),
- nbhc(nbhc),
- lambda(lambda)
- {
- run();
- }
-
- void run()
- {
- // init
- {
- initialize(deja_vu, f);
- initialize(parent, f);
- initialize(resp, f);
- initialize(zpar, f);
- initialize(area, f);
- //initialize(comp, f);
-
- mln::data::fill(deja_vu, false);
- //mln::data::fill(resp, false);
- mln::data::fill(area, 0);
-
- s = level::sort_psites_increasing(f);
- }
-
- // first pass
- {
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- make_set(p);
- for_all(n)
- if (f.has(n) && deja_vu(n))
- do_union(n, p);
- deja_vu(p) = true;
- }
- }
-
- // second pass: canonization
- {
- mln_bkd_piter(S) p(s);
- for_all(p)
- {
- point q = parent(p);
- if (f(parent(q)) == f(q))
- {
- parent(p) = parent(q);
- resp(q) = false;
- }
- }
- }
-
- // third pass: Merging region with area < lambda
- {
- mln_fwd_piter(S) p(s);
- for_all(p)
- {
- if (resp(p) && area(p) < lambda)
- {
- resp(p) = false;
- update_data(parent(p), area(p));
- }
- }
- }
- } // end of run()
-
- void make_set(const point& p)
- {
- parent(p) = p;
- zpar(p) = p;
- init_data(p);
- }
-
- void set_parent(const point& r, const point& p)
- {
- parent(r) = p;
- merge_data(r, p);
- }
-
- bool is_root(const point& p) const
- {
- return parent(p) == p;
- }
-
- bool is_node(const point& p) const
- {
- //return is_root(p) || f(parent(p)) != f(p);
- return (is_root(p) || resp(p));
- }
-
- point find_root(const point& x)
- {
- if (zpar(x) == x)
- return x;
- else
- return zpar(x) = find_root(zpar(x));
- }
-
- point find_representative(const point& x)
- {
- if (parent(x) == x || resp(x))
- return x;
- else
- return find_representative(parent(x));
- }
-
- void do_union(const point& n, const point& p)
- {
- point r = find_root(n);
- if (r != p)
- {
- set_parent(r, p);
- zpar(r) = p;
- }
- }
-
- void init_data(const point& p)
- {
- area(p) = 1;
- resp(p) = true;
- }
-
- void merge_data(const point& r, const point& p)
- {
- if (f(p) == f(r))
- {
- resp(p) = false;
- area(p) += area(r);
- }
- }
-
- void update_data(const point& p, int val)
- {
- area(p) += val;
- if (parent(p) != p && !resp(p))
- update_data(parent(p), val);
- }
-
- };
-}
-
-namespace mln
-{
- image2d<value::int_u16> convert_to_grey(const image2d<value::rgb8>& data)
- {
- image2d<value::int_u16> output(data.domain());
- mln_piter_(image2d<value::int_u16>) p(output.domain());
- for_all(p)
- output(p) = (int) (data(p).red() * 0.3 + data(p).green() * 0.58 + data(p).blue()) * 0.12;
- return output;
- }
-} // end of mln
-
-namespace mln
-{
-
- struct colorize : Function_v2v< colorize >
- {
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
- };
-
- template <typename I>
- I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
- data::fill(output, bg);
-
- mln_VAR(edge, ima | is_edge);
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
- template <typename I>
- I display_edge(const I& ima, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
-
- mln_VAR( cell, ima | is_cell );
- mln_piter(cell_t) q(cell.domain());
- for_all(q)
- {
- unsigned row = (q.row() / 2) * (zoom + 1);
- unsigned col = (q.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- for (unsigned j = 0; j < zoom; ++j)
- opt::at(output, row + i, col + j) = ima(q);
- }
-
- mln_VAR( edge, ima | is_edge );
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-
- namespace morpho
- {
-
- template <typename I, typename N>
- mln_concrete(I)
- dilation(const I& input, const N& nbh)
- {
- typedef mln_value(I) V;
-
- mln_concrete(I) output;
- initialize(output, input);
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (input.has(n) && input(n) != value::rgb8(0,0,0))
- output(p) = input(n);
- }
- return output;
- }
- } // mln::morpho
-
-
-} // mln
-
-
-
-template <typename T>
-mln::image2d<T>
-image2cells(const mln::image2d<T>& input)
-{
- mln::image2d<T> output(2 * input.nrows() - 1,
- 2 * input.ncols() - 1);
- for (unsigned row = 0; row < input.nrows(); ++row)
- for (unsigned col = 0; col < input.ncols(); ++col)
- mln::opt::at(output, 2 * row, 2 * col) = mln::opt::at(input, row, col);
- return output;
-}
-
-
-template <typename T>
-mln::image2d<T>
-cells2image(const mln::image2d<T>& input)
-{
- mln::image2d<T> output((input.nrows() + 1) / 2,
- (input.ncols() + 1) / 2);
- for (unsigned row = 0; row < input.nrows(); row += 2)
- for (unsigned col = 0; col < input.ncols(); col += 2)
- mln::opt::at(output, row / 2, col / 2) = mln::opt::at(input, row, col);
- return output;
-}
-
-
-template <typename I, typename N, typename Ic, typename Nc>
-unsigned min_tree(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
- int lambda)
-{
- using namespace mln;
-
- min_tree_<I,N,Ic,Nc> run(f, nbh, ref, nbhc, lambda);
-
-
- mln_piter(I) p(f.domain());
- unsigned nnodes = 0;
- for_all(p)
- {
- if (run.is_node(p))
- {
- std::cout << "nodes: " << p << std::endl;
- ++nnodes;
- }
- }
-
- colorize colors(nnodes);
- image2d<value::rgb8> tmp(ref.domain());
- data::fill(tmp, ref);
-
- mln_piter(I) q(f.domain());
- unsigned int i = 0;
- for_all(q)
- {
- if (run.is_node(q))
- {
- tmp(q) = colors(i);
- i++;
- }
- }
- mln_piter(I) r(f.domain());
- for_all(r)
- {
- if (!run.is_node(r))
- {
- tmp(r) = tmp(run.find_representative(r));
- }
- }
-
-
- image2d<value::rgb8> to_display(tmp.domain());
-
- data::fill(to_display, value::rgb8(255, 255, 255));
- data::paste((tmp | is_edge), to_display);
- data::paste(morpho::dilation(to_display, c4()), to_display);
-
- io::ppm::save(display_edge(tmp, literal::white, 3),
- "edge.ppm");
- io::ppm::save(tmp, "full.ppm");
- io::ppm::save(cells2image(to_display), "colorize.ppm");
-
- return nnodes;
-}
-
-
-template <typename I>
-I
-do_it(I& input, int lambda, unsigned& nbasins)
-{
- using namespace mln;
-
- /// Graph creation
- I graph;
- create_graph(input, graph, value::rgb8(0, 0, 0));
-
- // Initialization
- image2d<value::int_u16> ima = convert_to_grey(graph);
-
- // Neigbhorhood
- // e2c
- bool e2c_h[] = { 0, 1, 0,
- 0, 0, 0,
- 0, 1, 0 };
- bool e2c_v[] = { 0, 0, 0,
- 1, 0, 1,
- 0, 0, 0 };
-
- mln_VAR(e2c, make::double_neighb2d(is_row_odd, e2c_h, e2c_v));
-
- bool e2e_h[] = { 0, 0, 1, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 1, 0, 0 };
-
- bool e2e_v[] = { 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0 };
- mln_VAR(e2e, make::double_neighb2d(is_row_odd, e2e_h, e2e_v));
-
- // Algorithm
- distance(extend((graph | is_edge).rw(), pw::value(graph)), e2c, ima);
- io::pgm::save(ima, "edge.pgm");
-
- nbasins = min_tree((ima | is_edge), e2e, graph, e2c, lambda);
-
- return graph;
-}
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm lambda" << std::endl;
- std::cerr << " lambda >= 0" << std::endl;
- abort();
-}
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
-
- if (argc != 3)
- usage(argv);
-
- int lambda = atoi(argv[2]);
- if (lambda < 0)
- usage(argv);
-
- image2d<value::rgb8> ima;
- io::ppm::load(ima, argv[1]);
-
- unsigned nbasins;
- image2d<value::rgb8> output = do_it(ima, lambda, nbasins);
-
- //io::ppm::save(output, argv[3]);
-}
Index: ballas/color/min_tree_height_filter.cc
--- ballas/color/min_tree_height_filter.cc (revision 3184)
+++ ballas/color/min_tree_height_filter.cc (working copy)
@@ -1,553 +0,0 @@
-# include <mln/core/var.hh>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image/extended.hh>
-# include <mln/core/routine/extend.hh>
-
-# include <mln/core/alias/window2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/make/double_neighb2d.hh>
-# include <mln/core/site_set/p_centered.hh>
-
-
-# include <mln/literal/black.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pgm/save.hh>
-
-# include <mln/value/rgb8.hh>
-# include <mln/io/ppm/load.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/accu/min_max.hh>
-
-# include <mln/fun/i2v/array.hh>
-# include <mln/fun/p2v/iota.hh>
-
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-# include <mln/level/transform.hh>
-# include <mln/extension/fill.hh>
-# include <mln/opt/at.hh>
-
-# include <mln/morpho/closing_area.hh>
-
-
-# include <mln/debug/println.hh>
-
-# include "src/distance.hh"
-
-
-namespace mln
-{
- template <typename I, typename N, typename Ic, typename Nc>
- struct min_tree_
- {
- typedef mln_site(I) point;
- typedef p_array<point> S;
-
- // in:
- const I& f;
- const N& nbh;
- const Ic& ref;
- const Nc& nbhc;
-
- // aux:
- S s;
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, point) parent;
- mln_ch_value(I, bool) resp;
- mln_ch_value(I, point) zpar;
-
- // attached data:
- int lambda;
- mln_ch_value(I, int) height;
- mln_ch_value(Ic, value::rgb8) color;
-
-
- min_tree_(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
- int lambda)
- : f(f),
- nbh(nbh),
- ref(ref),
- nbhc(nbhc),
- lambda(lambda)
- {
- run();
- }
-
- void run()
- {
- // init
- {
- initialize(deja_vu, f);
- initialize(parent, f);
- initialize(resp, f);
- initialize(zpar, f);
- initialize(height, f);
- initialize(color, f);
-
- mln::data::fill(deja_vu, false);
- mln::data::fill(color, value::rgb8(255, 255, 255));
- mln::data::fill(height, 0);
-
- s = level::sort_psites_increasing(f);
- }
-
- // first pass
- {
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- make_set(p);
- for_all(n)
- if (f.has(n) && deja_vu(n))
- do_union(n, p);
- deja_vu(p) = true;
- }
- }
-
- // second pass: canonization
- {
- mln_bkd_piter(S) p(s);
- for_all(p)
- {
- point q = parent(p);
- if (f(parent(q)) == f(q))
- {
- parent(p) = parent(q);
- resp(q) = false;
- }
- }
- }
-
- // third pass: Merging region with height < lambda
- {
- mln_fwd_piter(S) p(s);
- for_all(p)
- {
- if (resp(p) && (height(p) < lambda))
- {
- resp(p) = false;
- update_data(parent(p), height(p), color(p));
- }
- }
- }
-
- } // end of run()
-
- void make_set(const point& p)
- {
- parent(p) = p;
- zpar(p) = p;
- init_data(p);
- }
-
- void set_parent(const point& r, const point& p)
- {
- parent(r) = p;
- merge_data(r, p);
- }
-
- bool is_root(const point& p) const
- {
- return parent(p) == p;
- }
-
- bool is_node(const point& p) const
- {
- //return is_root(p) || f(parent(p)) != f(p);
- return (is_root(p) || resp(p));
- }
-
- point find_root(const point& x)
- {
- if (zpar(x) == x)
- return x;
- else
- return zpar(x) = find_root(zpar(x));
- }
-
- point find_representative(const point& x)
- {
- if (parent(x) == x || resp(x))
- return x;
- else
- return find_representative(parent(x));
- }
-
- void do_union(const point& n, const point& p)
- {
- point r = find_root(n);
- if (r != p)
- {
- set_parent(r, p);
- zpar(r) = p;
- }
- }
-
- void init_data(const point& p)
- {
- // init height
- height(p) = f(p);
-
-
- // init color
- int red =0, green = 0, blue = 0;
-
- mln_niter(Nc) n(nbhc, p);
- for_all(n)
- {
- red += ref(n).red();
- green += ref(n).green();
- blue += ref(n).blue();
- }
-
- red /= 2;
- green /= 2;
- blue /= 2;
-
- color(p).red() = red;
- color(p).green() = green;
- color(p).blue() = blue;
-
-
- resp(p) = true;
- }
-
- void merge_data(const point& r, const point& p)
- {
- if (f(p) == f(r))
- {
- resp(p) = false;
-
- // merge height
- height(r) += height(r) > height(p) ? height(r) : height(p);
-
- // merge color
- color(r) = (color(r) + color(p)) / 2;
- }
- }
-
- void update_data(const point& p, int val, value::rgb8 c)
- {
- // update height
- height(p) = height(p) > val ? height(p) : val;
- // update color
- color(p) = (color(p) + c) / 2;
-
- if (parent(p) != p && !resp(p))
- update_data(parent(p), val, color(p));
- }
-
- };
-}
-
-namespace mln
-{
- image2d<value::int_u16> convert_to_grey(const image2d<value::rgb8>& data)
- {
- image2d<value::int_u16> output(data.domain());
- mln_piter_(image2d<value::int_u16>) p(output.domain());
- for_all(p)
- output(p) = (int) (data(p).red() * 0.3 + data(p).green() * 0.58 + data(p).blue()) * 0.12;
- return output;
- }
-} // end of mln
-
-namespace mln
-{
-
- struct colorize : Function_v2v< colorize >
- {
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
- };
-
- template <typename I>
- I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
- data::fill(output, bg);
-
- mln_VAR(edge, ima | is_edge);
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-
- template <typename I>
- I display_edge(const I& ima, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
-
- mln_VAR( cell, ima | is_cell );
- mln_piter(cell_t) q(cell.domain());
- for_all(q)
- {
- unsigned row = (q.row() / 2) * (zoom + 1);
- unsigned col = (q.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- for (unsigned j = 0; j < zoom; ++j)
- opt::at(output, row + i, col + j) = ima(q);
- }
-
- mln_VAR( edge, ima | is_edge );
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-
- namespace morpho
- {
-
- template <typename I, typename N>
- mln_concrete(I)
- dilation(const I& input, const N& nbh)
- {
- typedef mln_value(I) V;
-
- mln_concrete(I) output;
- initialize(output, input);
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (input.has(n) && input(n) != value::rgb8(0,0,0))
- output(p) = input(n);
- }
- return output;
- }
- } // mln::morpho
-
-} // mln
-
-
-
-template <typename T>
-mln::image2d<T>
-image2cells(const mln::image2d<T>& input)
-{
- mln::image2d<T> output(2 * input.nrows() - 1,
- 2 * input.ncols() - 1);
- for (unsigned row = 0; row < input.nrows(); ++row)
- for (unsigned col = 0; col < input.ncols(); ++col)
- mln::opt::at(output, 2 * row, 2 * col) =
- mln::opt::at(input, row, col);
- return output;
-}
-
-
-template <typename T>
-mln::image2d<T>
-cells2image(const mln::image2d<T>& input)
-{
- mln::image2d<T> output((input.nrows() + 1) / 2,
- (input.ncols() + 1) / 2);
- for (unsigned row = 0; row < input.nrows(); row += 2)
- for (unsigned col = 0; col < input.ncols(); col += 2)
- mln::opt::at(output, row / 2, col / 2) =
- mln::opt::at(input, row, col);
- return output;
-}
-
-
-
-
-template <typename I, typename N, typename Ic, typename Nc>
-unsigned min_tree(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
- int lambda)
-{
- using namespace mln;
-
- min_tree_<I,N,Ic,Nc> run(f, nbh, ref, nbhc, lambda);
-
-
- mln_piter(I) p(f.domain());
- unsigned nnodes = 0;
- for_all(p)
- {
- if (run.is_node(p))
- ++nnodes;
- }
-
- colorize colors(nnodes);
- image2d<value::rgb8> tmp(ref.domain());
- data::fill(tmp, literal::black);
- image2d<value::rgb8> tmp2(ref.domain());
- data::fill(tmp, ref);
-
- mln_piter(I) q(f.domain());
- unsigned int i = 0;
- for_all(q)
- {
- if (run.is_node(q))
- {
- tmp(q) = run.color(q);
- tmp2(q) = colors(i);
- i++;
- }
- }
-
- mln_piter(I) r(f.domain());
- for_all(r)
- {
- if (!run.is_node(r))
- {
- tmp(r) = tmp(run.find_representative(r));
- tmp2(r) = tmp2(run.find_representative(r));
- }
- }
-
- image2d<value::rgb8> to_display(tmp.domain());
- image2d<value::rgb8> to_display2(tmp2.domain());
-
- data::fill(to_display, literal::black);
- data::paste((tmp | is_edge), to_display);
- data::paste(morpho::dilation(to_display, c4()), to_display);
-
- data::fill(to_display2, literal::black);
- data::paste((tmp2 | is_edge), to_display2);
- data::paste(morpho::dilation(to_display2, c4()), to_display2);
-
-
- io::ppm::save(display_edge(tmp, literal::black, 3), "edge.ppm");
- io::ppm::save(tmp, "full.ppm");
- io::ppm::save(cells2image(to_display), "colorize.ppm");
-
- io::ppm::save(display_edge(tmp2, literal::black, 3), "edge2.ppm");
- io::ppm::save(cells2image(to_display2), "colorize2.ppm");
-
- return nnodes;
-}
-
-
-
-template <typename I>
-I
-do_it(I& input, int lambda, unsigned& nbasins)
-{
- using namespace mln;
-
- /// Graph creation
- I graph;
- create_graph(input, graph, value::rgb8(0, 0, 0));
-
- // Initialization
- image2d<value::int_u16> ima = convert_to_grey(graph);
-
- // Neigbhorhood
- // e2c
- bool e2c_h[] = { 0, 1, 0,
- 0, 0, 0,
- 0, 1, 0 };
- bool e2c_v[] = { 0, 0, 0,
- 1, 0, 1,
- 0, 0, 0 };
-
- mln_VAR(e2c, make::double_neighb2d(is_row_odd, e2c_h, e2c_v));
-
- bool e2e_h[] = { 0, 0, 1, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 1, 0, 0 };
-
- bool e2e_v[] = { 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0 };
- mln_VAR(e2e, make::double_neighb2d(is_row_odd, e2e_h, e2e_v));
-
- // Algorithm
- distance(extend((graph | is_edge).rw(), pw::value(graph)), e2c, ima);
-
- io::pgm::save(ima, "edge.pgm");
-
- nbasins = min_tree((ima | is_edge), e2e, graph, e2c, lambda);
-
- return graph;
-}
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm lambda" << std::endl;
- std::cerr << " lambda >= 0" << std::endl;
- abort();
-}
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
-
- if (argc != 3)
- usage(argv);
-
- int lambda = atoi(argv[2]);
- if (lambda < 0)
- usage(argv);
-
- image2d<value::rgb8> ima;
- io::ppm::load(ima, argv[1]);
-
- unsigned nbasins;
- image2d<value::rgb8> output = do_it(ima, lambda, nbasins);
-
- //io::ppm::save(output, argv[3]);
-}
Index: ballas/color/min_tree_color.cc
--- ballas/color/min_tree_color.cc (revision 3184)
+++ ballas/color/min_tree_color.cc (working copy)
@@ -1,536 +0,0 @@
-# include <mln/core/var.hh>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image/extended.hh>
-# include <mln/core/routine/extend.hh>
-
-# include <mln/core/alias/window2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/make/double_neighb2d.hh>
-# include <mln/core/site_set/p_centered.hh>
-
-# include <mln/literal/origin.hh>
-# include <mln/literal/black.hh>
-# include <mln/literal/white.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pgm/save.hh>
-
-# include <mln/value/rgb8.hh>
-# include <mln/io/ppm/load.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/accu/min_max.hh>
-
-# include <mln/fun/i2v/array.hh>
-# include <mln/fun/p2v/iota.hh>
-
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-# include <mln/level/transform.hh>
-# include <mln/extension/fill.hh>
-
-# include <mln/morpho/closing_area.hh>
-# include <mln/opt/at.hh>
-
-
-# include <mln/debug/println.hh>
-
-# if 0
-# include <mln/core/concept/image.hh>
-# include <mln/core/concept/neighborhood.hh>
-# include <mln/util/pix.hh>
-# include <mln/morpho/includes.hh>
-# include <mln/level/sort_psites.hh>
-#endif
-
-# include "src/distance.hh"
-
-namespace mln
-{
- template <typename I, typename N, typename Ic, typename Nc>
- struct min_tree_
- {
- typedef mln_site(I) point;
- typedef p_array<point> S;
-
- // in:
- const I& f;
- const N& nbh;
- const Ic& ref;
- const Nc& nbhc;
-
- // aux:
- S s;
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, point) parent;
- mln_ch_value(I, bool) resp;
- mln_ch_value(I, point) zpar;
-
- // attached data:
- unsigned lambda;
- mln_ch_value(I, value::rgb8) color;
- //mln_ch_value(Ic, value::rgb8) values;
- //initialize(values, ref);
- //mln_ch_value(I, int) comp;
-
- min_tree_(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
- int lambda)
- : f(f),
- nbh(nbh),
- ref(ref),
- nbhc(nbhc),
- lambda(lambda)
- {
- run();
- }
-
- void run()
- {
- // init
- {
- initialize(deja_vu, f);
- initialize(parent, f);
- initialize(resp, f);
- initialize(zpar, f);
- initialize(color, f);
- //initialize(comp, f);
-
- mln::data::fill(deja_vu, false);
- //mln::data::fill(resp, false);
- mln::data::fill(color, value::rgb8(0, 0, 0));
-
- s = level::sort_psites_increasing(f);
- }
-
- // first pass
- {
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- make_set(p);
- for_all(n)
- if (f.has(n) && deja_vu(n))
- do_union(n, p);
- deja_vu(p) = true;
- }
- }
-
- // second pass: canonization
- {
- mln_bkd_piter(S) p(s);
- for_all(p)
- {
- point q = parent(p);
- if (f(parent(q)) == f(q))
- {
- parent(p) = parent(q);
- resp(q) = false;
- }
- }
- }
-
- // third pass: Merging region with distance(color) < lambda
- {
- mln_fwd_piter(S) p(s);
- for_all(p)
- {
- point q = parent(p);
- if (resp(p) && distance(color(p), color(q)) < lambda)
- {
- resp(p) = false;
- update_data(q, color(p));
- }
- }
- }
-
- } // end of run()
-
- void make_set(const point& p)
- {
- parent(p) = p;
- zpar(p) = p;
- init_data(p);
- }
-
- void set_parent(const point& r, const point& p)
- {
- parent(r) = p;
- merge_data(r, p);
- }
-
- bool is_root(const point& p) const
- {
- return parent(p) == p;
- }
-
- bool is_node(const point& p) const
- {
- //return is_root(p) || f(parent(p)) != f(p);
- return (is_root(p) || resp(p));
- }
-
- point find_root(const point& x)
- {
- if (zpar(x) == x)
- return x;
- else
- return zpar(x) = find_root(zpar(x));
- }
-
- point find_representative(const point& x)
- {
- if (parent(x) == x || resp(x))
- return x;
- else
- return find_representative(parent(x));
- }
-
- void do_union(const point& n, const point& p)
- {
- point r = find_root(n);
- if (r != p)
- {
- set_parent(r, p);
- zpar(r) = p;
- }
- }
-
- void init_data(const point& p)
- {
- int red =0, green = 0, blue = 0;
-
- mln_niter(Nc) n(nbhc, p);
- for_all(n)
- {
- red += ref(n).red();
- green += ref(n).green();
- blue += ref(n).blue();
- }
-
- red /= 2;
- green /= 2;
- blue /= 2;
-
- color(p).red() = red;
- color(p).green() = green;
- color(p).blue() = blue;
-
- resp(p) = true;
- }
-
- void merge_data(const point& r, const point& p)
- {
- if (f(p) == f(r))
- {
- resp(p) = false;
- color(r) = (color(r) + color(p)) / 2;
- }
- }
-
- void update_data(const point& p, value::rgb8 val)
- {
- color(p) = (color(p) + val) / 2;
- if (parent(p) != p && !resp(p))
- update_data(parent(p), color(p));
- }
-
- };
-}
-
-namespace mln
-{
- image2d<value::int_u16> convert_to_grey(const image2d<value::rgb8>& data)
- {
- image2d<value::int_u16> output(data.domain());
- mln_piter_(image2d<value::int_u16>) p(output.domain());
- for_all(p)
- output(p) = (int) (data(p).red() * 0.3 + data(p).green() * 0.58 + data(p).blue()) * 0.12;
- return output;
- }
-} // end of mln
-
-namespace mln
-{
-
- struct colorize : Function_v2v< colorize >
- {
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
- };
-
- template <typename I>
- I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
- data::fill(output, bg);
-
- mln_VAR(edge, ima | is_edge);
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
- template <typename I>
- I display_edge(const I& ima, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
-
- mln_VAR( cell, ima | is_cell );
- mln_piter(cell_t) q(cell.domain());
- for_all(q)
- {
- unsigned row = (q.row() / 2) * (zoom + 1);
- unsigned col = (q.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- for (unsigned j = 0; j < zoom; ++j)
- opt::at(output, row + i, col + j) = ima(q);
- }
-
- mln_VAR( edge, ima | is_edge );
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-
- namespace morpho
- {
-
- template <typename I, typename N>
- mln_concrete(I)
- dilation(const I& input, const N& nbh)
- {
- typedef mln_value(I) V;
-
- mln_concrete(I) output;
- initialize(output, input);
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (input.has(n) && input(n) != value::rgb8(0,0,0))
- output(p) = input(n);
- }
- return output;
- }
- } // mln::morpho
-
-} // mln
-
-
-
-template <typename T>
-mln::image2d<T>
-image2cells(const mln::image2d<T>& input)
-{
- mln::image2d<T> output(2 * input.nrows() - 1,
- 2 * input.ncols() - 1);
- for (unsigned row = 0; row < input.nrows(); ++row)
- for (unsigned col = 0; col < input.ncols(); ++col)
- mln::opt::at(output, 2 * row, 2 * col) =
- mln::opt::at(input, row, col);
- return output;
-}
-
-
-template <typename T>
-mln::image2d<T>
-cells2image(const mln::image2d<T>& input)
-{
- mln::image2d<T> output((input.nrows() + 1) / 2,
- (input.ncols() + 1) / 2);
- for (unsigned row = 0; row < input.nrows(); row += 2)
- for (unsigned col = 0; col < input.ncols(); col += 2)
- mln::opt::at(output, row / 2, col / 2) =
- mln::opt::at(input, row, col);
- return output;
-}
-
-
-template <typename I, typename N, typename Ic, typename Nc>
-unsigned min_tree(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
- int lambda)
-{
- using namespace mln;
-
- min_tree_<I,N,Ic,Nc> run(f, nbh, ref, nbhc, lambda);
-
-
- mln_piter(I) p(f.domain());
- unsigned nnodes = 0;
- for_all(p)
- {
- if (run.is_node(p))
- ++nnodes;
- }
-
-#if 1
- colorize colors(nnodes);
- image2d<value::rgb8> tmp(ref.domain());
- data::fill(tmp, ref);
-
-
- mln_piter(I) q(f.domain());
- unsigned int i = 0;
- for_all(q)
- {
- if (run.is_node(q))
- {
- tmp(q) = colors(i);
- i++;
- }
- }
- mln_piter(I) r(f.domain());
- for_all(r)
- {
- if (!run.is_node(r))
- tmp(r) = tmp(run.find_representative(r));
- }
-
- image2d<value::rgb8> to_display(tmp.domain());
-
- data::fill(to_display, value::rgb8(255, 255, 255));
- data::paste((tmp | is_edge), to_display);
- data::paste(morpho::dilation(to_display, c4()), to_display);
-
- io::ppm::save(display_edge(tmp, literal::white, 3),
- "edge.ppm");
- io::ppm::save(tmp, "full.ppm");
- io::ppm::save(cells2image(to_display), "colorize.ppm");
-#endif
-
-#if 1
- // io::ppm::save(display_edge(run.values, literal::white, 3), "tmp_tree_colored.pgm");
-#endif
-
- return nnodes;
-}
-
-
-template <typename I>
-I
-do_it(I& input, int lambda, unsigned& nbasins)
-{
- using namespace mln;
-
- /// Graph creation
- I graph;
- create_graph(input, graph, value::rgb8(0, 0, 0));
-
- // Initialization
- image2d<value::int_u16> ima = convert_to_grey(graph);
-
- // Neigbhorhood
- // e2c
- bool e2c_h[] = { 0, 1, 0,
- 0, 0, 0,
- 0, 1, 0 };
- bool e2c_v[] = { 0, 0, 0,
- 1, 0, 1,
- 0, 0, 0 };
-
- mln_VAR(e2c, make::double_neighb2d(is_row_odd, e2c_h, e2c_v));
-
- bool e2e_h[] = { 0, 0, 1, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 1, 0, 0 };
-
- bool e2e_v[] = { 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0 };
- mln_VAR(e2e, make::double_neighb2d(is_row_odd, e2e_h, e2e_v));
-
- // Algorithm
- distance(extend((graph | is_edge).rw(), pw::value(graph)), e2c, ima);
-
- io::pgm::save(ima, "edge.pgm");
-
- nbasins = min_tree((ima | is_edge), e2e, graph, e2c, lambda);
-
- return graph;
-}
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm lambda" << std::endl;
- std::cerr << " lambda >= 0" << std::endl;
- abort();
-}
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
-
- if (argc != 3)
- usage(argv);
-
- int lambda = atoi(argv[2]);
- if (lambda < 0)
- usage(argv);
-
- image2d<value::rgb8> ima;
- io::ppm::load(ima, argv[1]);
-
- unsigned nbasins;
- image2d<value::rgb8> output = do_it(ima, lambda, nbasins);
-
- //io::ppm::save(output, argv[3]);
-}
Index: ballas/color/reference2.cc
--- ballas/color/reference2.cc (revision 3184)
+++ ballas/color/reference2.cc (working copy)
@@ -1,408 +0,0 @@
-# include <mln/core/var.hh>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image/extended.hh>
-# include <mln/core/routine/extend.hh>
-
-# include <mln/core/alias/window2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/make/double_neighb2d.hh>
-# include <mln/core/site_set/p_centered.hh>
-
-# include <mln/literal/origin.hh>
-# include <mln/literal/black.hh>
-# include <mln/literal/white.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pgm/save.hh>
-
-# include <mln/value/rgb8.hh>
-# include <mln/io/ppm/load.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/accu/min_max.hh>
-# include <mln/accu/mean.hh>
-
-# include <mln/fun/i2v/array.hh>
-# include <mln/fun/p2v/iota.hh>
-
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-# include <mln/level/transform.hh>
-# include <mln/extension/fill.hh>
-
-# include <mln/morpho/meyer_wst.hh>
-# include <mln/morpho/closing_volume.hh>
-
-# include <mln/linear/convolve.hh>
-# include <mln/make/w_window2d.hh>
-
-# include <mln/opt/at.hh>
-
-# include <mln/debug/println.hh>
-
-namespace mln
-{
- namespace morpho
- {
- template <typename I, typename N>
- mln_concrete(I)
- closing_volume(const I& input, const Neighborhood<N>& nbh, std::size_t lambda)
- {
- mln_concrete(I) output;
- initialize(output, input);
- closing_volume(input, nbh, lambda, output);
- return output;
- }
- }
-}
-
-namespace mln
-{
- template <typename I, typename O>
- void
- LoG_17x17(const I& input, const O& output)
- {
- mln_precondition(exact(output).domain() == exact(input).domain());
- int ws[] = { +0, 0, 0, 0, 0, 0,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0,
- +0, 0, 0, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0,
- +0, 0,-1,-1,-1,-2,-3,-3,-3,-3,-3,-2,-1,-1,-1, 0, 0,
- +0, 0,-1,-1,-2,-3,-3,-3,-3,-3,-3,-3,-2,-1,-1, 0, 0,
- +0,-1,-1,-2,-3,-3,-3,-2,-3,-2,-3,-3,-3,-2,-1,-1, 0,
- +0,-1,-2,-3,-3,-3, 0, 2, 4, 2, 0,-3,-3,-3,-2,-1, 0,
- -1,-1,-3,-3,-3, 0, 4,10,12,10, 4, 0,-3,-3,-3,-1,-1,
- -1,-1,-3,-3,-2, 2,10,18,21,18,10, 2,-2,-3,-3,-1,-1,
- -1,-1,-3,-3,-3, 4,12,21,24,21,12, 4,-3,-3,-3,-1,-1,
- -1,-1,-3,-3,-2, 2,10,18,21,18,10, 2,-2,-3,-3,-1,-1,
- -1,-1,-3,-3,-3, 0, 4,10,12,10, 4, 0,-3,-3,-3,-1,-1,
- +0,-1,-2,-3,-3,-3, 0, 2, 4, 2, 0,-3,-3,-3,-2,-1, 0,
- +0,-1,-1,-2,-3,-3,-3,-2,-3,-2,-3,-3,-3,-2,-1,-1, 0,
- +0, 0,-1,-1,-2,-3,-3,-3,-3,-3,-3,-3,-2,-1,-1, 0, 0,
- +0, 0,-1,-1,-1,-2,-3,-3,-3,-3,-3,-2,-1,-1,-1, 0, 0,
- +0, 0, 0, 0,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0,
- +0, 0, 0, 0, 0, 0,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0 };
- linear::convolve(input, make::w_window2d(ws), output);
- }
-} // !mln
-
-namespace mln
-{
- image2d<value::int_u8> convert_to_grey(const image2d<value::rgb8>& data)
- {
- image2d<value::int_u8> output(data.domain());
- mln_piter_(image2d<value::int_u8>) p(output.domain());
- for_all(p)
- output(p) = (int) (data(p).red() * 0.3 + data(p).green() * 0.58 + data(p).blue()) * 0.12;
- return output;
- }
-} // !mln
-
-// Functions
-
-inline
-bool is_row_odd(const mln::point2d& p)
-{
- return p.row() % 2;
-}
-
-inline
-bool is_cell(const mln::point2d& p)
-{
- return p.row() % 2 == 0 && p.col() % 2 == 0;
-}
-
-inline
-bool is_edge(const mln::point2d& p)
-{
- return p.row() % 2 + p.col() % 2 == 1;
-}
-
-inline
-bool is_point(const mln::point2d& p)
-{
- return p.row() % 2 && p.col() % 2;
-}
-
-inline
-bool is_not_edge(const mln::point2d& p)
-{
- return ! is_edge(p);
-}
-
-
-
-namespace mln
-{
-
- namespace border
- {
-
- template <typename I>
- void
- fill(I& ima, const mln_value(I)& v)
- {
- const int nrows = ima.nrows();
- const int ncols = ima.ncols();
- for (int r = -1; r <= nrows; ++r)
- {
- opt::at(ima, r, -1) = v;
- opt::at(ima, r, ncols) = v;
- }
- for (int c = -1; c <= ncols; ++c)
- {
- opt::at(ima, -1, c) = v;
- opt::at(ima, nrows, c) = v;
- }
- }
-
- } // mln::border
-
- namespace accu
- {
-
- template <typename I, typename L, typename A, typename V>
- inline
- void
- compute(const Image<I>& input_,
- const Image<L>& label_,
- const Accumulator<A>&,
- V& v)
- {
- trace::entering("accu::compute");
-
- const I& input = exact(input_);
- const L& label = exact(label_);
-
- const unsigned n = v.size();
- std::vector<A> a(n);
-
- mln_piter(I) p(input.domain());
- for_all(p)
- a[label(p)].take(input(p));
-
- for (unsigned l = 1; l < n; ++l)
- v(l) = a[l].to_result();
-
- trace::exiting("accu::compute");
- }
-
- } // mln::accu
-
- namespace morpho
- {
-
- template <typename I, typename N>
- mln_concrete(I)
- gradient(const I& input, const N& nbh)
- {
- mln_concrete(I) output;
- initialize(output, input);
- accu::min_max<mln_value(I)> mm;
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- mm.init();
- for_all(n) if (input.has(n))
- mm.take(input(n));
- output(p) = mm.second() - mm.first();
- }
- return output;
- }
-
- template <typename I, typename N>
- mln_concrete(I)
- dilation(const I& input, const N& nbh)
- {
- typedef mln_value(I) V;
-
- mln_concrete(I) output;
- initialize(output, input);
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (input.has(n) && input(n) != value::rgb8(0,0,0))
- output(p) = input(n);
- }
- return output;
- }
- } // mln::morpho
-
-
- struct colorize : Function_v2v< colorize >
- {
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
- };
-
-
- template <typename I>
- I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
- data::fill(output, bg);
- mln_VAR( edge, ima | is_edge );
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-} // mln
-
-
-
-template <typename T>
-mln::image2d<T>
-image2cells(const mln::image2d<T>& input)
-{
- mln::image2d<T> output(2 * input.nrows() - 1,
- 2 * input.ncols() - 1);
- for (int row = 0; row < input.nrows(); ++row)
- for (int col = 0; col < input.ncols(); ++col)
- mln::opt::at(output, 2 * row, 2 * col) = mln::opt::at(input, row, col);
- return output;
-}
-
-
-template <typename T>
-mln::image2d<T>
-cells2image(const mln::image2d<T>& input)
-{
- mln::image2d<T> output((input.nrows() + 1) / 2,
- (input.ncols() + 1) / 2);
- for (int row = 0; row < input.nrows(); row += 2)
- for (int col = 0; col < input.ncols(); col += 2)
- mln::opt::at(output, row / 2, col / 2) = mln::opt::at(input, row, col);
- return output;
-}
-
-
-
-
-template <typename I>
-mln_concrete(I)
-do_it(I& input, int lambda, unsigned& nbasins)
-{
- using namespace mln;
-
- /******************/
- /* Initialisation */
- /******************/
-
- image2d<value::int_u8> ima = image2cells(convert_to_grey(input));
-
- /**************************/
- /* Neighborhood defintion */
- /**************************/
-
- // e2c
- bool e2c_h[] = { 0, 1, 0,
- 0, 0, 0,
- 0, 1, 0 };
- bool e2c_v[] = { 0, 0, 0,
- 1, 0, 1,
- 0, 0, 0 };
- mln_VAR( e2c, make::double_neighb2d(is_row_odd, e2c_h, e2c_v) );
-
- // e2e
- bool e2e_h[] = { 0, 0, 1, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 1, 0, 0 };
- bool e2e_v[] = { 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0 };
- mln_VAR( e2e, make::double_neighb2d(is_row_odd, e2e_h, e2e_v) );
-
- // cell
- mln_VAR(cell, ima | is_cell);
-
- // edge
- mln_VAR(edge, extend((ima | is_edge).rw(), pw::value(ima)));
-
- // FIXME until laplacian is working use gradient / closing_area / wst
-
- data::paste(morpho::gradient(edge, e2c), edge);
- data::paste(morpho::closing_volume(edge, e2e, lambda), edge);
- data::fill(edge, morpho::meyer_wst(edge, e2e, nbasins));
-
- // Fill regions (with colorize) (won't work with laplacian...)
-
- colorize colors(nbasins);
-
- image2d<value::rgb8> cells(ima.domain());
- data::fill(cells, literal::white);
- data::paste(level::transform(edge, colors), cells);
- io::ppm::save(display_edge(cells, literal::white, 3), "tmp_edge.ppm");
-
- // Move the color of an edge which is non black in the cell
- data::paste(morpho::dilation(cells, c4()), cells);
-
- return cells2image(cells);
-}
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm lambda output.ppm" << std::endl;
- std::cerr << " lambda >= 0" << std::endl;
- abort();
-}
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
-
- if (argc != 4)
- usage(argv);
-
- int lambda = atoi(argv[2]);
- if (lambda < 0)
- usage(argv);
-
- image2d<value::rgb8> ima;
- io::ppm::load(ima, argv[1]);
-
- unsigned nbasins;
- image2d<value::rgb8> output = do_it(ima, lambda, nbasins);
-
- io::ppm::save(output, argv[3]);
-}
Index: ballas/color/src/graph.hh
--- ballas/color/src/graph.hh (revision 3184)
+++ ballas/color/src/graph.hh (working copy)
@@ -1,62 +0,0 @@
-/*! \file src/graph.hh
- *
- */
-
-#ifndef SRC_GRAPH_HH
-# define SRC_GRAPH_HH
-
-# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
-# include <mln/value/rgb8.hh>
-
-# include <mln/data/fill.hh>
-# include <mln/opt/at.hh>
-
-# include <mln/core/image/image2d.hh>
-
-
-// Neighborhood functions
-inline
-bool is_row_odd(const mln::point2d& p)
-{
- return p.row() % 2;
-}
-inline
-bool is_cell(const mln::point2d& p)
-{
- return p.row() % 2 == 0 && p.col() % 2 == 0;
-}
-inline
-bool is_edge(const mln::point2d& p)
-{
- return (p.row() % 2 + p.col() % 2) == 1;
-}
-inline
-bool is_point(const mln::point2d& p)
-{
- return p.row() % 2 && p.col() % 2;
-}
-inline
-bool is_not_edge(const mln::point2d& p)
-{
- return ! is_edge(p);
-}
-
-// Graph image creation function
-// FIXME: add exact conversion....
-// FIXME: check that the input image is in 2 dimension
-template <typename I>
-void
-create_graph(const I& ima, I& graph, mln_value(I) val)
-{
- graph = I(ima.nrows() * 2 -1, ima.ncols() * 2 - 1);
-
- mln::data::fill(graph, val);
-
- mln_piter(I) p(ima.domain());
- for_all(p)
- mln::opt::at(graph, p.row() * 2, p.col() * 2) = ima(p);
-}
-
-
-#endif // !SRC_GRAPH_HH
Index: ballas/color/src/io.hh
--- ballas/color/src/io.hh (revision 3184)
+++ ballas/color/src/io.hh (working copy)
@@ -1,57 +0,0 @@
-/*! \file src/io.hh
- *
- * Contains various method to load/save an image
- */
-
-#ifndef SRC_IO_HH
-# define SRC_IO_HH
-
-#include <mln/core/image/image2d.hh>
-
-#include <mln/value/int_u16.hh>
-#include <mln/value/int_s16.hh>
-
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pgm/save.hh>
-# include <mln/io/ppm/load.hh>
-# include <mln/io/ppm/save.hh>
-
-namespace IO
-{
-
- template <typename I>
- void load(I& ima, const std::string& file)
- {
- mln::io::ppm::load(ima, file);
- }
-
- template <>
- void load(mln::image2d<mln::value::int_u16>& ima,
- const std::string& file)
- {
- mln::io::pgm::load(ima, file);
- }
-
- template <typename I>
- void save(I& ima, const std::string& file)
- {
- mln::io::ppm::save(ima, file);
- }
-
- template <>
- void save(mln::image2d<mln::value::int_u16>& ima,
- const std::string& file)
- {
- mln::io::pgm::save(ima, file);
- }
-
- template <>
- void save(mln::image2d<mln::value::int_s16>& ima,
- const std::string& file)
- {
- mln::io::pgm::save(ima, file);
- }
-
-} // !IO
-
-#endif // !SRC_IO_HH
Index: ballas/color/src/distance.hh
--- ballas/color/src/distance.hh (revision 3184)
+++ ballas/color/src/distance.hh (working copy)
@@ -1,52 +0,0 @@
-/*! \file src/distance.hh
- *
- */
-
-#ifndef SRC_DISTANCE_HH
-# define SRC_DISTANCE_HH
-
-# include "graph.hh"
-
-# include <cmath>
-
-
-/// Manhatan distance
-inline
-unsigned distance(const mln::value::rgb8& lhs,
- const mln::value::rgb8& rhs)
-{
- return abs(lhs.red() - rhs.red()) +
- abs(lhs.green() - rhs.green()) +
- abs(lhs.blue() - rhs.blue());
-}
-
-
-/// Store the distance between two points on edge
-/// FIXME documentation
-template <typename I, typename N, typename O>
-void distance(const I& rgb_graph,
- const N& nbh,
- O& gl_graph)
-{
- mln_piter(I) p(rgb_graph.domain());
- mln_niter(N) n(nbh, p);
-
- for_all(p)
- {
- mln::value::rgb8 v1;
- mln::value::rgb8 v2;
-
- n.start();
- assert(n.is_valid() && rgb_graph.has(n));
- v1 = rgb_graph(n);
- n.next();
- assert(n.is_valid() && rgb_graph.has(n));
- v2 = rgb_graph(n);
-
- gl_graph(p) = distance(v1, v2);
- }
-}
-
-
-
-#endif // !SRC_DISTANCE_HH
Index: ballas/color/src/convert.hh
--- ballas/color/src/convert.hh (revision 3184)
+++ ballas/color/src/convert.hh (working copy)
@@ -1,37 +0,0 @@
-/*! \file src/convert.hh
- *
- * Method that convert an rgb image 2d into gray level
- */
-
-#ifndef SRC_CONVERT_HH
-# define SRC_CONVERT_HH
-
-# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
-# include <mln/value/int_s16.hh>
-# include <mln/value/rgb8.hh>
-
-# include <mln/core/image/image2d.hh>
-
-// Convert function
-void convert_to_gl(mln::image2d<mln::value::int_u16>& ima,
- const mln::image2d<mln::value::rgb8>& data)
-{
- mln_piter_(mln::image2d<mln::value::int_u16>) p(ima.domain());
- for_all(p)
- ima(p) = (int) (data(p).red() * 0.3 +
- data(p).green() * 0.58 +
- data(p).blue() * 0.12);
-}
-
-void convert_to_gl(mln::image2d<mln::value::int_s16>& ima,
- const mln::image2d<mln::value::rgb8>& data)
-{
- mln_piter_(mln::image2d<mln::value::int_s16>) p(ima.domain());
- for_all(p)
- ima(p) = (int) (data(p).red() * 0.3 +
- data(p).green() * 0.58 +
- data(p).blue() * 0.12);
-}
-
-#endif // !SRC_CONVERT_HH
Index: ballas/color/min_tree_color_v2.cc
--- ballas/color/min_tree_color_v2.cc (revision 3184)
+++ ballas/color/min_tree_color_v2.cc (working copy)
@@ -1,533 +0,0 @@
-# include <mln/core/var.hh>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/core/image/image_if.hh>
-# include <mln/core/image/extended.hh>
-# include <mln/core/routine/extend.hh>
-
-# include <mln/core/alias/window2d.hh>
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/make/double_neighb2d.hh>
-# include <mln/core/site_set/p_centered.hh>
-
-
-# include <mln/literal/black.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
-# include <mln/io/pgm/load.hh>
-# include <mln/io/pgm/save.hh>
-
-# include <mln/value/rgb8.hh>
-# include <mln/io/ppm/load.hh>
-# include <mln/io/ppm/save.hh>
-
-# include <mln/accu/min_max.hh>
-
-# include <mln/fun/i2v/array.hh>
-# include <mln/fun/p2v/iota.hh>
-
-# include <mln/data/paste.hh>
-# include <mln/data/fill.hh>
-# include <mln/level/transform.hh>
-# include <mln/extension/fill.hh>
-
-# include <mln/morpho/closing_area.hh>
-# include <mln/opt/at.hh>
-
-
-# include <mln/debug/println.hh>
-
-# include "src/distance.hh"
-
-namespace mln
-{
- template <typename I, typename N, typename Ic, typename Nc>
- struct min_tree_
- {
- typedef mln_site(I) point;
- typedef p_array<point> S;
-
- // in:
- const I& f;
- const N& nbh;
- const Ic& ref;
- const Nc& nbhc;
-
- // aux:
- S s;
- mln_ch_value(I, bool) deja_vu;
- mln_ch_value(I, point) parent;
- mln_ch_value(I, bool) resp;
- mln_ch_value(I, point) zpar;
-
- // attached data:
- unsigned lambda;
- mln_ch_value(I, value::rgb8) color;
- //mln_ch_value(Ic, value::rgb8) values;
- //initialize(values, ref);
- //mln_ch_value(I, int) comp;
-
- min_tree_(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
- int lambda)
- : f(f),
- nbh(nbh),
- ref(ref),
- nbhc(nbhc),
- lambda(lambda)
- {
- run();
- }
-
- void run()
- {
- // init
- {
- initialize(deja_vu, f);
- initialize(parent, f);
- initialize(resp, f);
- initialize(zpar, f);
- initialize(color, f);
-
- mln::data::fill(deja_vu, false);
- mln::data::fill(color, value::rgb8(255, 255, 255));
-
- s = level::sort_psites_increasing(f);
- }
-
- // first pass
- {
- mln_fwd_piter(S) p(s);
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- make_set(p);
- for_all(n)
- if (f.has(n) && deja_vu(n))
- do_union(n, p);
- deja_vu(p) = true;
- }
- }
-
- // second pass: canonization
- {
- mln_bkd_piter(S) p(s);
- for_all(p)
- {
- point q = parent(p);
- if (f(parent(q)) == f(q))
- {
- parent(p) = parent(q);
- resp(q) = false;
- }
- }
- }
-
- // third pass: Merging region with distance(color) < lambda
- {
- mln_fwd_piter(S) p(s);
- for_all(p)
- {
- point q = parent(p);
- if (resp(p) && distance(color(p), color(q)) < lambda)
- {
- resp(p) = false;
- update_data(q, color(p));
- }
- }
- }
-
- } // end of run()
-
- void make_set(const point& p)
- {
- parent(p) = p;
- zpar(p) = p;
- init_data(p);
- }
-
- void set_parent(const point& r, const point& p)
- {
- parent(r) = p;
- merge_data(r, p);
- }
-
- bool is_root(const point& p) const
- {
- return parent(p) == p;
- }
-
- bool is_node(const point& p) const
- {
- //return is_root(p) || f(parent(p)) != f(p);
- return (is_root(p) || resp(p));
- }
-
- point find_root(const point& x)
- {
- if (zpar(x) == x)
- return x;
- else
- return zpar(x) = find_root(zpar(x));
- }
-
- point find_representative(const point& x)
- {
- if (parent(x) == x || resp(x))
- return x;
- else
- return find_representative(parent(x));
- }
-
- void do_union(const point& n, const point& p)
- {
- point r = find_root(n);
- if (r != p)
- {
- set_parent(r, p);
- zpar(r) = p;
- }
- }
-
- void init_data(const point& p)
- {
- int red =0, green = 0, blue = 0;
-
- mln_niter(Nc) n(nbhc, p);
- for_all(n)
- {
- red += ref(n).red();
- green += ref(n).green();
- blue += ref(n).blue();
- }
-
- red /= 2;
- green /= 2;
- blue /= 2;
-
- color(p).red() = red;
- color(p).green() = green;
- color(p).blue() = blue;
-
- resp(p) = true;
- }
-
- void merge_data(const point& r, const point& p)
- {
- if (f(p) == f(r))
- {
- resp(p) = false;
- color(r) = (color(r) + color(p)) / 2;
- }
- }
-
- void update_data(const point& p, value::rgb8 val)
- {
- color(p) = (color(p) + val) / 2;
- if (parent(p) != p && !resp(p))
- update_data(parent(p), color(p));
- }
-
- };
-}
-
-namespace mln
-{
- image2d<value::int_u16> convert_to_grey(const image2d<value::rgb8>& data)
- {
- image2d<value::int_u16> output(data.domain());
- mln_piter_(image2d<value::int_u16>) p(output.domain());
- for_all(p)
- output(p) = (int) (data(p).red() * 0.3 + data(p).green() * 0.58 + data(p).blue()) * 0.12;
- return output;
- }
-} // end of mln
-
-namespace mln
-{
-
- struct colorize : Function_v2v< colorize >
- {
- typedef value::rgb8 result;
- colorize(unsigned max)
- : lut(max + 1)
- {
- lut[0] = literal::black;
- for (unsigned i = 1; i <= max; ++i)
- lut[i] = result(100 + std::rand() % 150,
- 100 + std::rand() % 150,
- 100 + std::rand() % 150);
- }
- result operator()(unsigned i) const
- {
- return lut[i];
- }
- std::vector<result> lut;
- };
-
- template <typename I>
- I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
- data::fill(output, bg);
-
- mln_VAR(edge, ima | is_edge);
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
- template <typename I>
- I display_edge(const I& ima, unsigned zoom)
- {
- unsigned nrows = ima.nrows() / 2 + 1;
- unsigned ncols = ima.ncols() / 2 + 1;
- I output(nrows * (zoom + 1) - 1,
- ncols * (zoom + 1) - 1);
-
- mln_VAR( cell, ima | is_cell );
- mln_piter(cell_t) q(cell.domain());
- for_all(q)
- {
- unsigned row = (q.row() / 2) * (zoom + 1);
- unsigned col = (q.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- for (unsigned j = 0; j < zoom; ++j)
- opt::at(output, row + i, col + j) = ima(q);
- }
-
- mln_VAR( edge, ima | is_edge );
- mln_piter(edge_t) p(edge.domain());
- for_all(p)
- if (p.row() % 2) // horizontal edge
- {
- unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
- unsigned col = (p.col() / 2) * (zoom + 1);
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row, col + i) = ima(p);
- }
- else // vertical edge
- {
- unsigned row = (p.row() / 2) * (zoom + 1);
- unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
- for (unsigned i = 0; i < zoom; ++i)
- opt::at(output, row + i, col) = ima(p);
- }
- return output;
- }
-
-
- namespace morpho
- {
-
- template <typename I, typename N>
- mln_concrete(I)
- dilation(const I& input, const N& nbh)
- {
- typedef mln_value(I) V;
-
- mln_concrete(I) output;
- initialize(output, input);
-
- mln_piter(I) p(input.domain());
- mln_niter(N) n(nbh, p);
- for_all(p)
- {
- for_all(n)
- if (input.has(n) && input(n) != value::rgb8(0,0,0))
- output(p) = input(n);
- }
- return output;
- }
- } // mln::morpho
-
-} // mln
-
-
-
-template <typename T>
-mln::image2d<T>
-image2cells(const mln::image2d<T>& input)
-{
- mln::image2d<T> output(2 * input.nrows() - 1,
- 2 * input.ncols() - 1);
- for (unsigned row = 0; row < input.nrows(); ++row)
- for (unsigned col = 0; col < input.ncols(); ++col)
- mln::opt::at(output, 2 * row, 2 * col) =
- mln::opt::at(input, row, col);
- return output;
-}
-
-
-template <typename T>
-mln::image2d<T>
-cells2image(const mln::image2d<T>& input)
-{
- mln::image2d<T> output((input.nrows() + 1) / 2,
- (input.ncols() + 1) / 2);
- for (unsigned row = 0; row < input.nrows(); row += 2)
- for (unsigned col = 0; col < input.ncols(); col += 2)
- mln::opt::at(output, row / 2, col / 2) =
- mln::opt::at(input, row, col);
- return output;
-}
-
-
-template <typename I, typename N, typename Ic, typename Nc>
-unsigned min_tree(const I& f, const N& nbh, const Ic& ref, const Nc& nbhc,
- int lambda)
-{
- using namespace mln;
-
- min_tree_<I,N,Ic,Nc> run(f, nbh, ref, nbhc, lambda);
-
-
- mln_piter(I) p(f.domain());
- unsigned nnodes = 0;
- for_all(p)
- {
- if (run.is_node(p))
- ++nnodes;
- }
-
- colorize colors(nnodes);
- image2d<value::rgb8> tmp(ref.domain());
- data::fill(tmp, literal::black);
- image2d<value::rgb8> tmp2(ref.domain());
- data::fill(tmp, ref);
-
- mln_piter(I) q(f.domain());
- unsigned int i = 0;
- for_all(q)
- {
- if (run.is_node(q))
- {
- tmp(q) = run.color(q);
- tmp2(q) = colors(i);
- i++;
- }
- }
-
- mln_piter(I) r(f.domain());
- for_all(r)
- {
- if (!run.is_node(r))
- {
- tmp(r) = tmp(run.find_representative(r));
- tmp2(r) = tmp2(run.find_representative(r));
- }
- }
-
- image2d<value::rgb8> to_display(tmp.domain());
- image2d<value::rgb8> to_display2(tmp2.domain());
-
- data::fill(to_display, literal::black);
- data::paste((tmp | is_edge), to_display);
- data::paste(morpho::dilation(to_display, c4()), to_display);
-
- data::fill(to_display2, literal::black);
- data::paste((tmp2 | is_edge), to_display2);
- data::paste(morpho::dilation(to_display2, c4()), to_display2);
-
-
- io::ppm::save(display_edge(tmp, literal::black, 3), "edge.ppm");
- io::ppm::save(tmp, "full.ppm");
- io::ppm::save(cells2image(to_display), "colorize.ppm");
-
- io::ppm::save(display_edge(tmp2, literal::black, 3), "edge2.ppm");
- io::ppm::save(cells2image(to_display2), "colorize2.ppm");
-
- return nnodes;
-}
-
-
-template <typename I>
-I
-do_it(I& input, int lambda, unsigned& nbasins)
-{
- using namespace mln;
-
- /// Graph creation
- I graph;
- create_graph(input, graph, value::rgb8(0, 0, 0));
-
- // Initialization
- image2d<value::int_u16> ima = convert_to_grey(graph);
-
- // Neigbhorhood
- // e2c
- bool e2c_h[] = { 0, 1, 0,
- 0, 0, 0,
- 0, 1, 0 };
- bool e2c_v[] = { 0, 0, 0,
- 1, 0, 1,
- 0, 0, 0 };
-
- mln_VAR(e2c, make::double_neighb2d(is_row_odd, e2c_h, e2c_v));
-
- bool e2e_h[] = { 0, 0, 1, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 0, 0, 1, 0, 0 };
-
- bool e2e_v[] = { 0, 0, 0, 0, 0,
- 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 1,
- 0, 1, 0, 1, 0,
- 0, 0, 0, 0, 0 };
- mln_VAR(e2e, make::double_neighb2d(is_row_odd, e2e_h, e2e_v));
-
- // Algorithm
- distance(extend((graph | is_edge).rw(), pw::value(graph)), e2c, ima);
-
- io::pgm::save(ima, "edge.pgm");
-
- nbasins = min_tree((ima | is_edge), e2e, graph, e2c, lambda);
-
- return graph;
-}
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.pgm lambda" << std::endl;
- std::cerr << " lambda >= 0" << std::endl;
- abort();
-}
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
-
- if (argc != 3)
- usage(argv);
-
- int lambda = atoi(argv[2]);
- if (lambda < 0)
- usage(argv);
-
- image2d<value::rgb8> ima;
- io::ppm::load(ima, argv[1]);
-
- unsigned nbasins;
- image2d<value::rgb8> output = do_it(ima, lambda, nbasins);
-
- //io::ppm::save(output, argv[3]);
-}
Index: ballas/color/laplacien.cc
--- ballas/color/laplacien.cc (revision 3184)
+++ ballas/color/laplacien.cc (working copy)
@@ -1,130 +0,0 @@
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/image_if.hh>
-
-# include <mln/core/alias/neighb2d.hh>
-# include <mln/make/double_neighb2d.hh>
-
-#include <mln/value/rgb8.hh>
-#include <mln/value/int_u16.hh>
-#include <mln/value/int_s16.hh>
-
-#include <mln/linear/gaussian.hh>
-#include <mln/morpho/erosion.hh>
-
-#include <mln/core/var.hh>
-#include <mln/debug/println.hh>
-#include <mln/opt/at.hh>
-
-#include "src/io.hh"
-#include "src/graph.hh"
-#include "src/convert.hh"
-
-
-void usage(char* argv[])
-{
- std::cerr << "usage: " << argv[0] << " input.ppm output.pgm" << std::endl;
- abort();
-}
-
-/// FIXME Put these elsewhere
-typedef mln::image2d<mln::value::rgb8> Icolor;
-typedef mln::image2d<mln::value::int_u16> Igray;
-
-void process(Icolor& graph, const Icolor& input)
-{
- using namespace mln;
-
- // Neighborhood definition
-
-// bool e2c_h[] = { 0, 1, 0,
-// 0, 0, 0,
-// 0, 1, 0 };
-// bool e2c_v[] = { 0, 0, 0,
-// 1, 0, 1,
-// 0, 0, 0 };
-
-// bool e2e_h[] = { 0, 0, 1, 0, 0,
-// 0, 1, 0, 1, 0,
-// 0, 0, 0, 0, 0,
-// 0, 1, 0, 1, 0,
-// 0, 0, 1, 0, 0 };
-// bool e2e_v[] = { 0, 0, 0, 0, 0,
-// 0, 1, 0, 1, 0,
-// 1, 0, 0, 0, 1,
-// 0, 1, 0, 1, 0,
-// 0, 0, 0, 0, 0 };
-
-// bool e2p_h[] = { 0, 0, 1,
-// 0, 0, 0,
-// 1, 0, 0 };
-// bool e2p_v[] = { 1, 0, 0,
-// 0, 0, 0,
-// 0, 0, 1 };
- //mln_VAR(e2c, make::double_neighb2d(is_row_odd, e2c_h, e2c_v));
-
-
- // convert the image into grey level
- Igray gray_graph(graph.bbox());
- convert_to_gl(gray_graph, graph);
-
- Igray gray_input(input.bbox());
- convert_to_gl(gray_input, input);
-
-
- //data::paste(morpho::dilation((gray_graph | is_cell), e2c.win()), gray_graph);
-// Igray save(gray_graph.bbox());
-// data::paste(gray_graph | is_cell, save);
-// IO::save(save, "tmp3.ppm");
-
- // Create the laplacian image
- //Igray laplacian(gray_input.bbox());
- image2d<int> laplacian(gray_input.bbox());
- linear::gaussian(gray_input, 2.0f, laplacian);
- //IO::save(laplacian, "tmp1.ppm");
- linear::laplacian(gray_input, 2.0f, laplacian);
- debug::println(laplacian);
- //IO::save(laplacian, "tmp2.ppm");
-
- // Display edge on the output images
-// debug::println(laplacian);
-
-// mln_piter_(Igray) p(laplacian.domain());
-// for_all(p)
-// if (laplacian(p) == 0u)
-// {
-// std::cout << "I'm here" << std::endl;
-// opt::at(graph, p.row() * 2, p.col() * 2) = value::rgb<8>(255, 0, 0);
-// }
-
-}
-
-
-
-int main(int argc, char* argv[])
-{
- using namespace mln;
-
- // Initialisation
- if (argc != 3)
- usage(argv);
-
- std::string input_file(argv[1]);
- std::string output_file(argv[2]);
-
-
- Icolor input;
-
- // Load the image
- IO::load(input, input_file);
-
- // create a graph image from the input
- Icolor graph;
- create_graph(input, graph);
-
- // Process
- process(graph, input);
-
-
- // Save
- IO::save(graph, output_file);
-}
Index: ballas/color/README
--- ballas/color/README (revision 3184)
+++ ballas/color/README (working copy)
@@ -1,83 +0,0 @@
--*- outline -*-
-
-* Fichiers sources:
-
-Les fichiers sources se trouvent dans milena/sandbox/ballas/color/.
-
-** Les méthodes de références:
-
-*** reference.cc:
- Utilisation de la seconde dérivée de gaussienne.
- Les passages par 0 sont mis en rouges.
-
-*** reference2.cc:
- Utilisation d'un gradient puis d'un filtre de clôture de volumes.
-
- Variante testée (non retenue):
- - un filtre de clôture d'aires.
-
-** min_tree:
-
-Les approches développées avec le min tree essayent de prendre en compte
-la couleur de l'image initial.
-
-Ici, on "expand" l'image pour pouvoir stocker les points et les edges directement
-sur l'image. Puis sur chaque edge, on stocke la distance séparant les deux
-pixels voisins cet edge. On construit ensuite un min tree sur ces edges.
-Ce min tree est ensuite filtrer afin d'éviter la sur-segmentation
-
-
-*** min_tree_area.cc:
- Dans cette version, un filtre d'aire est appliqué aux edges constituant
-le min tree. Si l'aire des edges d'une région du min tree est inférieure à un
-lambda donné, on fusionne la région avec sa région supérieure.
-
-*** min_tree_volume.cc
- Dans cette version, un filtre de volume est appliqué aux edges constituant
-le min tree.
-
-*** min_tree_color.cc
- Dans cette version, on filtre en fonction de la couleur moyenne.
-Si la distance entre la couleur moyenne constituant 2 régions est inférieure
-à un lambda donné, on fusionne les régions.
-
-
-* Organisation des répertoires:
-
-Les images de tests se trouve dans le répertoire ~ballas/pub/result/
-
-Chaque sous-répertoire contient des tests sur une image en particulier
-Cette image est stockée dans le répertoire sous le nom input.ppm.
-
-Chaque sous-répertoire contiennent des répertoires avec les résultats
-en fonction des méthodes utilisées:
-- ref1 contient les résultats de la méthode reference.cc
-- ref2 contient les résultats de la méthode reference2.cc
-- area contient les résultats de la méthode min_tree_area.cc
-- volume contient les résultats de la méthode min_tree_volume.cc
-- color contient les résultats de la méthode min_tree_color.cc
-
-Les résultats sont organisés de la manière suivante dans les répertoires
-area, volume et color.
-** edge.pgm:
- Image affichant les edges calculés avant le passage de min tree.
- Ces edges contiennent la distance entre les deux pixels voisins.
- Les pixels sont noir par défaut dans cette image.
-** edge.ppm:
- Image affichant les edges calcules après l'application du filtre sur le
- min tree.
- Ces edges contiennent la distance entre les deux pixels voisins.
- Les pixels sont noir par défaut dans cette image.
-** full.ppm:
- Superposition de l'image edge.ppm et de l'image de départ.
-** colorize.ppm:
- Image contenant les pixels coloriés à partir des edges de l'image.
- On utilise une dilatation pour colorier les pixels, ce qui altère la
- forme des lettres.
-
-Les résultats sont organisés de la manière suivante dans les répertoires
-ref1 et ref2.
-** lambda_x.ppm:
- x est le lambda utilisé pour le filtre.
- Dans ref1, nous avons une image avec les contours, alors que dans ref2,
- nous une image découpée en zones.
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Alexandre Abraham <abraham(a)lrde.epita.fr>
Fix coeff.
* nature/nature.cc: Fix coeff.
nature.cc | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
Index: nature/nature.cc
--- nature/nature.cc (revision 3183)
+++ nature/nature.cc (working copy)
@@ -191,17 +191,17 @@
score[PHOTO] += 100 - max;
score[TEXT] += max * 2;
- score[SCREENSHOT] += 50 + max / 2;
+ score[SCREENSHOT] += 80 + max / 2;
score[DRAWING] += 50 + max / 2;
std::cout << "Test 2 : co-occurence matrix diag_max[" << max << "]" << std::endl
<< "Photo : +" << 100 - max << std::endl;
- std::cout << "Screenshot : +" << 50 + max / 2 << std::endl;
+ std::cout << "Screenshot : +" << 80 + max / 2 << std::endl;
std::cout << "Text : +" << max * 2 << std::endl;
- std::cout << "Drawing : +" << 50 + max / 2 << std::endl << std::endl;
+ std::cout << "Drawing : +" << 80 + max / 2 << std::endl << std::endl;
@@ -385,15 +385,15 @@
cpt = 50;
score[PHOTO] += 50 - cpt;
- score[SCREENSHOT] += cpt * 5;
- score[TEXT] += 50 + cpt * max / 10;
- score[DRAWING] += 2 * (50 - cpt);
+ score[SCREENSHOT] += cpt * 8;
+ score[TEXT] += 50 + cpt * max / 3;
+ score[DRAWING] += 2 * (60 - cpt);
std::cout << "Test 3 : rectangle detection[" << cpt << "]" << std::endl
<< "Photo : +" << 50 - cpt << std::endl
<< "Screenshot : +" << cpt * 8 << std::endl
- << "Text : +" << 50 + cpt * max / 10 << std::endl
- << "Drawing : +" << 2 * (50 - cpt) << std::endl << std::endl;
+ << "Text : +" << 50 + cpt * max / 3 << std::endl
+ << "Drawing : +" << 2 * (60 - cpt) << std::endl << std::endl;
// Last but not least : text detection thanks to FFT
@@ -464,15 +464,15 @@
dist = dist / (log(fftb.nelements()) / log(10));
score[PHOTO] += dist * 25;
- score[SCREENSHOT] += dist * 25;
- score[TEXT] += (1 + cos(arg)) * (4 - dist) * 25;
- score[DRAWING] += dist * 25;
+ score[SCREENSHOT] += dist * 50;
+ score[TEXT] += (1 + abs(cos(arg))) * (4 - dist) * 40;
+ score[DRAWING] += dist * 50;
std::cout << "Test 4 : Fourier distance[" << dist << "]" << std::endl
<< "Photo : +" << dist * 25 << std::endl
- << "Screenshot : +" << dist * 25 << std::endl
- << "Text : +" << (1 + cos(arg)) * (4 - dist) * 25 << std::endl
- << "Drawing : +" << dist * 25 << std::endl << std::endl;
+ << "Screenshot : +" << dist * 50 << std::endl
+ << "Text : +" << (1 + abs(cos(arg))) * (4 - dist) * 40 << std::endl
+ << "Drawing : +" << dist * 50 << std::endl << std::endl;
// io::pbm::save(binarization::threshold(fft, max * 4 / 10), name.append("_fft.pbm"));
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Alexandre Abraham <abraham(a)lrde.epita.fr>
Fix call to 'at'.
* abraham/mln/transform/fft.hh: Add forgotten opt:: before at.
fft.hh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: abraham/mln/transform/fft.hh
--- abraham/mln/transform/fft.hh (revision 3182)
+++ abraham/mln/transform/fft.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -442,7 +442,7 @@
}
for (unsigned row = 0; row < this->trans_im.nrows(); ++row)
for (unsigned col = this->trans_im.ncols() - 1; col > this->trans_im.ncols() / 2; --col)
- at(this->trans_im, row, col) = opt::at(this->trans_im, this->trans_im.nrows() - row - 1,
+ opt::at(this->trans_im, row, col) = opt::at(this->trans_im, this->trans_im.nrows() - row - 1,
this->trans_im.ncols() - col - 1);
return this->trans_im;
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Alexandre Abraham <abraham(a)lrde.epita.fr>
Fix some constants.
* nature/nature.cc: Fix constants.
* nature/hsi.cc: New.
* nature/hom.cc: .
hom.cc | 246 ++------------------------------------------------------------
hsi.cc | 80 ++++++++++++++++++++
nature.cc | 26 +++---
3 files changed, 101 insertions(+), 251 deletions(-)
Index: nature/nature.cc
--- nature/nature.cc (revision 3181)
+++ nature/nature.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -27,7 +27,7 @@
#include <mln/core/image/image2d.hh>
#include <mln/core/image/cast_image.hh>
-#include <mln/core/image/thru.hh>
+#include <mln/core/image/fun_image.hh>
#include <mln/core/alias/neighb2d.hh>
#include <mln/io/ppm/load.hh>
@@ -80,7 +80,7 @@
};
template <typename T>
-unsigned nb_peaks (histo::data<T> &h)
+unsigned nb_peaks (histo::array<T> &h)
{
// First, we compute the maximum, ignoring the first column because it
// contains nonsense points
@@ -126,17 +126,17 @@
image2d<hsi_f> hsi = level::transform(input, fun::v2v::f_rgb_to_hsi_f);
- thru<mln::meta::hue<hsi_f>, image2d<hsi_f> > hue(hsi);
- thru<mln::meta::sat<hsi_f>, image2d<hsi_f> > sat(hsi);
- thru<mln::meta::inty<hsi_f>, image2d<hsi_f> > inty(hsi);
-
- cast_image_<float01_8, thru<mln::meta::hue<hsi_f>, image2d<hsi_f> > > qhue(hue); // quantified hue
- cast_image_<float01_8, thru<mln::meta::sat<hsi_f>, image2d<hsi_f> > > qsat(sat); // quantified sat
- cast_image_<float01_8, thru<mln::meta::inty<hsi_f>, image2d<hsi_f> > > qinty(inty); // quantified inty
-
- histo::data<float01_8> hhue = histo::compute(qhue);
- histo::data<float01_8> hsat = histo::compute(qsat);
- histo::data<float01_8> hinty = histo::compute(qinty);
+ fun_image<mln::meta::hue<hsi_f>, image2d<hsi_f> > hue(hsi);
+ fun_image<mln::meta::sat<hsi_f>, image2d<hsi_f> > sat(hsi);
+ fun_image<mln::meta::inty<hsi_f>, image2d<hsi_f> > inty(hsi);
+
+ cast_image_<float01_8, fun_image<mln::meta::hue<hsi_f>, image2d<hsi_f> > > qhue(hue); // quantified hue
+ cast_image_<float01_8, fun_image<mln::meta::sat<hsi_f>, image2d<hsi_f> > > qsat(sat); // quantified sat
+ cast_image_<float01_8, fun_image<mln::meta::inty<hsi_f>, image2d<hsi_f> > > qinty(inty); // quantified inty
+
+ histo::array<float01_8> hhue = histo::compute(qhue);
+ histo::array<float01_8> hsat = histo::compute(qsat);
+ histo::array<float01_8> hinty = histo::compute(qinty);
// Compute the number of peaks in the histogram to give a first intuition
@@ -465,7 +465,7 @@
score[PHOTO] += dist * 25;
score[SCREENSHOT] += dist * 25;
- score[TEXT] += (1 + cos(arg)) * 2 * (4 - dist) * 50;
+ score[TEXT] += (1 + cos(arg)) * (4 - dist) * 25;
score[DRAWING] += dist * 25;
std::cout << "Test 4 : Fourier distance[" << dist << "]" << std::endl
Index: nature/hsi.cc
--- nature/hsi.cc (revision 0)
+++ nature/hsi.cc (revision 0)
@@ -0,0 +1,80 @@
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#include <iterator>
+#include <string>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/fun_image.hh>
+#include <mln/core/alias/window2d.hh>
+#include <mln/win/all.hh>
+
+#include <mln/value/rgb8.hh>
+#include <mln/value/hsi.hh>
+
+#include <mln/fun/v2v/rgb_to_hsi.hh>
+#include <mln/fun/meta/inty.hh>
+
+#include <mln/level/compare.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/morpho/erosion.hh>
+
+#include <mln/accu/histo.hh>
+#include <mln/histo/compute.hh>
+#include <mln/level/transform.hh>
+#include <mln/data/paste.hh>
+
+using namespace mln;
+using namespace value;
+
+int main (int argc, const char* argv [])
+{
+ if (argc < 2) {
+ std::cerr << "usage: " << argv[0] << " in.ppm [other_files.ppm]" << std::endl;
+ return 1;
+ }
+
+ for (int i = 1; i < argc; ++i)
+ {
+ image2d<rgb8> input;
+ io::ppm::load(input, argv[i]);
+
+ image2d<hsi_f> hsi = level::transform(input, fun::v2v::f_rgb_to_hsi_f);
+ fun_image<mln::meta::inty<hsi_f>, image2d<hsi_f> > l(hsi);
+
+ win::rectangle2d rect(7,7);
+
+ std::string name = argv[i];
+ name.erase(name.length() - 4);
+ data::paste(morpho::erosion(l, rect), l);
+ input = level::transform(hsi, fun::v2v::f_hsi_to_rgb_3x8);
+ io::ppm::save(input, name.append("_tst.ppm"));
+ }
+}
Index: nature/hom.cc
--- nature/hom.cc (revision 3181)
+++ nature/hom.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -45,8 +45,7 @@
#include <mln/morpho/dilation.hh>
#include <mln/morpho/opening.hh>
-#include <mln/win/hline2d.hh>
-#include <mln/win/vline2d.hh>
+#include <mln/win/all.hh>
int main(int argc, const char * argv[])
{
@@ -70,245 +69,16 @@
// Compute the mean
int_t mean = estim::mean(ima);
+ image2d<bool> imab = binarization::threshold(ima, mean-10);
- image2d<bool> imab = binarization::threshold(ima, 10);
-
-
-
- window2d winout;
- window2d winin;
-
-// static const bool matout [] = {0, 0, 0, 0, 0, 0, 0,
-// 0, 0, 1, 0, 0, 0, 0,
-// 0, 0, 1, 0, 0, 0, 0,
-// 0, 0, 1, 0, 0, 0, 0,
-// 0, 0, 1, 1, 1, 1, 0,
-// 0, 0, 0, 0, 0, 0, 0,
-// 0, 0, 0, 0, 0, 0, 0};
-
- static const bool blmatout [] = {0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0};
-
-// static const bool blmatout [] = {0, 0, 0,
-// 1, 0, 0,
-// 1, 1, 0};
-
-
- convert::from_to(blmatout, winout);
-
-// static const bool matin [] = {0, 0, 0, 1, 0, 0, 0,
-// 0, 0, 0, 1, 0, 0, 0,
-// 0, 0, 0, 1, 0, 0, 0,
-// 0, 0, 0, 1, 1, 1, 1,
-// 0, 0, 0, 0, 0, 0, 0,
-// 0, 0, 0, 0, 0, 0, 0,
-// 0, 0, 0, 0, 0, 0, 0};
-
- static const bool blmatin [] = {0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 1, 1,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
-// static const bool blmatin [] = {0, 1, 0,
-// 0, 1, 1,
-// 0, 0, 0};
-
- convert::from_to(blmatin, winin);
- image2d<bool> bottom_left = morpho::hit_or_miss(imab, winout, winin);
-
-
-// static const bool brmatout [] = {0, 0, 0,
-// 0, 0, 1,
-// 0, 1, 1};
-
-// static const bool brmatin [] = {0, 1, 0,
-// 1, 1, 0,
-// 0, 0, 0};
-
- static const bool brmatout [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0};
-
- static const bool brmatin [] = {0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 1, 1, 1, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
-
- convert::from_to(brmatout, winout);
- convert::from_to(brmatin, winin);
- image2d<bool> bottom_right = morpho::hit_or_miss(imab, winout, winin);
-
-// static const bool urmatout [] = {0, 1, 1,
-// 0, 0, 1,
-// 0, 0, 0};
-
-// static const bool urmatin [] = {0, 0, 0,
-// 1, 1, 0,
-// 0, 1, 0};
-
- static const bool urmatout [] = {0, 0, 0, 0, 0,
- 0, 1, 1, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0};
-
- static const bool urmatin [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 1, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0};
-
-
- convert::from_to(urmatout, winout);
- convert::from_to(urmatin, winin);
- image2d<bool> up_right = morpho::hit_or_miss(imab, winout, winin);
-
-
-// static const bool ulmatout [] = {1, 1, 0,
-// 1, 0, 0,
-// 0, 0, 0};
-
-// static const bool ulmatin [] = {0, 0, 0,
-// 0, 1, 1,
-// 0, 1, 0};
-
- static const bool ulmatout [] = {0, 0, 0, 0, 0,
- 0, 1, 1, 1, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
- static const bool ulmatin [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 1,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0};
-
-
- convert::from_to(ulmatout, winout);
- convert::from_to(ulmatin, winin);
- image2d<bool> up_left = morpho::hit_or_miss(imab, winout, winin);
-
-
- static const bool umatout [] = {0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
- static const bool umatin [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
-
- convert::from_to(umatout, winout);
- convert::from_to(umatin, winin);
- image2d<bool> up = morpho::hit_or_miss(imab, winout, winin);
-
-
- static const bool bmatout [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0};
-
- static const bool bmatin [] = {0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0};
-
-
- convert::from_to(bmatout, winout);
- convert::from_to(bmatin, winin);
- image2d<bool> bottom = morpho::hit_or_miss(imab, winout, winin);
-
-
- static const bool lmatout [] = {0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 1, 0, 0, 0};
-
- static const bool lmatin [] = {0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0};
-
-
- convert::from_to(lmatout, winout);
- convert::from_to(lmatin, winin);
- image2d<bool> left = morpho::hit_or_miss(imab, winout, winin);
-
-
- static const bool rmatout [] = {0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0,
- 0, 0, 0, 1, 0};
-
- static const bool rmatin [] = {0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 0};
-
-
- convert::from_to(rmatout, winout);
- convert::from_to(rmatin, winin);
- image2d<bool> right = morpho::hit_or_miss(imab, winout, winin);
-
+ io::pbm::save(imab, "hop.pbm");
+ window2d out = win::disk2d(25) - win::disk2d(22);
+ win::disk2d in(4);
std::string name(argv[i]);
name.erase(name.length() - 4);
- io::pbm::save( imab, name.append("_bin.pbm"));
-
- name = argv[i];
- name.erase(name.length() - 4);
- // image2d<bool> final(right.domain());
- // data::fill(final, false);
- // mln_piter_(image2d<bool>) p(final.domain());
- // for_all(p)
- // final(p) = up_left(p) || up_right(p) || bottom_right(p) || bottom_left(p) || up(p) || bottom(p) || left(p) || right(p);
-
- image2d<bool> inter (up_left + up_right + bottom_right + bottom_left + up + bottom + left + right);
-
- static const bool vert [] = {0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0};
-
- static const bool hori [] = {0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0};
-
- convert::from_to(vert, winin);
- convert::from_to(hori, winout);
-
- image2d<bool> final = morpho::opening(inter, win::hline2d(20));
- final += morpho::opening(inter, win::vline2d(20));
-
- io::pbm::save( final,
- name.append("_hom.pbm"));
+ io::pbm::save(morpho::hit_or_miss(imab, in, out), name.append("_hom.pbm"));
}
}
1
0
* laurent/ismm2009.cc: Use the implementation written by Alexandre
Abraham for one of its previous seminar (#0821).
---
milena/sandbox/ChangeLog | 7 +
milena/sandbox/laurent/ismm2009.cc | 282 ++++++++++++++++++------------------
2 files changed, 151 insertions(+), 138 deletions(-)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 7fd1cbf..ccd1ffd 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,10 @@
+2009-01-21 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add a new LCA implementation to Laurent's code.
+
+ * laurent/ismm2009.cc: Use the implementation written by Alexandre
+ Abraham for one of its previous seminar (#0821).
+
2009-01-21 Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Update INIM.
diff --git a/milena/sandbox/laurent/ismm2009.cc b/milena/sandbox/laurent/ismm2009.cc
index eed5f65..c3250d1 100644
--- a/milena/sandbox/laurent/ismm2009.cc
+++ b/milena/sandbox/laurent/ismm2009.cc
@@ -22,13 +22,13 @@
#include <mln/util/timer.hh>
#include <mln/util/fibonacci_heap.hh>
-
+#include <stack>
/*
TO-DO list:
- handling adjacency on the fly (instead of having an image)
- */
+*/
namespace mln
@@ -109,23 +109,23 @@ namespace mln
typedef mln_element(Q) E;
while (! q.is_empty())
- {
- E e = q.pop_front();
-
- L l1 = wst(p1_from_e(e)),
- l2 = wst(p2_from_e(e));
- mln_invariant(l1 != l2);
- L l1r = find_root_l(lpar, l1),
- l2r = find_root_l(lpar, l2);
-
- mln_invariant(l1r == lr || l2r == lr);
-
- if (l1r == l2r)
- // 'e' is an internal edge => forget it.
- continue;
+ {
+ E e = q.pop_front();
- return e;
- }
+ L l1 = wst(p1_from_e(e)),
+ l2 = wst(p2_from_e(e));
+ mln_invariant(l1 != l2);
+ L l1r = find_root_l(lpar, l1),
+ l2r = find_root_l(lpar, l2);
+
+ mln_invariant(l1r == lr || l2r == lr);
+
+ if (l1r == l2r)
+ // 'e' is an internal edge => forget it.
+ continue;
+
+ return e;
+ }
mln_invariant(0); // We should not be here!
@@ -133,160 +133,168 @@ namespace mln
}
- // Compute an LCA; reference(?) code.
-
- template <typename L, typename E, typename Epar>
- std::vector< std::vector<E> >
- compute_lca(const L& l_max,
- const std::vector<E>& edge,
- const Epar& epar)
+ /// Compute an LCA
+ /// Reference article: The LCA Problem Revisited, M. A. Bender and M.
+ /// Farach-Colton, May 2000
+ ///
+ /// See also Topological Watershed, Alexandre Abraham, LRDE CSI report
+ /// 0821, June 2008
+ template <typename L, typename I, typename E>
+ class lca_t
{
- std::cout << "LCA computing...";
- std::cout.flush();
- mln_ch_value(Epar, std::vector<L>) chl; // Children (known as array).
- initialize(chl, epar);
-
- unsigned size = l_max.next();
+ public:
- std::vector< std::vector<E> > lca(size);
- for (L l = 1; l <= l_max; ++l)
+ /// Constructor
+ lca_t(const L& l_max_,
+ const I& edge_children,
+ const std::vector<E>& roots)
+ {
+ unsigned l_max = l_max_.next();
+ euler_tour_edge_.resize(2 * l_max + 1);
+ euler_tour_depth_.resize(2 * l_max + 1);
+ initialize (euler_position_, edge_children);
+
+ // BUILD EULER TOUR
+ std::stack<E> to_treat;
+ for (unsigned i = 0; i < roots.size(); ++i)
+ to_treat.push(roots[i]);
+
+ unsigned euler_edge = 0;
+ mln_ch_value(I, bool) deja_vu;
+ initialize(deja_vu, edge_children);
+ data::fill(deja_vu, false);
+
+ while (!to_treat.empty())
{
- lca[l].resize(size);
- lca[l][l] = edge[l]; // Diagonal => itself.
- }
- std::vector<bool> deja_vu(size);
+ E e = to_treat.top();
+ to_treat.pop();
- E e;
+ euler_tour_edge_[euler_edge] = e;
+ if (deja_vu(e))
+ euler_tour_depth_[euler_edge] = euler_tour_depth_[euler_edge - 1] - 1;
+ else
+ euler_tour_depth_[euler_edge] = euler_tour_depth_[euler_edge - 1] + 1;
- // The 1st label (l = 1) is a special case since
- // we cannot have lca[1][i] with i < 1!
- {
- e = edge[1];
- do
+ if (!deja_vu(e))
{
- chl(e).push_back(1);
- e = epar(e);
+ for (int j = edge_children(e).size() - 1; j >= 0; --j)
+ {
+ to_treat.push(e);
+ to_treat.push(edge_children(e)[j]);
+ }
+ deja_vu(e) = true;
+ euler_position_(e) = euler_edge;
}
- while (e != epar(e));
- chl(e).push_back(1);
- }
+ ++euler_edge;
+ }
- for (L l = 2; l <= l_max; ++l)
- {
- std::fill(deja_vu.begin(), deja_vu.end(), false);
- e = edge[l];
- for (;;)
- {
- std::vector<L>& chl_e = chl(e);
- unsigned n = chl_e.size();
+ // BUILD MINIMAS
+ int size = 2 * l_max - 1;
+ int logn = (int)(ceil(log((double)(size))/log(2.0)));
- // Compute lca[l_][l] with l_ = 1..l-1
- for (unsigned i = 0; i < n; ++i)
- {
- if (deja_vu[chl_e[i]])
- continue;
- L l_ = chl_e[i];
- mln_invariant(l_ < l);
- lca[l_][l] = e;
- deja_vu[l_] = true;
- }
+ minim_ = new int [logn * size]; // FIXME : Think about freeing this
+ Minim_ = new int* [logn];
- // Update 'chl' with l;
- chl(e).push_back(l);
+ Minim_[0] = minim_;
+
+ // Init
+ for (unsigned i = 0; i < size - 1; ++i)
+ if (euler_tour_depth_[i] < euler_tour_depth_[i+1])
+ {
+ Minim_[0][i] = i;
+ } else {
+ Minim_[0][i] = i+1;
+ }
- if (e == epar(e)) // Root so stop.
- break;
- e = epar(e); // Otherwise go to parent.
+ int k;
+ for (int j = 1; j < logn; j++)
+ {
+ k = 1 << (j - 1);
+ Minim_[j] = &minim_[j * size];
+ for (int i = 0; i < size; i++)
+ {
+ if ((i + (k << 1)) < size)
+ {
+ if (euler_tour_depth_[Minim_[j - 1][i]] <= euler_tour_depth_[Minim_[j - 1][i + k]])
+ Minim_[j][i] = Minim_[j - 1][i];
+ else
+ Minim_[j][i] = Minim_[j - 1][i + k];
}
+ }
}
+ }
- // e is the root node; we have processed all labels
- // so they are stored as the children of e:
- mln_invariant(chl(e).size() == l_max); // All labels are children.
-
-
-// // Save the LCA into a file.
-// {
-// std::ofstream out("lca.txt");
-
-// for (L l = 1; l <= l_max; ++l)
-// {
-// out << "l = " << l << ": ";
-// for (L l2 = l; l2 <= l_max; ++l2)
-// {
-// out << lca[l][l2] << ' ';
-// }
-// out << std::endl;
-// }
-// out.close();
+ /// Destructor
+ ~lca_t()
+ {
+ delete[] Minim_;
+ delete[] minim_;
+ }
-// // Display children tree.
-// {
-// std::cout << "chl tree: " << std::endl;
-// for (L l = 1; l <= l_max; ++l)
-// {
-// E e_ = edge[l];
-// std::cout << "l = " << l << " => ";
-// do
-// {
-// std::cout << e_ << " : ";
-// for (unsigned i = 0; i < chl(e_).size(); ++i)
-// std::cout << chl(e_)[i] << ' ';
-// std::cout << " -> ";
-// e_ = epar(e_);
-// }
-// while (epar(e_) != e_);
-// std::cout << e_ << " : ";
-// for (unsigned i = 0; i < chl(e_).size(); ++i)
-// std::cout << chl(e_)[i] << ' ';
-// std::cout << std::endl;
-// }
-// }
+ const E& operator() (const E& a, const E& b)
+ {
+ if (a == b)
+ return a;
+ int m = euler_position_(a),
+ n = euler_position_(b),
+ k;
- std::cout << "done!" << std::endl;
+ if (m > n)
+ std::swap(m, n);
- return lca;
- }
+ k = (int)(log((double)(n - m))/log(2.));
+ if (euler_tour_depth_[Minim_[k][m]]
+ < euler_tour_depth_[Minim_[k][n - (1 << k)]])
+ return euler_tour_edge_[Minim_[k][m]];
+ else
+ return euler_tour_edge_[Minim_[k][n - (1 << k)]];
+ }
+ private:
+ int *minim_;
+ int **Minim_;
+ std::vector<E> euler_tour_edge_;
+ std::vector<unsigned> euler_tour_depth_;
+ mln_ch_value(I, unsigned) euler_position_;
+ };
+ // Transform attributes so that they are all different!
- // Transform attributes so that they are all different!
-
template <typename A, typename L>
void
make_unique_attribute(util::array<A>& a,
- std::vector< std::pair<A,L> >& v,
- L l_max,
- bool echo)
+ std::vector< std::pair<A,L> >& v,
+ L l_max,
+ bool echo)
{
// Display attributes.
if (echo)
- {
- std::cout << "(attribute, label) = { ";
- for (unsigned i = 1; i <= l_max; ++i)
- std::cout << '(' << v[i].first // Attribute (increasing).
- << ','
- << v[i].second // Region label.
- << ") ";
- std::cout << '}' << std::endl
- << std::endl;
- }
+ {
+ std::cout << "(attribute, label) = { ";
+ for (unsigned i = 1; i <= l_max; ++i)
+ std::cout << '(' << v[i].first // Attribute (increasing).
+ << ','
+ << v[i].second // Region label.
+ << ") ";
+ std::cout << '}' << std::endl
+ << std::endl;
+ }
std::map<A,A> lut; // old value -> new value
for (unsigned l = 1; l <= l_max; ++l)
- {
- A old_a = v[l].first,
- new_a = old_a + l - 1;
- lut[old_a] = new_a;
- v[l].first = new_a; // new value
- }
+ {
+ A old_a = v[l].first,
+ new_a = old_a + l - 1;
+ lut[old_a] = new_a;
+ v[l].first = new_a; // new value
+ }
for (unsigned l = 1; l <= l_max; ++l)
a[l] = lut[ a[l] ];
}
@@ -967,9 +975,7 @@ int main(int argc, char* argv[])
{
// First, processing the 1D-faces (edges) of the watershed line.
- std::vector< std::vector<E> > lca;
-
- lca = compute_lca(n_basins, edge, epar); // lca is auxiliary data.
+ lca_t<L,chl_t,E> lca(n_basins, chl, roots);
mln_piter_(g_line_t) e(g_line.domain());
for_all(e)
@@ -977,7 +983,7 @@ int main(int argc, char* argv[])
L l1 = adj_line(e).first(),
l2 = adj_line(e).second();
mln_invariant(l1 != 0 && l2 > l1);
- E e_ = lca[l1][l2];
+ E e_ = lca(edge[l1],edge[l2]);
mln_invariant(is_line(e_));
mln_invariant(aa(e_) != 0); // aa is valid at e_.
--
1.5.6.5
1
0
21 Jan '09
* headers.mk: remove to_rgb.hh from distribution.
* mln/convert/all.hh: remove to_rgb.hh.
* mln/convert/from_to.hxx: add more predeclarations.
* mln/convert/impl/from_value_to_value.hh: if no value concept is
caught in the dispatch, try to call a from_to_ overload.
* mln/fun/v2v/rgb_to_hsl.hh: add new global variables of function
converting rgb16 to hsl.
* mln/value/hsl.hh,
* mln/value/rgb.hh: add new from_to_ overloads.
* tests/convert/Makefile.am,
* tests/convert/to_hsl.cc,
* tests/convert/to_rgb.cc: new tests. Test conversions with rgb<n> and
hsl<h,s,l> using from_to.
* mln/convert/to_rgb.hh: remove. Useless since conversions are now done
thanks to from_to.
* tests/unit_test/Makefile.am,
* tests/unit_test/mln_convert_to_rgb.cc: remove unit_test related to
to_rgb.hh.
* mln/fun/v2v/rgb_to_hsl.hh: do not include hsl.hh anymore.
---
milena/ChangeLog | 33 ++++
milena/headers.mk | 1 -
milena/mln/convert/all.hh | 5 +-
milena/mln/convert/from_to.hxx | 25 +++
milena/mln/convert/impl/from_value_to_value.hh | 27 ++-
milena/mln/fun/v2v/rgb_to_hsl.hh | 15 +-
milena/mln/value/hsl.hh | 195 +++++++++++++++++---
milena/mln/value/rgb.hh | 67 +++++++-
milena/tests/convert/Makefile.am | 4 +
.../convert/to_rgb.hh => tests/convert/to_hsl.cc} | 75 ++------
.../convert/all.hh => tests/convert/to_rgb.cc} | 43 ++---
milena/tests/unit_test/Makefile.am | 2 -
milena/tests/unit_test/mln_convert_to_rgb.cc | 11 -
13 files changed, 364 insertions(+), 139 deletions(-)
rename milena/{mln/convert/to_rgb.hh => tests/convert/to_hsl.cc} (54%)
copy milena/{mln/convert/all.hh => tests/convert/to_rgb.cc} (68%)
delete mode 100644 milena/tests/unit_test/mln_convert_to_rgb.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 3da59ee..6e30fb1 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,36 @@
+2009-01-20 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Handle rgb and hsl conversions in from_to and remove to_rgb.
+
+ * headers.mk: remove to_rgb.hh from distribution.
+
+ * mln/convert/all.hh: remove to_rgb.hh.
+
+ * mln/convert/from_to.hxx: add more predeclarations.
+
+ * mln/convert/impl/from_value_to_value.hh: if no value concept is
+ caught in the dispatch, try to call a from_to_ overload.
+
+ * mln/fun/v2v/rgb_to_hsl.hh: add new global variables of function
+ converting rgb16 to hsl.
+
+ * mln/value/hsl.hh,
+ * mln/value/rgb.hh: add new from_to_ overloads.
+
+ * tests/convert/Makefile.am,
+ * tests/convert/to_hsl.cc,
+ * tests/convert/to_rgb.cc: new tests. Test conversions with rgb<n> and
+ hsl<h,s,l> using from_to.
+
+ * mln/convert/to_rgb.hh: remove. Useless since conversions are now done
+ thanks to from_to.
+
+ * tests/unit_test/Makefile.am,
+ * tests/unit_test/mln_convert_to_rgb.cc: remove unit_test related to
+ to_rgb.hh.
+
+ * mln/fun/v2v/rgb_to_hsl.hh: do not include hsl.hh anymore.
+
2009-01-21 Nicolas Ballas <ballas(a)lrde.epita.fr>
Externalize element and nelement method in fastest images.
diff --git a/milena/headers.mk b/milena/headers.mk
index 04c0a73..5babdd4 100644
--- a/milena/headers.mk
+++ b/milena/headers.mk
@@ -271,7 +271,6 @@ mln/convert/impl/from_int_to_value.hh \
mln/convert/to_dpoint.hh \
mln/convert/to_p_array.hh \
mln/convert/from_to.hxx \
-mln/convert/to_rgb.hh \
mln/convert/essential.hh \
mln/value/shell.hh \
mln/value/float01_f.hh \
diff --git a/milena/mln/convert/all.hh b/milena/mln/convert/all.hh
index 0fab453..0336039 100644
--- a/milena/mln/convert/all.hh
+++ b/milena/mln/convert/all.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -49,7 +49,6 @@ namespace mln
# include <mln/convert/to_dpoint.hh>
# include <mln/convert/to_fun.hh>
# include <mln/convert/to_image.hh>
-# include <mln/convert/to_rgb.hh>
# include <mln/convert/to_p_array.hh>
# include <mln/convert/to_window.hh>
diff --git a/milena/mln/convert/from_to.hxx b/milena/mln/convert/from_to.hxx
index e2cbe3d..404a22f 100644
--- a/milena/mln/convert/from_to.hxx
+++ b/milena/mln/convert/from_to.hxx
@@ -82,6 +82,8 @@ namespace mln
namespace value {
template <unsigned n> struct rgb;
+ template <typename H, typename S, typename L> class hsl_;
+ template <unsigned n> struct int_u;
}
// end of Forward declarations.
@@ -149,6 +151,29 @@ namespace mln
void
from_to_(bool from, value::rgb<m>& to);
+ // int_u -> rgb.
+ template <unsigned m>
+ void from_to_(const value::int_u<m>& from, value::rgb<m>& to);
+
+ // hsl -> rgb8.
+ template <typename H, typename S, typename L>
+ void from_to_(const value::hsl_<H,S,L>&, value::rgb<8>& to);
+
+ // hsl -> rgb16.
+ template <typename H, typename S, typename L>
+ void from_to_(const value::hsl_<H,S,L>&, value::rgb<16>& to);
+
+
+ // rgb to hsl
+ template <typename H, typename S, typename L>
+ void
+ from_to_(const value::rgb<16>& from, value::hsl_<H,S,L>& to);
+
+ // rgb to hsl
+ template <typename H, typename S, typename L>
+ void
+ from_to_(const value::rgb<8>& from, value::hsl_<H,S,L>& to);
+
// C-array -> Image.
template <typename V, unsigned S, typename I>
diff --git a/milena/mln/convert/impl/from_value_to_value.hh b/milena/mln/convert/impl/from_value_to_value.hh
index 5879b7a..f5d69fd 100644
--- a/milena/mln/convert/impl/from_value_to_value.hh
+++ b/milena/mln/convert/impl/from_value_to_value.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,12 +29,12 @@
#ifndef MLN_CONVERT_IMPL_FROM_VALUE_TO_VALUE_HH
# define MLN_CONVERT_IMPL_FROM_VALUE_TO_VALUE_HH
-/*! \file mln/convert/from_to.hh
- *
- * \brief General conversion procedure from a value to a value.
- *
- * \todo Augment code + add checks.
- */
+/// \file mln/convert/from_to.hh
+///
+/// General conversion procedure from a value to a value.
+///
+/// \todo Augment code + add checks.
+
# include <utility>
# include <mln/core/concept/image.hh>
@@ -43,7 +44,7 @@
# include <mln/core/site_set/p_run.hh>
# include <mln/metal/converts_to.hh>
-
+# include <mln/convert/from_to.hxx>
namespace mln
{
@@ -88,6 +89,16 @@ namespace mln
exact(to) = exact(from).to_equiv();
}
+ template <typename V, typename W>
+ inline
+ void
+ from_value_to_value_(const Value<V>& from, Value<W>& to)
+ {
+ // No concept based conversion. Trying to find more specific
+ // conversion with other from_to overloads.
+ convert::over_load::from_to_(exact(from), exact(to));
+ }
+
// Facades.
diff --git a/milena/mln/fun/v2v/rgb_to_hsl.hh b/milena/mln/fun/v2v/rgb_to_hsl.hh
index a205544..3bfe060 100644
--- a/milena/mln/fun/v2v/rgb_to_hsl.hh
+++ b/milena/mln/fun/v2v/rgb_to_hsl.hh
@@ -30,17 +30,21 @@
#include <cmath>
-#include <mln/value/rgb8.hh>
#include <mln/math/round.hh>
#include <mln/math/max.hh>
#include <mln/math/min.hh>
-#include <mln/value/hsl.hh>
-
namespace mln
{
+ // Forward declaration
+ namespace value
+ {
+ template <unsigned n> struct rgb;
+ template <typename H, typename S, typename L> class hsl_;
+ typedef hsl_<float, float, float> hsl_f;
+ }
namespace fun
{
@@ -73,9 +77,11 @@ namespace mln
};
- typedef f_hsl_to_rgb_<value::rgb8> f_hsl_to_rgb_3x8_t;
+ typedef f_hsl_to_rgb_< value::rgb<8> > f_hsl_to_rgb_3x8_t;
+ typedef f_hsl_to_rgb_< value::rgb<16> > f_hsl_to_rgb_3x16_t;
extern f_hsl_to_rgb_3x8_t f_hsl_to_rgb_3x8;
+ extern f_hsl_to_rgb_3x16_t f_hsl_to_rgb_3x16;
# ifndef MLN_INCLUDE_ONLY
@@ -85,6 +91,7 @@ namespace mln
f_rgb_to_hsl_f_t f_rgb_to_hsl_f;
f_hsl_to_rgb_3x8_t f_hsl_to_rgb_3x8;
+ f_hsl_to_rgb_3x16_t f_hsl_to_rgb_3x16;
/// \}
diff --git a/milena/mln/value/hsl.hh b/milena/mln/value/hsl.hh
index 0a48c53..0ac4087 100644
--- a/milena/mln/value/hsl.hh
+++ b/milena/mln/value/hsl.hh
@@ -25,6 +25,15 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
+/// \file mln/value/hsl.hh
+///
+/// Color class.
+///
+/// \todo write a better doc.
+
+#ifndef MLN_VALUE_HSL_HH
+# define MLN_VALUE_HSL_HH
+
#include <mln/value/ops.hh>
#include <mln/value/concept/vectorial.hh>
@@ -33,13 +42,45 @@
#include <mln/value/float01_8.hh>
-#ifndef MLN_VALUE_HSL_HH
-# define MLN_VALUE_HSL_HH
+// Used in from_to
+#include <mln/fun/v2v/rgb_to_hsl.hh>
namespace mln
{
+ // Forward declarations.
+ namespace value
+ {
+
+ template <typename H, typename S, typename L>
+ class hsl_;
+
+ }
+
+
+
+ namespace convert
+ {
+
+ namespace over_load
+ {
+
+ // rgb to hsl
+ template <typename H, typename S, typename L>
+ void
+ from_to_(const value::rgb<16>& from, value::hsl_<H,S,L>& to);
+
+ // rgb to hsl
+ template <typename H, typename S, typename L>
+ void
+ from_to_(const value::rgb<8>& from, value::hsl_<H,S,L>& to);
+
+ } // end of namespace mln::convert::over_load
+
+ } // end of namespace mln::convert
+
+
namespace value
{
@@ -71,32 +112,14 @@ namespace mln
}
/// Read-only access to the hue component.
- const H& hue() const
- {
- return this->hue_;
- }
- const S& sat() const
- {
- return this->sat_;
- }
- const L& lum() const
- {
- return this->lum_;
- }
+ const H& hue() const;
+ const S& sat() const;
+ const L& lum() const;
/// Read-write access to the hue component.
- H& hue()
- {
- return this->hue_;
- }
- S& sat()
- {
- return this->sat_;
- }
- L& lum()
- {
- return this->lum_;
- }
+ H& hue();
+ S& sat();
+ L& lum();
private:
H hue_;
@@ -108,8 +131,128 @@ namespace mln
typedef hsl_<double, double, double> hsl_d;
+
+ /// Print an hsl \p c into the output stream \p ostr.
+ ///
+ /// \param[in,out] ostr An output stream.
+ /// \param[in] c An rgb.
+ ///
+ /// \return The modified output stream \p ostr.
+ template <typename H, typename S, typename L>
+ std::ostream& operator<<(std::ostream& ostr, const hsl_<H,S,L>& c);
+
+ } // end of namespace mln::value
+
+
+
+ // More forward declarations
+ namespace fun
+ {
+ namespace v2v
+ {
+
+ template <typename T_hsl>
+ struct f_rgb_to_hsl_;
+
+ typedef f_rgb_to_hsl_<value::hsl_f> f_rgb_to_hsl_f_t;
+
+ extern f_rgb_to_hsl_f_t f_rgb_to_hsl_f;
+
+ }
+
+ }
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace value
+ {
+
+ template <typename H, typename S, typename L>
+ const H&
+ hsl_<H,S,L>::hue() const
+ {
+ return this->hue_;
+ }
+
+ template <typename H, typename S, typename L>
+ const S&
+ hsl_<H,S,L>::sat() const
+ {
+ return this->sat_;
+ }
+
+ template <typename H, typename S, typename L>
+ const L&
+ hsl_<H,S,L>::lum() const
+ {
+ return this->lum_;
+ }
+
+ template <typename H, typename S, typename L>
+ H&
+ hsl_<H,S,L>::hue()
+ {
+ return this->hue_;
+ }
+
+ template <typename H, typename S, typename L>
+ S&
+ hsl_<H,S,L>::sat()
+ {
+ return this->sat_;
+ }
+
+ template <typename H, typename S, typename L>
+ L&
+ hsl_<H,S,L>::lum()
+ {
+ return this->lum_;
+ }
+
+
+ template <typename H, typename S, typename L>
+ inline
+ std::ostream& operator<<(std::ostream& ostr, const hsl_<H,S,L>& v)
+ {
+ return ostr << '(' << debug::format(v.hue())
+ << ',' << debug::format(v.sat())
+ << ',' << debug::format(v.lum())
+ << ')';
+ }
+
} // end of namespace mln::value
+
+ namespace convert
+ {
+
+ namespace over_load
+ {
+
+ template <typename H, typename S, typename L>
+ void
+ from_to_(const value::rgb<16>& from, value::hsl_<H,S,L>& to)
+ {
+ to = fun::v2v::f_rgb_to_hsl_f(from);
+ }
+
+
+ template <typename H, typename S, typename L>
+ void
+ from_to_(const value::rgb<8>& from, value::hsl_<H,S,L>& to)
+ {
+ to = fun::v2v::f_rgb_to_hsl_f(from);
+ }
+
+ } // end of namespace mln::convert::over_load
+
+ } // end of namespace mln::convert
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
} // end of namespace mln
#endif // ! MLN_VALUE_HSL_HH
diff --git a/milena/mln/value/rgb.hh b/milena/mln/value/rgb.hh
index 452031d..6b2a479 100644
--- a/milena/mln/value/rgb.hh
+++ b/milena/mln/value/rgb.hh
@@ -25,9 +25,6 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_VALUE_RGB_HH
-# define MLN_VALUE_RGB_HH
-
/// \file mln/value/rgb.hh
///
/// Color class for red-green-blue where every component is
@@ -38,16 +35,42 @@
/// \todo Introduce the concept of Color, then generalize from_to_ to
/// colors.
+#ifndef MLN_VALUE_RGB_HH
+# define MLN_VALUE_RGB_HH
+
+
# include <mln/value/ops.hh>
# include <mln/value/concept/vectorial.hh>
# include <mln/value/int_u.hh>
# include <mln/algebra/vec.hh>
+// Needed by from_to_.
+# include <mln/fun/v2v/rgb_to_hsl.hh>
namespace mln
{
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ template <typename T_rgb>
+ struct f_hsl_to_rgb_;
+
+ typedef f_hsl_to_rgb_< value::rgb<8> > f_hsl_to_rgb_3x8_t;
+ typedef f_hsl_to_rgb_< value::rgb<16> > f_hsl_to_rgb_3x16_t;
+
+ extern f_hsl_to_rgb_3x8_t f_hsl_to_rgb_3x8;
+ extern f_hsl_to_rgb_3x16_t f_hsl_to_rgb_3x16;
+
+ }
+
+ }
+
+
namespace literal
{
/// \{ Forward declarations.
@@ -77,8 +100,11 @@ namespace mln
// Forward declaration.
- namespace value {
+ namespace value
+ {
template <unsigned n> struct rgb;
+ template <typename H, typename S, typename L> class hsl_;
+ template <unsigned n> struct int_u;
}
@@ -96,6 +122,18 @@ namespace mln
template <unsigned m>
void from_to_(bool from, value::rgb<m>& to);
+ // int_u -> rgb.
+ template <unsigned m>
+ void from_to_(const value::int_u<m>& from, value::rgb<m>& to);
+
+ // hsl -> rgb8.
+ template <typename H, typename S, typename L>
+ void from_to_(const value::hsl_<H,S,L>&, value::rgb<8>& to);
+
+ // hsl -> rgb16.
+ template <typename H, typename S, typename L>
+ void from_to_(const value::hsl_<H,S,L>&, value::rgb<16>& to);
+
} // end of namespace mln::convert::over_load
} // end of namespace mln::convert
@@ -711,6 +749,27 @@ namespace mln
to = *black_;
}
+ template <unsigned m>
+ void
+ from_to_(const value::int_u<m>& from, value::rgb<m>& to)
+ {
+ to = value::rgb<m>(from, from, from);
+ }
+
+ template <typename H, typename S, typename L>
+ void
+ from_to_(const value::hsl_<H,S,L>& from, value::rgb<8>& to)
+ {
+ to = fun::v2v::f_hsl_to_rgb_3x8(from);
+ }
+
+ template <typename H, typename S, typename L>
+ void
+ from_to_(const value::hsl_<H,S,L>& from, value::rgb<16>& to)
+ {
+ to = fun::v2v::f_hsl_to_rgb_3x16(from);
+ }
+
} // end of namespace mln::convert::over_load
} // end of namespace mln::convert
diff --git a/milena/tests/convert/Makefile.am b/milena/tests/convert/Makefile.am
index 975305b..bceaf38 100644
--- a/milena/tests/convert/Makefile.am
+++ b/milena/tests/convert/Makefile.am
@@ -4,14 +4,18 @@ include $(top_srcdir)/milena/tests/tests.mk
##FIXME: re-enable all tests
check_PROGRAMS = \
+ to_hsl \
to_image \
to_p_array \
to_p_set \
+ to_rgb \
to_window
+to_hsl_SOURCES = to_hsl.cc
to_image_SOURCES = to_image.cc
to_p_array_SOURCES = to_p_array.cc
to_p_set_SOURCES = to_p_set.cc
+to_rgb_SOURCES = to_rgb.cc
to_window_SOURCES = to_window.cc
TESTS = $(check_PROGRAMS)
diff --git a/milena/mln/convert/to_rgb.hh b/milena/tests/convert/to_hsl.cc
similarity index 54%
rename from milena/mln/convert/to_rgb.hh
rename to milena/tests/convert/to_hsl.cc
index af396a3..3f24faa 100644
--- a/milena/mln/convert/to_rgb.hh
+++ b/milena/tests/convert/to_hsl.cc
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,66 +26,26 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CONVERT_TO_RGB_HH
-# define MLN_CONVERT_TO_RGB_HH
+/// \file tests/convert/to_hsl.cc
+///
+/// Tests on mln::convert::from_to_ for hsl<H,S,L>.
-/*! \file mln/convert/to_rgb.hh
- *
- * \brief Conversions to mln::value::rgb.
- *
- * \todo Re-write.
- */
+#include <mln/core/image/image2d.hh>
+#include <mln/value/hsl.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/convert/to.hh>
-# include <mln/value/rgb.hh>
-namespace mln
+int main()
{
+ using namespace mln;
- namespace convert
- {
+ value::rgb8 c1(3,3,3);
+ value::hsl_f c2 = convert::to<value::hsl_f>(c1);
+// mln_assertion(c2 == hsl_f(0,0,3)); //FIXME: wrong result.
- using namespace value;
+ value::hsl_f c3(3,3,3);
+ c1 = convert::to<value::rgb8>(c3);
+// mln_assertion(c1 == rgb8(2,4,0)); //FIXME: wrong result.
- /// Convert a int_u \p val into rgb value.
- template <unsigned int n>
- rgb<n> to_rgb(const int_u<n>& i);
-
- template <unsigned int n>
- rgb<n>& to_rgb(rgb<n>& i);
-
- template <unsigned int n>
- const rgb<n>& to_rgb(const rgb<n>& i);
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- template <unsigned int n>
- inline
- rgb<n> to_rgb(const int_u<n>& i)
- {
- rgb<n> c(i, i, i);
- return c;
- }
-
- template <unsigned int n>
- inline
- rgb<n>& to_rgb(rgb<n>& i)
- {
- return i;
- }
-
- template <unsigned int n>
- inline
- const rgb<n>& to_rgb(const rgb<n>& i)
- {
- return i;
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace mln::convert
-
-} // end of namespace mln
-
-
-#endif // ! MLN_CONVERT_TO_WINDOW_HH
+}
diff --git a/milena/mln/convert/all.hh b/milena/tests/convert/to_rgb.cc
similarity index 68%
copy from milena/mln/convert/all.hh
copy to milena/tests/convert/to_rgb.cc
index 0fab453..24c7508 100644
--- a/milena/mln/convert/all.hh
+++ b/milena/tests/convert/to_rgb.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -26,32 +26,29 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CONVERT_ALL_HH
-# define MLN_CONVERT_ALL_HH
-
-/// \file mln/convert/all.hh
+/// \file tests/convert/to_rgb.cc
///
-/// File that includes all conversion-related routines.
-
-
-namespace mln
-{
+/// Tests on mln::convert::from_to_ for rgb<n>.
- /// Namespace of conversion routines.
- namespace convert {}
-
-}
+#include <mln/core/image/image2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/convert/to.hh>
-# include <mln/convert/from_to.hh>
-# include <mln/convert/to.hh>
+int main()
+{
+ using namespace mln;
-# include <mln/convert/to_dpoint.hh>
-# include <mln/convert/to_fun.hh>
-# include <mln/convert/to_image.hh>
-# include <mln/convert/to_rgb.hh>
-# include <mln/convert/to_p_array.hh>
-# include <mln/convert/to_window.hh>
+ value::rgb8 c1(3,3,3);
+ value::rgb8 c2 = convert::to<value::rgb8>(c1);
+ mln_assertion(c1 == c2);
+ const value::rgb8 c3(3,3,3);
+ c2 = convert::to<value::rgb8>(c3);
+ mln_assertion(c2 == c3);
-#endif // ! MLN_CONVERT_ALL_HH
+ value::int_u8 i = 3;
+ c2 = convert::to<value::rgb8>(i);
+ mln_assertion(c2 == value::rgb8(3,3,3));
+}
diff --git a/milena/tests/unit_test/Makefile.am b/milena/tests/unit_test/Makefile.am
index f7886cd..9398c88 100644
--- a/milena/tests/unit_test/Makefile.am
+++ b/milena/tests/unit_test/Makefile.am
@@ -267,7 +267,6 @@ mln_convert_impl_from_float_to_value \
mln_convert_impl_from_int_to_value \
mln_convert_to_dpoint \
mln_convert_to_p_array \
-mln_convert_to_rgb \
mln_convert_essential \
mln_value_shell \
mln_value_float01_f \
@@ -1283,7 +1282,6 @@ mln_convert_impl_from_float_to_value_SOURCES = mln_convert_impl_from_float_to_va
mln_convert_impl_from_int_to_value_SOURCES = mln_convert_impl_from_int_to_value.cc
mln_convert_to_dpoint_SOURCES = mln_convert_to_dpoint.cc
mln_convert_to_p_array_SOURCES = mln_convert_to_p_array.cc
-mln_convert_to_rgb_SOURCES = mln_convert_to_rgb.cc
mln_convert_essential_SOURCES = mln_convert_essential.cc
mln_value_shell_SOURCES = mln_value_shell.cc
mln_value_float01_f_SOURCES = mln_value_float01_f.cc
diff --git a/milena/tests/unit_test/mln_convert_to_rgb.cc b/milena/tests/unit_test/mln_convert_to_rgb.cc
deleted file mode 100644
index d98e87a..0000000
--- a/milena/tests/unit_test/mln_convert_to_rgb.cc
+++ /dev/null
@@ -1,11 +0,0 @@
-// Unit test for mln/convert/to_rgb.hh.
-// Generated by ./build_unit_test.sh, do not modify.
-
-// Include the file twice, so we detect missing inclusion guards.
-#include <mln/convert/to_rgb.hh>
-#include <mln/convert/to_rgb.hh>
-
-int main()
-{
- // Nothing.
-}
--
1.5.6.5
1
0
21 Jan '09
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Externalize element and nelement method in fastest images.
* mln/opt/element.hh: New, define opt::element and opt::nelements.
* mln/debug/println_with_border.spe.hh,
* mln/debug/println_with_border.hh,
* mln/data/paste.spe.hh,
* mln/data/fill_with_value.spe.hh,
* mln/data/fill_with_image.spe.hh,
* mln/data/memcpy_.hh,
* mln/data/memset_.hh,
* mln/border/fill.hh,
* mln/border/duplicate.hh,
* mln/border/mirror.hh,
* tests/opt/value.cc,
* tests/border/duplicate_full.cc,
* tests/border/mirror_full.cc,
* tests/border/fill_full.cc,
* tests/border/duplicate.cc,
* tests/border/mirror.cc,
* tests/border/fill.cc: Use now opt::element and opt::nelements.
* mln/opt/value.hh: Update Copyright.
* tests/opt/element.cc: New tests.
mln/border/duplicate.hh | 29 +++---
mln/border/fill.hh | 13 +-
mln/border/mirror.hh | 33 ++++---
mln/data/fill_with_image.spe.hh | 3
mln/data/fill_with_value.spe.hh | 3
mln/data/memcpy_.hh | 26 ++---
mln/data/memset_.hh | 10 +-
mln/data/paste.spe.hh | 3
mln/debug/println_with_border.hh | 3
mln/debug/println_with_border.spe.hh | 3
mln/opt/element.hh | 165 +++++++++++++++++++++++++++++++++++
mln/opt/value.hh | 2
tests/border/duplicate.cc | 51 +++++-----
tests/border/duplicate_full.cc | 5 -
tests/border/fill.cc | 5 -
tests/border/fill_full.cc | 25 ++---
tests/border/mirror.cc | 101 ++++++++++-----------
tests/border/mirror_full.cc | 5 -
tests/opt/element.cc | 47 +++++++++
tests/opt/value.cc | 4
20 files changed, 390 insertions(+), 146 deletions(-)
Index: mln/debug/println_with_border.spe.hh
--- mln/debug/println_with_border.spe.hh (revision 3178)
+++ mln/debug/println_with_border.spe.hh (working copy)
@@ -40,6 +40,7 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/window.hh>
# include <mln/debug/format.hh>
+# include <mln/opt/element.hh>
namespace mln
{
@@ -61,7 +62,7 @@
println_with_border(const box2d& b, const I& input)
{
const unsigned ncols = b.ncols() + 2 * input.border();
- for (size_t i = 0; i < input.nelements(); i++)
+ for (size_t i = 0; i < opt::nelements(input); i++)
{
std::cout << format(input.buffer()[i]) << ' ';
if (((i + 1) % ncols) == 0)
Index: mln/debug/println_with_border.hh
--- mln/debug/println_with_border.hh (revision 3178)
+++ mln/debug/println_with_border.hh (working copy)
@@ -43,6 +43,7 @@
# include <mln/debug/format.hh>
// Specializations are in:
# include <mln/debug/println_with_border.spe.hh>
+# include <mln/opt/element.hh>
namespace mln
{
@@ -66,7 +67,7 @@
void
println_with_border(const S&, const I& input)
{
- for (size_t i = 0; i < input.nelements(); i++)
+ for (size_t i = 0; i < opt::nelements(input); i++)
std::cout << format(input.buffer()[i]) << ' ';
std::cout << std::endl;
}
Index: mln/opt/element.hh
--- mln/opt/element.hh (revision 0)
+++ mln/opt/element.hh (revision 0)
@@ -0,0 +1,165 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_OPT_ELEMENT_HH
+# define MLN_OPT_ELEMENT_HH
+
+/// \file mln/opt/element.hh
+///
+/// Define the opt::element and opt::nelements routines.
+
+# include <mln/core/concept/image.hh>
+# include <mln/trait/images.hh>
+
+namespace mln
+{
+
+ namespace opt
+ {
+
+ template <typename I>
+ inline
+ mln_rvalue(I) element(const Image<I>& ima, unsigned index);
+
+ template <typename I>
+ inline
+ mln_lvalue(I) element(Image<I>& ima, unsigned index);
+
+ template <typename I>
+ inline
+ unsigned nelements(const Image<I>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I>
+ inline
+ mln_rvalue(I) element_impl(trait::image::category::domain_morpher,
+ const Image<I>& ima, unsigned index)
+ {
+ return element(*exact(ima).delegatee_());
+ }
+
+ template <typename I>
+ inline
+ mln_rvalue(I) element_impl(trait::image::category::any,
+ const Image<I>& ima, unsigned index)
+ {
+ mlc_and(mlc_is(mln_trait_image_value_storage(I),
+ trait::image::value_storage::one_block),
+ mlc_is(mln_trait_image_value_access(I),
+ trait::image::value_access::direct))::check();
+
+ return exact(ima).element(index);
+ }
+
+
+ template <typename I>
+ inline
+ mln_lvalue(I) element_impl(trait::image::category::domain_morpher,
+ Image<I>& ima, unsigned index)
+ {
+ return element(*exact(ima).delegatee_());
+ }
+
+ template <typename I>
+ inline
+ mln_lvalue(I) element_impl(trait::image::category::any,
+ Image<I>& ima, unsigned index)
+ {
+ mlc_and(mlc_is(mln_trait_image_value_storage(I),
+ trait::image::value_storage::one_block),
+ mlc_is(mln_trait_image_value_access(I),
+ trait::image::value_access::direct))::check();
+
+ return exact(ima).element(index);
+ }
+
+
+
+
+ template <typename I>
+ inline
+ unsigned nelements_impl(trait::image::category::domain_morpher,
+ const Image<I>& ima)
+ {
+ return nelements(*exact(ima).delegatee_());
+ }
+
+ template <typename I>
+ inline
+ unsigned nelements_impl(trait::image::category::any,
+ const Image<I>& ima)
+ {
+ mlc_is(mln_trait_image_value_storage(I),
+ trait::image::value_storage::one_block)::check();
+
+ return exact(ima).nelements();
+ }
+
+
+
+
+
+
+ } // end of namespace mln::opt::impl
+
+
+ template <typename I>
+ inline
+ mln_rvalue(I) element(const Image<I>& ima, unsigned index)
+ {
+ return impl::element_impl(mln_trait_image_category(I)(), ima, index);
+ }
+
+ template <typename I>
+ inline
+ mln_lvalue(I) element(Image<I>& ima, unsigned index)
+ {
+ return impl::element_impl(mln_trait_image_category(I)(), ima, index);
+ }
+
+
+ template <typename I>
+ inline
+ unsigned nelements(const Image<I>& ima)
+ {
+ return impl::nelements_impl(mln_trait_image_category(I)(), ima);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::opt
+
+} // end of namespace mln
+
+
+#endif // ! MLN_OPT_VALUE_HH
Index: mln/opt/value.hh
--- mln/opt/value.hh (revision 3178)
+++ mln/opt/value.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2009 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of the Olena Library. This library is free
Index: mln/data/paste.spe.hh
--- mln/data/paste.spe.hh (revision 3178)
+++ mln/data/paste.spe.hh (working copy)
@@ -43,6 +43,7 @@
# include <mln/core/box_runstart_piter.hh>
# include <mln/border/get.hh>
# include <mln/opt/value.hh>
+# include <mln/opt/element.hh>
@@ -111,7 +112,7 @@
*(src.address_()) = input.buffer();
*(dst.address_()) = output.buffer();
- memcpy_(dst, src, input.nelements());
+ memcpy_(dst, src, opt::nelements(input));
trace::exiting("data::impl::paste_fastest");
}
Index: mln/data/fill_with_value.spe.hh
--- mln/data/fill_with_value.spe.hh (revision 3178)
+++ mln/data/fill_with_value.spe.hh (working copy)
@@ -38,6 +38,7 @@
# include <mln/data/memset_.hh>
# include <mln/opt/value.hh>
+# include <mln/opt/element.hh>
# ifndef MLN_INCLUDE_ONLY
@@ -89,7 +90,7 @@
trait::image::value_access::direct))::check();
mln_value(I) v = static_cast<mln_value(I)>(val);
- data::memset_(ima, ima.point_at_index(0), v, ima.nelements());
+ data::memset_(ima, ima.point_at_index(0), v, opt::nelements(ima));
trace::exiting("data::impl::fill_with_value_one_block");
}
Index: mln/data/fill_with_image.spe.hh
--- mln/data/fill_with_image.spe.hh (revision 3178)
+++ mln/data/fill_with_image.spe.hh (working copy)
@@ -44,6 +44,7 @@
# include <mln/core/box_runstart_piter.hh>
# include <mln/border/get.hh>
# include <mln/opt/value.hh>
+# include <mln/opt/element.hh>
# ifndef MLN_INCLUDE_ONLY
@@ -89,7 +90,7 @@
*(src.address_()) = data.buffer();
*(dst.address_()) = ima.buffer();
- memcpy_(dst, src, ima.nelements());
+ memcpy_(dst, src, opt::nelements(ima));
trace::exiting("data::impl::fill_with_image_fastest");
}
Index: mln/data/memcpy_.hh
--- mln/data/memcpy_.hh (revision 3178)
+++ mln/data/memcpy_.hh (working copy)
@@ -39,6 +39,8 @@
# include <mln/core/concept/image.hh>
# include <mln/core/pixel.hh>
# include <mln/metal/is_not_const.hh>
+# include <mln/opt/element.hh>
+
namespace mln
@@ -126,18 +128,18 @@
mln_precondition(dest.ima().is_valid());
mln_precondition(src.ima().is_valid());
- mln_precondition(&dest.val() >= &dest.ima().element(0));
- mln_precondition(&dest.val() < &dest.ima().element(0) +
- dest.ima().nelements());
-
- mln_precondition(&dest.val() + n <= &dest.ima().element(0) +
- dest.ima().nelements());
-
- mln_precondition(&src.val() >= &src.ima().element(0));
- mln_precondition(&src.val() < &src.ima().element(0) +
- src.ima().nelements());
- mln_precondition(&src.val() + n <= &src.ima().element(0) +
- src.ima().nelements());
+ mln_precondition(&dest.val() >= &opt::element(dest.ima(), 0));
+ mln_precondition(&dest.val() < &opt::element(dest.ima(), 0) +
+ opt::nelements(dest.ima()));
+
+ mln_precondition(&dest.val() + n <= &opt::element(dest.ima(), 0) +
+ opt::nelements(dest.ima()));
+
+ mln_precondition(&src.val() >= &opt::element(src.ima(), 0));
+ mln_precondition(&src.val() < &opt::element(src.ima(), 0) +
+ opt::nelements(src.ima()));
+ mln_precondition(&src.val() + n <= &opt::element(src.ima(), 0) +
+ opt::nelements(src.ima()));
impl::memcpy__(dest, src, n);
Index: mln/data/memset_.hh
--- mln/data/memset_.hh (revision 3178)
+++ mln/data/memset_.hh (working copy)
@@ -38,6 +38,8 @@
# include <mln/core/concept/image.hh>
# include <mln/core/pixel.hh>
# include <mln/metal/is_not_const.hh>
+# include <mln/opt/element.hh>
+
namespace mln
@@ -132,8 +134,10 @@
P& pix = mln::internal::force_exact<P>(pix_);
mln_precondition(pix.ima().is_valid());
mln_precondition(& pix.val() >= & pix.ima()[0]);
- mln_precondition(& pix.val() < & pix.ima()[0] + pix.ima().nelements());
- mln_precondition(& pix.val() + n <= & pix.ima()[0] + pix.ima().nelements());
+ mln_precondition(& pix.val() < & pix.ima()[0] +
+ opt::nelements(pix.ima()));
+ mln_precondition(& pix.val() + n <= & pix.ima()[0] +
+ opt::nelements(pix.ima()));
impl::memset__(pix, v, n);
@@ -151,7 +155,7 @@
mln_precondition(input.is_valid());
mln_precondition(input.has(p));
- mln_precondition(input.index_of_point(p) + n <= input.nelements());
+ mln_precondition(input.index_of_point(p) + n <= opt::nelements(input));
pixel<I> pix(input, p);
impl::memset__(pix, v, n);
Index: mln/border/fill.hh
--- mln/border/fill.hh (revision 3178)
+++ mln/border/fill.hh (working copy)
@@ -38,6 +38,7 @@
# include <mln/core/concept/image.hh>
# include <mln/core/box_runstart_piter.hh>
+# include <mln/opt/element.hh>
namespace mln
@@ -99,14 +100,14 @@
for_all (pl)
{
unsigned end = ima.index_of_point (pl);
- std::memset((void*)&ima.element(st),
+ std::memset((void*)&opt::element(ima, st),
*(const int*)(&v),
end - st);
st = end + len_r;
}
- std::memset((void*)&ima.element(st),
+ std::memset((void*)&opt::element(ima, st),
*(const int*)(&v),
- ima.nelements () - st);
+ opt::nelements(ima) - st);
trace::exiting("border::impl::fill_size_1");
}
@@ -130,11 +131,11 @@
{
unsigned end = ima.index_of_point (pl);
for (unsigned i = st; i < end; ++i)
- ima.element(i) = v;
+ opt::element(ima, i) = v;
st = end + len_r;
}
- for (unsigned i = st; i < ima.nelements (); ++i)
- ima.element(i) = v;
+ for (unsigned i = st; i < opt::nelements(ima); ++i)
+ opt::element(ima, i) = v;
trace::exiting("border::impl::fill_size_n");
}
Index: mln/border/duplicate.hh
--- mln/border/duplicate.hh (revision 3178)
+++ mln/border/duplicate.hh (working copy)
@@ -37,6 +37,7 @@
# include <mln/core/routine/primary.hh>
# include <mln/core/box_runstart_piter.hh>
# include <mln/border/get.hh>
+# include <mln/opt/element.hh>
namespace mln
@@ -75,11 +76,11 @@
unsigned border = ima.border();
for (unsigned i = 0; i < border; ++i)
- ima.element(i) = ima.element(border);
+ opt::element(ima, i) = opt::element(ima, border);
unsigned st = border + len_c - 1;
- for (unsigned i = st + 1; i < ima.nelements(); ++i)
- ima.element(i) = ima.element(st);
+ for (unsigned i = st + 1; i < opt::nelements(ima); ++i)
+ opt::element(ima, i) = opt::element(ima, st);
trace::exiting("border::impl::duplicate_1D");
}
@@ -104,23 +105,23 @@
{
st = ima.index_of_point (pl);
for (unsigned i = 1; i <= border; ++i)
- ima.element(st - i) = ima.element(st);
+ opt::element(ima, st - i) = opt::element(ima, st);
st = st + len_c - 1;
for (unsigned i = 1; i <= border; ++i)
- ima.element(st + i) = ima.element(st);
+ opt::element(ima, st + i) = opt::element(ima, st);
}
// Duplicate n first * border line
st = real_len_c * border;
for (unsigned k = 0; k < border; ++k)
for (unsigned i = 0; i < real_len_c; ++i)
- ima.element(k * real_len_c + i) = ima.element(st + i);
+ opt::element(ima, k * real_len_c + i) = opt::element(ima, st + i);
// Duplicate n last * border line
st = real_len_c * (border + len_r - 1);
for (unsigned k = 1; k <= border; ++k)
for (unsigned i = st; i < st + real_len_c; ++i)
- ima.element(k * real_len_c + i) = ima.element(i);
+ opt::element(ima, k * real_len_c + i) = opt::element(ima, i);
trace::exiting("border::impl::duplicate_2D");
}
@@ -155,10 +156,10 @@
{
st = ima.index_of_point (pl);
for (unsigned i = 1; i <= border; ++i)
- ima.element(st - i) = ima.element(st);
+ opt::element(ima, st - i) = opt::element(ima, st);
st = st + len_c - 1;
for (unsigned i = 1; i <= border; ++i)
- ima.element(st + i) = ima.element(st);
+ opt::element(ima, st + i) = opt::element(ima, st);
pl.next();
}
@@ -166,26 +167,28 @@
st = border * face + k * face + border * real_len_c ;
for (unsigned j = 1; j <= border; ++j)
for (unsigned i = 0; i < real_len_c; ++i)
- ima.element(st - j * real_len_c + i) = ima.element(st + i);
+ opt::element(ima, st - j * real_len_c + i) =
+ opt::element(ima, st + i);
// Duplicate n last * border line
st = border * face + k * face + (len_r + border - 1) * real_len_c ;
for (unsigned j = 1; j <= border; ++j)
for (unsigned i = 0; i < real_len_c; ++i)
- ima.element(st + j * real_len_c + i) = ima.element(st + i);
+ opt::element(ima, st + j * real_len_c + i) =
+ opt::element(ima, st + i);
}
// Duplicate n first * border face
st = border * face;
for (unsigned k = 0; k < border; ++k)
for (unsigned i = 0; i < face; ++i)
- ima.element(k * face + i) = ima.element(st + i);
+ opt::element(ima, k * face + i) = opt::element(ima, st + i);
// Duplicate n last * border face
st = (len_s + border - 1) * face;
for (unsigned k = 1; k <= border; ++k)
for (unsigned i = 0; i < face; ++i)
- ima.element(st + k * face + i) = ima.element(st + i);
+ opt::element(ima, st + k * face + i) = opt::element(ima, st + i);
trace::exiting("border::impl::duplicate_3D");
}
Index: mln/border/mirror.hh
--- mln/border/mirror.hh (revision 3178)
+++ mln/border/mirror.hh (working copy)
@@ -49,6 +49,8 @@
# include <mln/geom/max_col.hh>
# include <mln/geom/ninds.hh>
+# include <mln/opt/element.hh>
+
namespace mln
{
@@ -95,10 +97,10 @@
{
def::coord i = 0;
for (; i < min; ++i)
- ima.element(border - 1 - i) = ima(point1d(i));
+ opt::element(ima, border - 1 - i) = ima(point1d(i));
for (; i < border; ++i)
- ima.element(border - 1 - i) = ima(point1d(static_cast<def::coord>(min - 1)));
+ opt::element(ima, border - 1 - i) = ima(point1d(static_cast<def::coord>(min - 1)));
}
/// right border
@@ -109,12 +111,12 @@
for (;
i < min;
++i, --j)
- ima.element(border + nbinds + i) = ima(point1d(j));
+ opt::element(ima, border + nbinds + i) = ima(point1d(j));
++j;
for (;
i < border;
++i)
- ima.element(border + nbinds + i) = ima(point1d(j));
+ opt::element(ima, border + nbinds + i) = ima(point1d(j));
}
trace::exiting("border::impl::mirror_");
}
@@ -136,49 +138,56 @@
// mirror top left corner
for (unsigned i = 0; i < border; ++i)
for (unsigned j = 0; j < border; ++j)
- ima.element(i * ((nbcols + 1) + 2 * border) + j) = ima.element(s);
+ opt::element(ima, i * ((nbcols + 1) + 2 * border) + j) =
+ opt::element(ima, s);
// mirror top left corner
s = start + nbcols;
for (unsigned i = 0; i < border; ++i)
for (unsigned j = 1; j <= border; ++j)
- ima.element(i * ((nbcols + 1) + 2 * border) + (nbcols + border + j)) = ima.element(s);
+ opt::element(ima, i * ((nbcols + 1) + 2 * border) + (nbcols + border + j)) = opt::element(ima, s);
// mirror bottom left corner
s = start + (nbrows * real_nbcols);
for (unsigned i = 1; i <= border; ++i)
for (unsigned j = 1; j <= border; ++j)
- ima.element(s - i + (j * (real_nbcols))) = ima.element(s);
+ opt::element(ima, s - i + (j * (real_nbcols))) =
+ opt::element(ima, s);
// mirror bottom right corner
s = start + (nbrows * real_nbcols) + nbcols;
for (unsigned i = 1; i <= border; ++i)
for (unsigned j = 1; j <= border; ++j)
- ima.element(s + i + (j * real_nbcols)) = ima.element(s);
+ opt::element(ima, s + i + (j * real_nbcols)) =
+ opt::element(ima, s);
// mirror top border
s = start;
for (unsigned i = 0; i <= nbcols; ++i)
for (unsigned j = 1; j <= border; ++j)
- ima.element(s + i - (j * real_nbcols)) = ima.element(s + i + ((j - 1)* real_nbcols));
+ opt::element(ima, s + i - (j * real_nbcols)) =
+ opt::element(ima, s + i + ((j - 1)* real_nbcols));
// mirror left border
s = start;
for (unsigned i = 0; i <= nbrows; ++i)
for (unsigned j = 1; j <= border; ++j)
- ima.element(s + (i * real_nbcols) - j) = ima.element(s + (i * real_nbcols) + (j - 1));
+ opt::element(ima, s + (i * real_nbcols) - j) =
+ opt::element(ima, s + (i * real_nbcols) + (j - 1));
// mirror right border
s = start;
for (unsigned i = 0; i <= nbrows; ++i)
for (unsigned j = 1; j <= border; ++j)
- ima.element(s + (i * real_nbcols + nbcols) + j) = ima.element(s + (i * real_nbcols + nbcols) - (j - 1));
+ opt::element(ima, s + (i * real_nbcols + nbcols) + j) =
+ opt::element(ima, s + (i * real_nbcols + nbcols) - (j - 1));
// mirror bottom border
s = start + (nbrows * real_nbcols);
for (unsigned i = 0; i <= nbcols; ++i)
for (unsigned j = 1; j <= border; ++j)
- ima.element(s + i + (j * real_nbcols)) = ima.element(s + i - ((j - 1)* real_nbcols));
+ opt::element(ima, s + i + (j * real_nbcols)) =
+ opt::element(ima, s + i - ((j - 1)* real_nbcols));
trace::exiting("border::impl::mirror_");
}
Index: tests/opt/value.cc
--- tests/opt/value.cc (revision 3178)
+++ tests/opt/value.cc (working copy)
@@ -26,9 +26,9 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/// \file tests/opt/at.cc
+/// \file tests/opt/value.cc
///
-/// Tests on mln::opt::at.
+/// Tests on mln::opt::value.
#include <mln/opt/value.hh>
#include <mln/core/image/flat_image.hh>
Index: tests/opt/element.cc
--- tests/opt/element.cc (revision 0)
+++ tests/opt/element.cc (revision 0)
@@ -0,0 +1,47 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file tests/opt/value.cc
+///
+/// Tests on mln::opt::at.
+
+#include <mln/opt/element.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/trace/all.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<short> ima(12, 12);
+
+ opt::element(ima, 2) = 51;
+ mln_precondition(opt::element(ima, 2) == 51);
+ mln_precondition(opt::nelements(ima) == 324);
+}
Index: tests/border/duplicate_full.cc
--- tests/border/duplicate_full.cc (revision 3178)
+++ tests/border/duplicate_full.cc (working copy)
@@ -36,6 +36,7 @@
#include <mln/border/duplicate.hh>
#include <mln/value/int_u8.hh>
#include <mln/value/int_s8.hh>
+#include <mln/opt/element.hh>
namespace mln
{
@@ -50,7 +51,7 @@
border::duplicate(ima);
for (int i = 0; i < c; ++i)
- mln_assertion(ima.element(i) == ref[i]);
+ mln_assertion(opt::element(ima, i) == ref[i]);
}
template <typename T>
@@ -64,7 +65,7 @@
border::duplicate(ima);
for (int i = 0; i < c * r; ++i)
- mln_assertion(ima.element(i) == ref[i]);
+ mln_assertion(opt::element(ima, i) == ref[i]);
}
}
Index: tests/border/mirror_full.cc
--- tests/border/mirror_full.cc (revision 3178)
+++ tests/border/mirror_full.cc (working copy)
@@ -36,6 +36,7 @@
#include <mln/border/mirror.hh>
#include <mln/value/int_u8.hh>
#include <mln/value/int_s8.hh>
+#include <mln/opt/element.hh>
namespace mln
@@ -51,7 +52,7 @@
border::mirror(ima);
for (int i = 0; i < c; ++i)
- mln_assertion(ima.element(i) == ref[i]);
+ mln_assertion(opt::element(ima, i) == ref[i]);
}
template <typename T>
@@ -65,7 +66,7 @@
border::mirror(ima);
for (int i = 0; i < c * r; ++i)
- mln_assertion(ima.element(i) == ref[i]);
+ mln_assertion(opt::element(ima, i) == ref[i]);
}
}
Index: tests/border/fill_full.cc
--- tests/border/fill_full.cc (revision 3178)
+++ tests/border/fill_full.cc (working copy)
@@ -32,8 +32,10 @@
///
/// \todo Rewrite this non-sense test file!!!
+
#include <mln/border/fill.hh>
#include <mln/data/fill.hh>
+#include <mln/opt/element.hh>
#include <mln/core/image/image1d.hh>
#include <mln/core/image/image2d.hh>
#include <mln/core/image/image3d.hh>
@@ -47,6 +49,7 @@
#include <mln/value/float01_16.hh>
#include <mln/debug/println_with_border.hh>
+
using namespace mln;
@@ -60,13 +63,13 @@
unsigned i = 0;
for(i = 0; i < border; ++i)
- mln_assertion (ima.element(i) == value);
+ mln_assertion (opt::element(ima, i) == value);
unsigned bo = border + row;
for(; i < bo; ++i)
- mln_assertion (ima.element(i) == v);
+ mln_assertion (opt::element(ima, i) == v);
bo += border;
for(; i < bo; ++i)
- mln_assertion (ima.element(i) == value);
+ mln_assertion (opt::element(ima, i) == value);
}
template <typename T>
@@ -85,18 +88,18 @@
unsigned ww = r * c;
for(i = 0; i < bo; ++i)
- mln_assertion (ima.element(i) == value);
+ mln_assertion (opt::element(ima, i) == value);
bo += c * row;
for(; i < bo; ++i)
{
unsigned cur = i % c;
if (cur < border || cur >= u)
- mln_assertion (ima.element(i) == value);
+ mln_assertion (opt::element(ima, i) == value);
else
- mln_assertion (ima.element(i) == v);
+ mln_assertion (opt::element(ima, i) == v);
}
for(; i < ww; ++i)
- mln_assertion (ima.element(i) == value);
+ mln_assertion (opt::element(ima, i) == value);
}
template <typename T>
@@ -115,18 +118,18 @@
unsigned ww = r * c;
for(i = 0; i < bo; ++i)
- mln_assertion (ima.element(i) == value);
+ mln_assertion (opt::element(ima, i) == value);
bo += c * row;
for(; i < bo; ++i)
{
unsigned cur = i % c;
if (cur < border || cur >= u)
- mln_assertion (ima.element(i) == value);
+ mln_assertion (opt::element(ima, i) == value);
else
- mln_assertion (ima.element(i) == v);
+ mln_assertion (opt::element(ima, i) == v);
}
for(; i < ww; ++i)
- mln_assertion (ima.element(i) == value);
+ mln_assertion (opt::element(ima, i) == value);
}
Index: tests/border/duplicate.cc
--- tests/border/duplicate.cc (revision 3178)
+++ tests/border/duplicate.cc (working copy)
@@ -34,6 +34,7 @@
#include <mln/core/image/image2d.hh>
#include <mln/debug/iota.hh>
#include <mln/border/duplicate.hh>
+#include <mln/opt/element.hh>
using namespace mln;
@@ -46,30 +47,30 @@
debug::iota(ima);
border::duplicate(ima);
- mln_assertion(ima.element( 0) == 1);
- mln_assertion(ima.element( 1) == 1);
- mln_assertion(ima.element( 2) == 2);
- mln_assertion(ima.element( 3) == 3);
- mln_assertion(ima.element( 4) == 3);
- mln_assertion(ima.element( 5) == 1);
- mln_assertion(ima.element( 6) == 1);
- mln_assertion(ima.element( 7) == 2);
- mln_assertion(ima.element( 8) == 3);
- mln_assertion(ima.element( 9) == 3);
- mln_assertion(ima.element(10) == 4);
- mln_assertion(ima.element(11) == 4);
- mln_assertion(ima.element(12) == 5);
- mln_assertion(ima.element(13) == 6);
- mln_assertion(ima.element(14) == 6);
- mln_assertion(ima.element(15) == 7);
- mln_assertion(ima.element(16) == 7);
- mln_assertion(ima.element(17) == 8);
- mln_assertion(ima.element(18) == 9);
- mln_assertion(ima.element(19) == 9);
- mln_assertion(ima.element(20) == 7);
- mln_assertion(ima.element(21) == 7);
- mln_assertion(ima.element(22) == 8);
- mln_assertion(ima.element(23) == 9);
- mln_assertion(ima.element(24) == 9);
+ mln_assertion(opt::element(ima, 0) == 1);
+ mln_assertion(opt::element(ima, 1) == 1);
+ mln_assertion(opt::element(ima, 2) == 2);
+ mln_assertion(opt::element(ima, 3) == 3);
+ mln_assertion(opt::element(ima, 4) == 3);
+ mln_assertion(opt::element(ima, 5) == 1);
+ mln_assertion(opt::element(ima, 6) == 1);
+ mln_assertion(opt::element(ima, 7) == 2);
+ mln_assertion(opt::element(ima, 8) == 3);
+ mln_assertion(opt::element(ima, 9) == 3);
+ mln_assertion(opt::element(ima, 10) == 4);
+ mln_assertion(opt::element(ima, 11) == 4);
+ mln_assertion(opt::element(ima, 12) == 5);
+ mln_assertion(opt::element(ima, 13) == 6);
+ mln_assertion(opt::element(ima, 14) == 6);
+ mln_assertion(opt::element(ima, 15) == 7);
+ mln_assertion(opt::element(ima, 16) == 7);
+ mln_assertion(opt::element(ima, 17) == 8);
+ mln_assertion(opt::element(ima, 18) == 9);
+ mln_assertion(opt::element(ima, 19) == 9);
+ mln_assertion(opt::element(ima, 20) == 7);
+ mln_assertion(opt::element(ima, 21) == 7);
+ mln_assertion(opt::element(ima, 22) == 8);
+ mln_assertion(opt::element(ima, 23) == 9);
+ mln_assertion(opt::element(ima, 24) == 9);
}
Index: tests/border/mirror.cc
--- tests/border/mirror.cc (revision 3178)
+++ tests/border/mirror.cc (working copy)
@@ -34,6 +34,7 @@
#include <mln/core/image/image2d.hh>
#include <mln/debug/iota.hh>
#include <mln/border/mirror.hh>
+#include <mln/opt/element.hh>
#include <mln/debug/println_with_border.hh>
@@ -46,14 +47,14 @@
image1d<int> ima(2, 3);
debug::iota(ima);
border::mirror(ima);
- mln_assertion(ima.element(0) == 2);
- mln_assertion(ima.element(1) == 2);
- mln_assertion(ima.element(2) == 1);
- mln_assertion(ima.element(3) == 1);
- mln_assertion(ima.element(4) == 2);
- mln_assertion(ima.element(5) == 2);
- mln_assertion(ima.element(6) == 1);
- mln_assertion(ima.element(7) == 1);
+ mln_assertion(opt::element(ima, 0) == 2);
+ mln_assertion(opt::element(ima, 1) == 2);
+ mln_assertion(opt::element(ima, 2) == 1);
+ mln_assertion(opt::element(ima, 3) == 1);
+ mln_assertion(opt::element(ima, 4) == 2);
+ mln_assertion(opt::element(ima, 5) == 2);
+ mln_assertion(opt::element(ima, 6) == 1);
+ mln_assertion(opt::element(ima, 7) == 1);
}
@@ -62,47 +63,47 @@
debug::iota(ima);
border::mirror(ima);
- mln_assertion(ima.element( 0) == 1);
- mln_assertion(ima.element( 1) == 1);
- mln_assertion(ima.element( 2) == 4);
- mln_assertion(ima.element( 3) == 5);
- mln_assertion(ima.element( 4) == 6);
- mln_assertion(ima.element( 5) == 3);
- mln_assertion(ima.element( 6) == 3);
- mln_assertion(ima.element( 7) == 1);
- mln_assertion(ima.element( 8) == 1);
- mln_assertion(ima.element( 9) == 1);
- mln_assertion(ima.element(10) == 2);
- mln_assertion(ima.element(11) == 3);
- mln_assertion(ima.element(12) == 3);
- mln_assertion(ima.element(13) == 3);
- mln_assertion(ima.element(14) == 2);
- mln_assertion(ima.element(15) == 1);
- mln_assertion(ima.element(16) == 1);
- mln_assertion(ima.element(17) == 2);
- mln_assertion(ima.element(18) == 3);
- mln_assertion(ima.element(19) == 3);
- mln_assertion(ima.element(20) == 2);
- mln_assertion(ima.element(21) == 5);
- mln_assertion(ima.element(22) == 4);
- mln_assertion(ima.element(23) == 4);
- mln_assertion(ima.element(24) == 5);
- mln_assertion(ima.element(25) == 6);
- mln_assertion(ima.element(26) == 6);
- mln_assertion(ima.element(27) == 5);
- mln_assertion(ima.element(28) == 4);
- mln_assertion(ima.element(29) == 4);
- mln_assertion(ima.element(30) == 4);
- mln_assertion(ima.element(31) == 5);
- mln_assertion(ima.element(32) == 6);
- mln_assertion(ima.element(33) == 6);
- mln_assertion(ima.element(34) == 6);
- mln_assertion(ima.element(35) == 4);
- mln_assertion(ima.element(36) == 4);
- mln_assertion(ima.element(37) == 1);
- mln_assertion(ima.element(38) == 2);
- mln_assertion(ima.element(39) == 3);
- mln_assertion(ima.element(40) == 6);
- mln_assertion(ima.element(41) == 6);
+ mln_assertion(opt::element(ima, 0) == 1);
+ mln_assertion(opt::element(ima, 1) == 1);
+ mln_assertion(opt::element(ima, 2) == 4);
+ mln_assertion(opt::element(ima, 3) == 5);
+ mln_assertion(opt::element(ima, 4) == 6);
+ mln_assertion(opt::element(ima, 5) == 3);
+ mln_assertion(opt::element(ima, 6) == 3);
+ mln_assertion(opt::element(ima, 7) == 1);
+ mln_assertion(opt::element(ima, 8) == 1);
+ mln_assertion(opt::element(ima, 9) == 1);
+ mln_assertion(opt::element(ima, 10) == 2);
+ mln_assertion(opt::element(ima, 11) == 3);
+ mln_assertion(opt::element(ima, 12) == 3);
+ mln_assertion(opt::element(ima, 13) == 3);
+ mln_assertion(opt::element(ima, 14) == 2);
+ mln_assertion(opt::element(ima, 15) == 1);
+ mln_assertion(opt::element(ima, 16) == 1);
+ mln_assertion(opt::element(ima, 17) == 2);
+ mln_assertion(opt::element(ima, 18) == 3);
+ mln_assertion(opt::element(ima, 19) == 3);
+ mln_assertion(opt::element(ima, 20) == 2);
+ mln_assertion(opt::element(ima, 21) == 5);
+ mln_assertion(opt::element(ima, 22) == 4);
+ mln_assertion(opt::element(ima, 23) == 4);
+ mln_assertion(opt::element(ima, 24) == 5);
+ mln_assertion(opt::element(ima, 25) == 6);
+ mln_assertion(opt::element(ima, 26) == 6);
+ mln_assertion(opt::element(ima, 27) == 5);
+ mln_assertion(opt::element(ima, 28) == 4);
+ mln_assertion(opt::element(ima, 29) == 4);
+ mln_assertion(opt::element(ima, 30) == 4);
+ mln_assertion(opt::element(ima, 31) == 5);
+ mln_assertion(opt::element(ima, 32) == 6);
+ mln_assertion(opt::element(ima, 33) == 6);
+ mln_assertion(opt::element(ima, 34) == 6);
+ mln_assertion(opt::element(ima, 35) == 4);
+ mln_assertion(opt::element(ima, 36) == 4);
+ mln_assertion(opt::element(ima, 37) == 1);
+ mln_assertion(opt::element(ima, 38) == 2);
+ mln_assertion(opt::element(ima, 39) == 3);
+ mln_assertion(opt::element(ima, 40) == 6);
+ mln_assertion(opt::element(ima, 41) == 6);
}
Index: tests/border/fill.cc
--- tests/border/fill.cc (revision 3178)
+++ tests/border/fill.cc (working copy)
@@ -34,6 +34,7 @@
#include <mln/core/image/image2d.hh>
#include <mln/value/int_u8.hh>
#include <mln/debug/println_with_border.hh>
+#include <mln/opt/element.hh>
using namespace mln;
@@ -48,11 +49,11 @@
border::fill (ima, 42);
for(int i = 0; i < ww; ++i)
if ((i / w < border) || (i / w > border + size))
- mln_assertion (ima.element(i) == 42u);
+ mln_assertion (opt::element(ima, i) == 42u);
else
if ((i % w < border) &&
(border + size <= i % w))
- mln_assertion (ima.element(i) == 42u);
+ mln_assertion (opt::element(ima, i) == 42u);
}
int
1
0
21 Jan '09
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Fix mln mean. mln_sum(T) MUST be divisible by unsigned.
* mln/accu/mean.hh: Fix here.
mean.hh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: mln/accu/mean.hh
--- mln/accu/mean.hh (revision 3177)
+++ mln/accu/mean.hh (working copy)
@@ -150,7 +150,7 @@
M
mean<T,S,M>::to_result() const
{
- S n = static_cast<S>(count_.to_result());
+ unsigned n = count_.to_result();
return static_cast<M>(sum_.to_result() / n);
}
1
0