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.