
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Make room for INIM 2011 and store 2009 stuff. * inim/2011: New directory. * inim/2009: New directory. * inim/ocr, * inim/classif, * inim/binarization, * inim/color, * inim/nature: Move to... * inim/2009/ocr, * inim/2009/classif, * inim/2009/binarization, * inim/2009/color, * inim/2009/nature: ...these new directories. * inim/ocr/resize.hh, * inim/ocr/ocr_without_preprocess.cc, * inim/ocr/skeleton.old.hh, * inim/ocr/simple_point.hh, * inim/ocr/skeleton.hh, * inim/ocr/check_simple_point.cc, * inim/ocr/compute_local_configurations.cc, * inim/ocr/tesseract_wrap.hh, * inim/ocr/skeleton.old.cc, * inim/ocr/check.sh, * inim/ocr/simple_point.cc, * inim/ocr/ocr_with_preprocess.cc, * inim/ocr/enlarge.hh, * inim/ocr/Makefile, * inim/classif/plotscript, * inim/classif/src, * inim/classif/src/max_tree.hh, * inim/classif/src/display.hh, * inim/classif/src/iccvg04.cc, * inim/classif/src/proj.hh, * inim/classif/src/v2.cc, * inim/classif/Makefile, * inim/binarization/proof-of-concept, * inim/binarization/proof-of-concept/build, * inim/binarization/proof-of-concept/build/configure.in, * inim/binarization/proof-of-concept/build/Makefile, * inim/binarization/proof-of-concept/configure, * inim/binarization/proof-of-concept/configure.in, * inim/binarization/proof-of-concept/scripts, * inim/binarization/proof-of-concept/scripts/init_tar.sh, * inim/binarization/proof-of-concept/scripts/flower, * inim/binarization/proof-of-concept/scripts/todo.sh, * inim/binarization/proof-of-concept/src, * inim/binarization/proof-of-concept/src/gradient.cc, * inim/binarization/proof-of-concept/src/util.hxx, * inim/binarization/proof-of-concept/src/basic.cc, * inim/binarization/proof-of-concept/src/snake2d.hh, * inim/binarization/proof-of-concept/ChangeLog, * inim/binarization/proof-of-concept/check, * inim/binarization/proof-of-concept/check/graph.sh, * inim/binarization/proof-of-concept/check/histo.gp, * inim/binarization/proof-of-concept/check/Makefile, * inim/binarization/proof-of-concept/Makefile, * inim/binarization/snake2d.hh, * inim/binarization/binarization.hh, * inim/binarization/snake2d.cc, * inim/binarization/binarization.cc, * inim/color/min_tree_volume_filter.cc, * inim/color/reference.cc, * inim/color/min_tree_area_filter.cc, * inim/color/min_tree_height_filter.cc, * inim/color/min_tree_color.cc, * inim/color/reference2.cc, * inim/color/src, * inim/color/src/graph.hh, * inim/color/src/io.hh, * inim/color/src/distance.hh, * inim/color/src/convert.hh, * inim/color/min_tree_color_v2.cc, * inim/color/laplacien.cc, * inim/color/README, * inim/nature/gradient.cc, * inim/nature/erosion.cc, * inim/nature/mco.cc, * inim/nature/closing.cc, * inim/nature/nature.cc, * inim/nature/opening.cc, * inim/nature/fft.cc, * inim/nature/co_occurence.hh, * inim/nature/hom.cc, * inim/nature/proj.hh, * inim/nature/test.sh, * inim/nature/Makefile, * inim/nature/histo_hsi.cc, * inim/nature/proj.cc: Respectively move... * inim/2009/ocr, * inim/2009/classif, * inim/2009/binarization, * inim/2009/color, * inim/2009/nature: ...here. binarization/binarization.cc | 36 - binarization/binarization.hh | 78 -- binarization/proof-of-concept/ChangeLog | 69 -- binarization/proof-of-concept/Makefile | 87 --- binarization/proof-of-concept/build/Makefile | 79 -- binarization/proof-of-concept/build/configure.in | 5 binarization/proof-of-concept/check/Makefile | 71 -- binarization/proof-of-concept/check/graph.sh | 27 binarization/proof-of-concept/check/histo.gp | 19 binarization/proof-of-concept/configure | 264 --------- binarization/proof-of-concept/configure.in | 26 binarization/proof-of-concept/scripts/flower | 33 - binarization/proof-of-concept/scripts/init_tar.sh | 14 binarization/proof-of-concept/scripts/todo.sh | 26 binarization/proof-of-concept/src/basic.cc | 75 -- binarization/proof-of-concept/src/gradient.cc | 109 --- binarization/proof-of-concept/src/snake2d.hh | 190 ------ binarization/proof-of-concept/src/util.hxx | 97 --- binarization/snake2d.cc | 39 - binarization/snake2d.hh | 190 ------ classif/Makefile | 87 --- classif/plotscript | 4 classif/src/display.hh | 80 -- classif/src/iccvg04.cc | 171 ------ classif/src/max_tree.hh | 312 ----------- classif/src/proj.hh | 139 ---- classif/src/v2.cc | 178 ------ color/README | 83 -- color/laplacien.cc | 130 ---- color/min_tree_area_filter.cc | 515 ------------------ color/min_tree_color.cc | 536 ------------------- color/min_tree_color_v2.cc | 533 ------------------- color/min_tree_height_filter.cc | 553 ------------------- color/min_tree_volume_filter.cc | 551 ------------------- color/reference.cc | 557 -------------------- color/reference2.cc | 408 -------------- color/src/convert.hh | 37 - color/src/distance.hh | 52 - color/src/graph.hh | 62 -- color/src/io.hh | 57 -- nature/Makefile | 24 nature/closing.cc | 61 -- 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 | 316 ----------- nature/mco.cc | 48 - nature/nature.cc | 499 ----------------- nature/opening.cc | 61 -- nature/proj.cc | 68 -- nature/proj.hh | 64 -- nature/test.sh | 11 ocr/Makefile | 26 ocr/check.sh | 31 - ocr/check_simple_point.cc | 61 -- ocr/compute_local_configurations.cc | 74 -- ocr/enlarge.hh | 202 ------- ocr/ocr_with_preprocess.cc | 170 ------ ocr/ocr_without_preprocess.cc | 90 --- ocr/resize.hh | 96 --- ocr/simple_point.cc | 39 - ocr/simple_point.hh | 206 ------- ocr/skeleton.hh | 200 ------- ocr/skeleton.old.cc | 30 - ocr/skeleton.old.hh | 612 ---------------------- ocr/tesseract_wrap.hh | 91 --- 68 files changed, 10098 deletions(-) Index: inim/ocr/resize.hh --- inim/ocr/resize.hh (revision 3756) +++ inim/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: inim/ocr/ocr_without_preprocess.cc --- inim/ocr/ocr_without_preprocess.cc (revision 3756) +++ inim/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: inim/ocr/skeleton.old.hh --- inim/ocr/skeleton.old.hh (revision 3756) +++ inim/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: inim/ocr/simple_point.hh --- inim/ocr/simple_point.hh (revision 3756) +++ inim/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, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, - 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, - 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, - 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, - - 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2, - 2, 2, 3, 3, 2, 2, 2, 2, 3, 3, 4, 3, 3, 3, 3, 2, - 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, - 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 1, - - 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, - 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, - 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, - 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, - - 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 2, 2, 2, 3, 2, - 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, - 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, - 1, 1, 2, 2, 1, 1, 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: inim/ocr/skeleton.hh --- inim/ocr/skeleton.hh (revision 3756) +++ inim/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: inim/ocr/check_simple_point.cc --- inim/ocr/check_simple_point.cc (revision 3756) +++ inim/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: inim/ocr/compute_local_configurations.cc --- inim/ocr/compute_local_configurations.cc (revision 3756) +++ inim/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: inim/ocr/tesseract_wrap.hh --- inim/ocr/tesseract_wrap.hh (revision 3756) +++ inim/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: inim/ocr/skeleton.old.cc --- inim/ocr/skeleton.old.cc (revision 3756) +++ inim/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: inim/ocr/check.sh --- inim/ocr/check.sh (revision 3756) +++ inim/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: inim/ocr/simple_point.cc --- inim/ocr/simple_point.cc (revision 3756) +++ inim/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: inim/ocr/ocr_with_preprocess.cc --- inim/ocr/ocr_with_preprocess.cc (revision 3756) +++ inim/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: inim/ocr/enlarge.hh --- inim/ocr/enlarge.hh (revision 3756) +++ inim/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: inim/ocr/Makefile --- inim/ocr/Makefile (revision 3756) +++ inim/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 Index: inim/classif/plotscript --- inim/classif/plotscript (revision 3756) +++ inim/classif/plotscript (working copy) @@ -1,4 +0,0 @@ -set xlabel "red" -set ylabel "green" -set zlabel "blue" -splot "plot" Index: inim/classif/src/max_tree.hh --- inim/classif/src/max_tree.hh (revision 3756) +++ inim/classif/src/max_tree.hh (working copy) @@ -1,312 +0,0 @@ -#ifndef MAX_TREE_HH_ -# define MAX_TREE_HH_ - -# include <mln/core/concept/image.hh> -# include <mln/core/concept/neighborhood.hh> -# include <mln/data/fill.hh> -# include <mln/util/pix.hh> -# include <mln/morpho/includes.hh> -# include <mln/level/sort_psites.hh> - -# include <mln/core/image/image2d.hh> -# include <mln/core/image/image3d.hh> -# include <mln/core/alias/neighb2d.hh> -# include <mln/value/int_u8.hh> -# include <mln/value/rgb8.hh> -# include <mln/io/pgm/load.hh> -# include <mln/core/site_set/p_array.hh> -# include <mln/debug/println.hh> -# include <mln/io/ppm/save.hh> - -using namespace mln; - -template <typename I, typename N> -struct max_tree_ -{ - typedef mln_site(I) point; - typedef p_array<point> S; - - // in: - const I& f; - const N& nbh; - - // aux: - S s; - mln_ch_value(I, bool) deja_vu; - mln_ch_value(I, point) parent; - mln_ch_value(I, point) new_parent; - mln_ch_value(I, point) zpar; - - //tags - image3d<bool> is_active; - - max_tree_(const I& f, const N& nbh) - : f(f), nbh(nbh), is_active(f.domain()), new_parent(f.domain()) - { - run(); - data::fill(is_active, true); - - new_parent = parent; - } - - void run() - { - // init - { - initialize(deja_vu, f); - mln::data::fill(deja_vu, false); - initialize(parent, f); - initialize(zpar, f); - s = level::sort_psites_decreasing(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); - } - } - - } // end of run() - - point active_parent(const point& p) - { - point node = new_parent(p); - - while (not is_active(node) && not is_root(node)) - node = new_parent(node); - - return node; - } - - void make_set(const point& p) - { - parent(p) = p; - zpar(p) = p; - } - - image3d<unsigned> compute_nb_represent() - { - image3d<unsigned> nb_represent(f.domain()); - - data::fill(nb_represent, 0); - mln_fwd_piter(S) p(s); - - for_all(p) - { - nb_represent(p) += f(p); - if (not is_root(p)) - nb_represent(parent(p)) += nb_represent(p); - } - - return nb_represent; - } - - image3d<unsigned> compute_volume() - { - image3d<unsigned> volume(f.domain()); - - data::fill(volume, 0); - mln_fwd_piter(S) p(s); - - for_all(p) - { - volume(p) += 1; - if (not is_root(p)) - volume(parent(p)) += volume(p); - } - - return volume; - } - - image3d< algebra::vec<3, double> > compute_mean_color() - { - image3d< algebra::vec<3, double> > mean_color(f.domain()); - - update_parents(); - - mln_fwd_piter(S) p(s); - for_all(p) - mean_color(p) = make::vec(p[0], p[1], p[2]); - - for_all(p) - mean_color(new_parent(p)) = (mean_color(new_parent(p)) + mean_color(p)) / 2.; - - return mean_color; - } - - // Filter method - template<typename X> - void lumberjack(const X& ima, const mln_value(X)& lambda) - { - unsigned progress = 0; - unsigned step = s.nsites() / 100; - - mln_fwd_piter(S) p(s); - - for_all(p) - { - if (ima(p) < lambda) - is_active(p) = false; - - ++progress; - if (progress % step == 0) - { - std::cout << "." << std::flush; - progress = 0; - } - } - - std::cout << std::endl; - } - - // Fusion method - template<typename X> - void nuclear_fusion(const X& ima, double lambda) - { - unsigned progress = 0; - unsigned step = s.nsites() / 100; - - update_parents(); - - mln_fwd_piter(S) p(s); - for_all(p) - { - if (ima(p) != 0) - if (fabs(1. - ima(new_parent(p)) / (double) ima(p)) < lambda) - is_active(p) = false; - - ++progress; - if (progress % step == 0) - { - std::cout << "." << std::flush; - progress = 0; - } - } - - std::cout << std::endl; - } - - void color_fusion(int lambda) - { - unsigned progress = 0; - unsigned step = s.nsites() / 100; - - update_parents(); - - mln_fwd_piter(S) p(s); - for_all(p) - { - if (new_parent(p)[0] - p[0] < lambda && - new_parent(p)[1] - p[1] < lambda && - new_parent(p)[2] - p[2] < lambda) - is_active(p) = false; - - ++progress; - if (progress % step == 0) - { - std::cout << "." << std::flush; - progress = 0; - } - } - std::cout << std::endl; - } - - void update_parents() - { - unsigned progress = 0; - unsigned step = s.nsites() / 100; - - std::cout << "Update parents"; - - mln_fwd_piter(S) p(s); - for_all(p) - { - new_parent(p) = active_parent(p); - - ++progress; - if (progress % step == 0) - { - std::cout << "." << std::flush; - progress = 0; - } - } - std::cout << std::endl; - } - - template < typename J > - void to_ppm(const J& ima, const std::string& file, unsigned f, - const image3d< algebra::vec<3, double> >& mean_color) - { - update_parents(); - - J out(ima.domain()); - data::fill(out, value::rgb8(0, 0, 0)); - - mln_piter(J) p(ima.domain()); - for_all(p) - { - point3d node = new_parent(point3d(ima(p).red() / f, ima(p).green() / f, ima(p).blue() / f)); - - out(p) = value::rgb8(static_cast<unsigned char>(mean_color(node)[0] * f), - static_cast<unsigned char>(mean_color(node)[1] * f), - static_cast<unsigned char>(mean_color(node)[2] * f)); - } - - io::ppm::save(out, file); - } - - unsigned number_of_nodes() - { - return s.nsites(); - } - - 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); - } - - point find_root(const point& x) - { - if (zpar(x) == x) - return x; - else - return zpar(x) = find_root(zpar(x)); - } - - void do_union(const point& n, const point& p) - { - point r = find_root(n); - if (r != p) - { - parent(r) = p; - zpar(r) = p; - } - } -}; - - -#endif /* !MAX_TREE_HH_ */ Index: inim/classif/src/display.hh --- inim/classif/src/display.hh (revision 3756) +++ inim/classif/src/display.hh (working copy) @@ -1,80 +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__DISPLAY_HH -# define MLN__DISPLAY_HH - -#include <mln/io/ppm/save.hh> -#include <mln/geom/nrows.hh> -#include <mln/geom/ncols.hh> -#include <mln/geom/nslis.hh> -#include <mln/value/all.hh> -#include <mln/core/image/image3d.hh> -#include <mln/literal/colors.hh> - -#include <sys/stat.h> -#include <sstream> -#include <string.h> -#include <stdlib.h> - - -namespace mln -{ - - template <typename I, typename J, typename K> - void display(const I& histo, const J& ws, K mean, const char * dir) - { - mkdir(dir, 0777); - chdir(dir); - - image2d< value::rgb8 > out(geom::nrows(histo), geom::ncols(histo)); - data::fill(out, literal::white); - - for (int s = 0; s < geom::nslis(histo); ++s) - { - for (int r = 0; r < geom::nrows(histo); ++r) - for (int c = 0; c < geom::ncols(histo); ++c) - if (histo(point3d(s,r,c)) > 0) - { - if (ws(point3d(s,r,c)) > 0) - out(point2d(r, c)) = convert::to<value::rgb8>(mean[ws(point3d(s,r,c))]); - else - out(point2d(r, c)) = literal::red; - } - - std::ostringstream is; - is << "out_00" << s << ".ppm"; - io::ppm::save(out, is.str()); - } - - chdir(".."); - } - -} // end of namespace mln - -#endif /* MLN__DISPLAY_HH */ - Index: inim/classif/src/iccvg04.cc --- inim/classif/src/iccvg04.cc (revision 3756) +++ inim/classif/src/iccvg04.cc (working copy) @@ -1,171 +0,0 @@ -#include <iostream> - -#include <mln/core/image/image2d.hh> -#include <mln/core/image/image3d.hh> -#include <mln/value/all.hh> - -#include <mln/data/fill.hh> - -#include <mln/morpho/closing_volume.hh> -#include <mln/morpho/closing_area.hh> -#include <mln/morpho/opening_volume.hh> -#include <mln/morpho/opening_area.hh> - -#include <mln/arith/revert.hh> -#include <mln/morpho/meyer_wst.hh> -#include <mln/core/alias/neighb3d.hh> -#include <mln/util/array.hh> -#include <mln/labeling/compute.hh> - -#include <mln/geom/nrows.hh> -#include <mln/geom/ncols.hh> -#include <mln/geom/nslis.hh> - -#include <mln/io/ppm/load.hh> -#include <mln/io/pgm/save.hh> -#include <mln/io/ppm/save.hh> - -#include <mln/estim/min_max.hh> -#include <mln/algebra/vec.hh> -#include <mln/algebra/vec.hh> - -#include <mln/literal/all.hh> - -#include <mln/level/stretch.hh> - -#include <sys/stat.h> -#include <sstream> -#include <string.h> -#include <stdlib.h> - -#include "proj.hh" -#include "display.hh" - -using namespace mln; - -unsigned max = 0; - -template <typename I> -mln::image3d<unsigned> -fill_histo(const I& ima, int f) -{ - const value::int_u8 v = 255 / f; // FIXME - image3d<unsigned> histo(v,v,v); - data::fill(histo, 0); - - mln_piter(I) p(ima.domain()); - for_all(p) - { - point3d p3(ima(p).red() / f, ima(p).green() / f, ima(p).blue() / f); - histo(p3)++; - } - return histo; -} - -template <typename I> -void gplot(const I& ima) -{ - mln_piter(I) p(ima.domain()); - for_all(p) - { - if (ima(p) != 0) - std::cout << p[0] << ' ' << p[1] << ' ' << p[2] << std::endl; - } -} - -template <typename I, typename J, typename K> -void -classify_image(const I& ima, const J& histo, const K& ws, int nbasins, int f) -{ - unsigned border = 0; - unsigned count[nbasins + 1]; - memset(count, 0, (nbasins + 1) * sizeof (unsigned)); - - algebra::vec<3, double> sum[nbasins + 1]; - for (int i = 0; i < nbasins + 1; ++i) - sum[i] = literal::zero; - - // Compute representatives of every class - mln_piter(I) p(ima.domain()); - for_all(p) - { - point3d p3(ima(p).red() / f, ima(p).green() / f, ima(p).blue() / f); - int w = ws(p3); - - //Even if we are not on a border of the WS - count[w] += histo(p3); - sum[w] += histo(p3) * convert::to< algebra::vec<3, value::int_u8> >(p3); - - std::cerr << "p3 : " << p3 << " == " << - convert::to<algebra::vec<3, value::int_u8> >(p3) << std::endl; - } - - std::cout << "dyke point : " << count[0] << std::endl; - for (int i = 0; i < nbasins + 1; ++i) - { - std::cout << "sum[" << i << "] = " << sum[i] * f << " / " << count[i] << " == "; - sum[i] = (sum[i] * f) / count[i]; - std::cout << sum[i] << std::endl; - } - - // Make an output image where colors are replaced by their representatives. - mln_piter(I) pi(ima.domain()); - I out(ima.domain()); - for_all(pi) - { - //retrieve color class - value::rgb8 coul = ima(pi); - int w = ws(point3d(coul.red() / f, coul.green() / f, coul.blue() / f)); - - //if w == 0, out(pi) = 0 ie is part of a border of the watershed - if (w == 0) - out(pi) = literal::red; - else - out(pi) = convert::to<value::rgb8>(sum[w]); - - std::cerr << "out(" << pi << ") = sum[" << w << "]; //" - << sum[w] << " : rgb8(" << sum[w] << ")" << std::endl; - } - - io::ppm::save(out, "out.ppm"); - save_class(histo, ws, sum, "palette.ppm"); - display(histo, ws, sum, "histo"); -} - -bool usage(int argc, char ** argv) -{ - if (argc != 4) - { - std::cout << "usage: " << argv[0] << " image div_factor lambda" << std::endl; - return false; - } - return true; -} - - -int main(int argc, char **argv) -{ - if (not usage(argc, argv)) - return 1; - const int div_factor = atoi(argv[2]); - const int lambda = atoi(argv[3]); - - image2d<value::rgb8> ima; - ima = io::ppm::load<value::rgb8>(argv[1]); - - //make histo - image3d<unsigned> histo = fill_histo(ima,div_factor); - - //compute opening_volume of histo - image3d<unsigned> histo_filtered; - histo_filtered = morpho::opening_volume(histo, c6(), lambda); - - //watershed over histo_closure - unsigned nbasins = 0; - image3d<unsigned> ws = morpho::meyer_wst(arith::revert(histo_filtered), - c6(), nbasins); - std::cout << "nbassins : " << nbasins << std::endl; - - //classify image - classify_image(ima, histo, ws, nbasins, div_factor); -} Index: inim/classif/src/proj.hh --- inim/classif/src/proj.hh (revision 3756) +++ inim/classif/src/proj.hh (working copy) @@ -1,139 +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/ppm/save.hh> -#include <mln/io/pgm/save.hh> -#include <mln/data/paste.hh> -#include <mln/accu/mean.hh> -#include <mln/accu/maj_h.hh> -#include <mln/literal/white.hh> -#include <mln/literal/colors.hh> -#include <mln/make/vec.hh> -#include <mln/opt/at.hh> - -namespace mln -{ - - template <typename T, typename A> - image2d<mln_result(A)> - proj(const image3d<T>& input, A) - { - image2d<A> acc(geom::nslis(input), geom::nrows(input)); - mln_piter(image3d<T>) p(input.domain()); - for_all(p) // 3d - if (input(p) != literal::zero) - opt::at(acc, p.sli(), p.row()).take(input(p)); - - image2d<mln_result(A)> output(acc.domain()); - data::paste(acc, output); - return output; - } - - template <typename T, typename U, typename K> - void - save_class(const image3d<T>& histo, const image3d<U>& ws, - K mean, const char * fn) - { - accu::maj_h<value::int_u8> maj_1; - image2d<value::int_u8> hproj = proj(histo, maj_1); - - accu::maj_h<value::int_u8> maj_2; - image2d<value::int_u8> proj_class = proj(ws, maj_2); - - //std::cout << histo; - - image2d<value::rgb8> out(proj_class.domain()); - data::fill(out, literal::white); - - mln_piter(image2d<value::int_u8>) p(proj_class.domain()); - for_all(p) - if (hproj(p) > 0) - { - if (proj_class(p) > 0) - out(p) = convert::to<value::rgb8>(mean[proj_class(p)]); - else - out(p) = literal::red; - } - io::ppm::save(out, fn); - } - - template <typename T, typename I, typename A> - image2d<mln_result(A)> - proj_vec(const image3d<T>& input, const I& histo, A) - { - image2d<A> acc(geom::nslis(input), geom::nrows(input)); - mln_piter(image3d<T>) p(input.domain()); - for_all(p) // 3d - if (histo(p) != literal::zero) - opt::at(acc, p.sli(), p.row()).take(input(p)); - - image2d<mln_result(A)> output(acc.domain()); - data::paste(acc, output); - return output; - } - - template <typename I, typename T, typename U, typename V> - void - save_class_v2(const I& ima, const T& histo, image3d<U>& mean, - const image3d<V>& parent, unsigned f, - const char * fn) - { - image3d<value::rgb8> out3d(histo.domain()); - - mln_piter(I) p(ima.domain()); - for_all(p) - { - point3d p3 = point3d(ima(p).red() / f, - ima(p).green() / f, - ima(p).blue() / f); - out3d(p3) = convert::to<value::rgb8>(mean(parent(p3))); - } - - //FIXME: maj_h implies set is finite, mx set is ordered - accu::mean<mln::algebra::vec<3u, float> > maj_2; - image2d<mln::algebra::vec<3u, float> > mproj = - proj_vec(out3d, histo, maj_2); - - image2d<value::rgb8> out(geom::nslis(histo), geom::nrows(histo)); - data::fill(out, literal::white); - - mln_piter(image2d<value::int_u8>) p1(out.domain()); - for_all(p1) - { - out(p1) = convert::to<value::rgb8>(mproj(p1)); - } - - io::ppm::save(out, fn); - } - -} // end of namespace mln - -#endif /* MLN_PROJ_HH */ - Index: inim/classif/src/v2.cc --- inim/classif/src/v2.cc (revision 3756) +++ inim/classif/src/v2.cc (working copy) @@ -1,178 +0,0 @@ -#include <mln/core/image/image2d.hh> -#include <mln/core/image/image3d.hh> - -#include <mln/value/all.hh> - -#include <mln/data/fill.hh> -#include <mln/geom/nrows.hh> -#include <mln/geom/ncols.hh> -#include <mln/geom/nslis.hh> - - -#include <mln/io/ppm/load.hh> -#include <mln/io/pgm/save.hh> -#include <mln/io/ppm/save.hh> - -#include <mln/arith/revert.hh> -#include <mln/core/alias/neighb3d.hh> - -#include "max_tree.hh" -#include "proj.hh" -#include "display.hh" - -using namespace mln; - -template <typename I> -mln::image3d<unsigned> -fill_histo(const I& ima, int f) -{ - const value::int_u8 v = 256 / f; // FIXME - image3d<unsigned> histo(v,v,v); - data::fill(histo, 0); - - mln_piter(I) p(ima.domain()); - for_all(p) - { - point3d p3(ima(p).red() / f, ima(p).green() / f, ima(p).blue() / f); - histo(p3)++; - } - return histo; -} - -template <typename I> -image3d< double > -compute_density(const I& weight, const I& volume) -{ - image3d< double > density(volume.domain()); - - mln_piter(I) p(volume.domain()); - for_all(p) - density(p) = weight(p) / volume(p); - - return density; -} - -template <typename I, typename J, typename N> -void -process_max_tree(const I& ima, const J& histo, const N& nbh, - double density_lambda, double value_lambda, - unsigned volume_lambda, unsigned nb_represent_lambda, - unsigned color_lambda, unsigned div_factor) -{ - max_tree_<J,N> run(histo, nbh); - - - // FIXME: write a compute() method with functor argument - image3d<unsigned> nb_represent = run.compute_nb_represent(); - image3d<unsigned> volume = run.compute_volume(); // surface (area) - image3d< algebra::vec<3, double> > mean_color = run.compute_mean_color(); - image3d<double> density = compute_density(nb_represent, volume); - - // Density fusion - if (density_lambda > 0.00001) - { - std::cout << "Density fusion" << std::endl; - run.nuclear_fusion(density, density_lambda); - } - - // value fusion - if (value_lambda > 0.00001) - { - std::cout << "Value fusion" << std::endl; - run.nuclear_fusion(histo, value_lambda); - } - - // Volume cutting - if (volume_lambda != 0) - { - std::cout << "Volume cutting" << std::endl; - run.lumberjack(volume, volume_lambda); - } - - // Represent cutting - if (nb_represent_lambda != 0) - { - std::cout << "nb_represent cutting" << std::endl; - run.lumberjack(nb_represent, nb_represent_lambda); - } - - // Color fusion - if (color_lambda != 0) - { - std::cout << "Color fusion" << std::endl; - run.color_fusion(color_lambda); // FIXME: factorize the code with a functor - } - - // Compute mean color of active nodes - std::cout << "Compute mean color" << std::endl; - run.compute_mean_color(); - - // Print informations on the filtered max tree - { - int nb_class = 0; - - mln_piter(image3d<unsigned>) p(nb_represent.domain()); - - std::cerr.precision(2); - - std::cerr << "Color\t\tId\t\tdensity\t\tvolume\t\tnb_represent" << std::endl; - - for_all(p) - if (run.is_active(p)) - { - std::cerr << mean_color(p) << "\t\t" << nb_class - << "\t\t" << density(p) << "\t\t" << volume(p) - << "\t\t" << nb_represent(p) << std::endl; - ++nb_class; - } - - std::cout << "Number of classes : " << nb_class << std::endl; - } - - - // Write the image w.r.t. the max tree - run.to_ppm(ima, "out.ppm", div_factor, mean_color); - - //proj - save_class_v2(ima, histo, mean_color, run.new_parent, - div_factor, "histo.ppm"); -} - -bool usage(int argc, char ** argv) -{ - if (argc != 8) - { - std::cout << "usage: " << argv[0] << " image div_factor " - << "density_lambda value_lambda volume_lambda " - << "nb_represent_lambda color_lambda" << std::endl; - std::cout << "Help: A value of 0 for any lambda means " - << "the related action won't be performed" << std::endl; - return false; - } - - return true; -} - -int main(int argc, char* argv[]) -{ - if (not usage(argc, argv)) - return 1; - - image2d<value::rgb8> ima; - - ima = io::ppm::load<value::rgb8>(argv[1]); - - int div_factor = atoi(argv[2]); - float density_lambda = atof(argv[3]); - float value_lambda = atof(argv[4]); - unsigned volume_lambda = atoi(argv[5]); - unsigned nb_represent_lambda = atoi(argv[6]); - unsigned color_lambda = atoi(argv[7]); - - //make histo - image3d<unsigned> histo = fill_histo(ima, div_factor); - - // Process max_tree - process_max_tree(ima, histo, c6(), density_lambda, value_lambda, - volume_lambda, nb_represent_lambda, color_lambda, div_factor); -} Index: inim/classif/Makefile --- inim/classif/Makefile (revision 3756) +++ inim/classif/Makefile (working copy) @@ -1,87 +0,0 @@ -DISP=xv - -# ICCVG -ICCVG_INCLUDES=-I../../.. -ICCVG_SRC=src/iccvg04.cc -ICCVG=iccvg -ICCVG_DBG=iccvg_dbg - -IMG?=../../img/lena.ppm -DIV?=4 -LAMBDA?=10 - -# V2 -V2_INCLUDES=-I../../.. -V2_SRC=src/v2.cc src/max_tree.hh -V2=v2 -V2_DBG=v2_dbg - - -LOG=> stdout.log 2> stderr.log - -all: $(ICCVG) $(V2) - -$(ICCVG): $(ICCVG_SRC) - g++ $(ICCVG_INCLUDES) -O1 -DNDEBUG $(ICCVG_SRC) -o $(ICCVG) - - -$(ICCVG_DBG): $(ICCVG_SRC) - g++ $(ICCVG_INCLUDES) -Wall -W -O0 -g3 -ggdb3 $(ICCVG_SRC) -o $(ICCVG_DBG) - -$(V2): $(V2_SRC) - g++ $(V2_INCLUDES) -O1 -DNDEBUG $(V2_SRC) -o $(V2) - - -$(V2_DBG): $(V2_SRC) .dep_v2 - g++ $(V2_INCLUDES) -Wall -W -O0 -g3 -ggdb3 $(V2_SRC) -o $(V2_DBG) - - -.PHONY:clean check check-debug valgrind .dep_iccvg .dep_v2 - -clean: - rm -f $(ICCVG) - rm -f $(ICCVG_DBG) - rm -f $(V2) - rm -f $(V2_DBG) - rm -f *.log - rm -f .dep_iccvg .dep_v2 .dep_iccvgr .dep_v2r - -check-debug: $(ICCVG_DBG) - ./iccvg_dbg $(IMG) $(DIV) $(LAMBDA) $(LOG) - cat stdout.log - $(DISP) out.ppm & - -check: $(ICCVG) - ./iccvg $(IMG) $(DIV) $(LAMBDA) $(LOG) - cat stdout.log - $(DISP) out.ppm & - -v2-check: $(V2) - ./v2 $(IMG) $(DIV) $(LAMBDA) $(LOG) - cat stdout.log - $(DISP) out.ppm & - -valgrind: $(ICCVG_DBG) - valgrind --log-file=valgrind.log ./iccvg_dbg ../../img/lena.ppm $(DIV) $(LAMBDA) $(LOG) - -gdb: $(ICCVG_DBG) - echo "run ../../img/lena.ppm $(DIV) $(LAMBDA)" > gdb.cmd - gdb $(ICCVG_DBG) -x gdb.cmd - -v2-gdb: $(V2_DBG) - echo "run ../../img/lena.ppm $(DIV) $(LAMBDA) $(LOG)" > gdb.cmd - gdb $(V2_DBG) -x gdb.cmd - - -.dep_iccvg: - g++ $(ICCVG_INCLUDES) -MM src/iccvg04.cc > $@ - @sed -ir s/iccvg04.cc// .dep_iccvg - @sed -ir s/iccvg04.o/iccvg/ .dep_iccvg - -.dep_v2: - g++ $(V2_INCLUDES) -MM src/v2.cc > $@ - @sed -ir s/v2.cc// .dep_v2 - @sed -ir s/v2.o/v2/ .dep_v2 - --include .dep_iccvg --include .dep_v2 Index: inim/binarization/proof-of-concept/build/configure.in --- inim/binarization/proof-of-concept/build/configure.in (revision 3756) +++ inim/binarization/proof-of-concept/build/configure.in (working copy) @@ -1,5 +0,0 @@ -## configure.in -## Made by nicuveo for owl - -CFIL1 = ../src/basic.cc -CFIL2 = ../src/gradient.cc Index: inim/binarization/proof-of-concept/build/Makefile --- inim/binarization/proof-of-concept/build/Makefile (revision 3756) +++ inim/binarization/proof-of-concept/build/Makefile (working copy) @@ -1,79 +0,0 @@ -## -## Makefile for owl -## Made by nicuveo <nicuveo@lrde.epita.fr> -## - -include Makefile.rules - - - -# VARIABLES - -EXE1 = ../bin/basic -EXE2 = ../bin/gradient - -OBJS1 = $(notdir $(CFIL1:.cc=.o)) -OBJS2 = $(notdir $(CFIL2:.cc=.o)) - -CFIL = $(sort $(CFIL1) $(CFIL2)) -OBJS = $(sort $(OBJS1) $(OBJS2)) -DEPS = $(notdir $(CFIL:.cc=.d)) - - - -# MAIN - -all: $(EXE1) $(EXE2) - -basic: $(EXE1) - -gradient : $(EXE2) - -clean: do_clean - -distclean: do_distclean - - - -# CLEAN - -do_clean: - rm -f $(OBJS) - -do_distclean: do_clean - rm -f $(EXE1) $(EXE2) $(DEPS) - rm -f Makefile.rules Makefile.deps tmp - - - -# COMPIL - -$(EXE1): $(OBJS1) - $(CC) $(OBJS1) $(LDFLAGS) -o $(EXE1) - -$(EXE2): $(OBJS2) - $(CC) $(OBJS2) $(LDFLAGS) -o $(EXE2) - -$(OBJS): - $(CC) $(CFLAGS) -c $< -o $@ - - - -# DEPS - -Makefile.deps: - rm -f $@ - @echo "-- Regenerating basic dependencies" - @for f in $(CFIL) ; do \ - echo "`basename $$f`: \\" | sed 's/\(.*\)\.cc/\1.d/' >> $@; \ - echo "$$f" >> $@ ; done - @echo "-include $(DEPS)" >> Makefile.deps - -$(DEPS): - @echo "$(CC) $(DEPFLAGS) $< > $@" - @$(CC) $(DEPFLAGS) $< -MT "$(@:.d=.o) $@" > tmp - @mv tmp $@ - - - -include Makefile.deps Index: inim/binarization/proof-of-concept/configure --- inim/binarization/proof-of-concept/configure (revision 3756) +++ inim/binarization/proof-of-concept/configure (working copy) @@ -1,264 +0,0 @@ -#!/bin/sh -## configure for inim -## Made by nicuveo <nicuveo@lrde.epita.fr> -## - - - -###################################################################### -## Vars - -base="" -block="" -nonbl="" -verbose="true" -profile="" -options="" -folders="" -os=`uname -s` -cc="cc" - - - -###################################################################### -## Extraction functions - -# Prepare file -getfile() -{ - expand "$1" | sed ':a -/\\$/N -s/ *\\\n */ / -ta -s/#.*$// -s/^ *// -/^$/d' -} - -# Get 'system' value -getsysvalue() -{ - getfile "$1" | sed -n "s/^$2: *//p" | tail -n 1 -} - -getvalue() -{ - gdef=`echo "$block" | sed -n "s/^$1 *= *//p" | tail -n 1` - gspe=`echo "$block" | sed -n "s/^$os@$1 *= *//p" | tail -n 1` - ndef=`echo "$nonbl" | sed -n "s/^$1 *= *//p" | tail -n 1` - nspe=`echo "$nonbl" | sed -n "s/^$os@$1 *= *//p" | tail -n 1` - - if [ -n "$gspe" ] ; then - echo "$gspe" - else - if [ -n "$gdef" ] ; then - echo "$gdef" - else - if [ -n "$nspe" ] ; then - echo "$nspe" - else - echo "$ndef" - fi - fi - fi -} - -# Get block -getblock() -{ - getfile "$1" | sed -n "/\[$2\]/,/\[.*\]/P" -} - -# Get non-block -getnonblock() -{ - getfile "$1" | sed -n '1,/\[.*\]/p' -} - - - -###################################################################### -## Init functions - -# Print usage -usage() -{ - echo "usage: configure [options] [profile name]" - echo "options:" - echo " -h : print this help" - echo " -q : disable verbose mode" - echo " -o arg: compilation options string" -} - -# getoptions -getoptions() -{ - while [ $# -ne 0 ] ; do - if [ -z "`echo "$1" | sed -n '/^-/P'`" ] ; then - if [ "$current" = "" ] ; then - profile="$1" - else - usage - echo "!!! you can provide only one profile name" - exit 1 - fi - else - case "$1" in - "-h") - usage - exit 0;; - "-q") - verbose="";; - "-o") - if [ $# -eq 1 ] ; then - usage - echo "!!! -o option takes a argument" - exit 3 - fi - shift - cfil="$1";; - *) - usage - echo "!!! $1 is not a valid option" - exit 2;; - esac - fi - shift - done -} - -# profile selection and test -getprofile() -{ - if [ -z "$profile" ] ; then - profile=`getsysvalue configure.in profile` - if [ -n "$verbose" ] ; then - echo "--- using default profile '$profile'" - fi - else - if [ -n "$verbose" ] ; then - echo "--- using profile '$profile'" - fi - fi - - if [ -z "`getblock configure.in "$profile"`" ] ; then - echo "!!! unknown profile '$profile'" - exit 4 - fi -} - -# init script -init() -{ - getoptions "$@" - getprofile - folders=`find ./*/ -name "configure.in" | sed 's/configure.in//'` - block=`getblock configure.in "$profile"` - nonbl=`getnonblock configure.in` - base="$PWD" -} - - - -###################################################################### -## Specific tasks - -# File header -print_header() -{ - echo "##" - echo "## $1" - echo "## generated with configure script" - echo "##" -} - -print_os () -{ - echo "" - echo "" - echo "## OS" - echo "OS = $os" -} - -print_rule() -{ - echo "" - echo "" - echo "## $1" - echo "$nonbl" | sed -n "s/^\($os@\)\{0,1\}$1 *\([:+]\{0,1\}=\) */$1 \2 /p" - echo "$block" | sed -n "s/^\($os@\)\{0,1\}$1 *\([:+]\{0,1\}=\) */$1 \2 /p" -} - -# Get compiler -checkcc() -{ - cc=`getvalue "CC"` - if [ -z "$cc" ] ; then - echo "!!! No compiler specified" - exit 5 - fi - if [ ! -x "`which "$cc" 2> /dev/null`" ] ; then - echo "!!! $cc is not a valid executable file" - exit 6 - fi - if [ -n "$verbose" ] ; then - echo "--- using '`which "$cc" 2> /dev/null`' as compiler" - fi -} - -# Extract all rules from file -createrules() -{ - for rule in `echo "$block -$nonbl" | sed -n 's/^ *\([^ ]\{1,\}\@\)\{0,1\}\([^ ]\{1,\}\) *[:+]\{0,1\}=.*$/\2/p'\ - | sort | uniq` ; do - print_rule "$rule" >> Makefile.rules - done -} - -# Copy Makefile -copymakefile() -{ - if [ -n "$verbose" ] ; then - echo ">>> $1/Makefile.rules" | tr -s '/' - fi - - block=`getblock configure.in "$profile"` - nonbl=`getnonblock configure.in` - createrules - - if [ -n "$verbose" ] ; then - echo ">>> Creating dependencies" - fi - rm -f Makefile.deps *.d > /dev/null 2>&1 - make -k Makefile.deps > /dev/null 2>&1 -} - - - -###################################################################### -## Code - -# Main function -main() -{ - checkcc - print_header "Makefile.rules" > Makefile.rules - print_os >> Makefile.rules - createrules ./ - - for folder in $folders ; do - cp Makefile.rules "$folder" 2> /dev/null - cd "$folder" - copymakefile "$folder" - cd "$base" - done - - if [ -n "$options" ] ; then - echo "CFLAGS += $options" >> Makefile.rules - fi -} - -# Calls -init "$@" -main Index: inim/binarization/proof-of-concept/configure.in --- inim/binarization/proof-of-concept/configure.in (revision 3756) +++ inim/binarization/proof-of-concept/configure.in (working copy) @@ -1,26 +0,0 @@ -## configure.in -## Made by nicuveo for inim - - - -## Configuration -profile: release - - -## Defaults -CC = g++ -CFLAGS = -W -Wall -Werror -ansi -I ../../../../.. -LDFLAGS = -DEPFLAGS = -I ../../../../.. -MM - -#Darwin@LDFLAGS := - - -## Debug -[debug] - CFLAGS += -Wextra -g -pg - LDFLAGS += -pg - -## Release -[release] - CFLAGS += -DNDEBUG -O1 Index: inim/binarization/proof-of-concept/scripts/init_tar.sh --- inim/binarization/proof-of-concept/scripts/init_tar.sh (revision 3756) +++ inim/binarization/proof-of-concept/scripts/init_tar.sh (working copy) @@ -1,14 +0,0 @@ -#! /bin/sh - -if [ $# -ne 1 ] ; then - echo "usage : init_tar.sh \"tarball_root_dir\"" - return 1 -fi -echo "rm -Rf $1" -rm -Rf "$1" -echo "mkdir $1 2> /dev/null" -mkdir "$1" 2> /dev/null -for file in `ls | grep -v $1` ; do - echo "ln -fs ../$file $1/$file" - ln -fs "../$file" "$1/$file" -done Index: inim/binarization/proof-of-concept/scripts/flower --- inim/binarization/proof-of-concept/scripts/flower (revision 3756) +++ inim/binarization/proof-of-concept/scripts/flower (working copy) @@ -1,33 +0,0 @@ - .... - ,;;'''';;, ,;;;;, - , ;;' `;;, .,;;;' ; - ,;;; ;; `;;,';;;,. ,%;;' ' - ,;;,;; ;; ,;`;;;, `;::. %%;' - ;;;,;;; `' ,;;; ;;,;;, `::,%%;' - ;;;,;;;, .,%%%%%'% ;;;;,;; %;;; - ,%,. `;;;,;;;, .,%%%%%%%%%'%; ;;;;;,;; %;;; - ;,`%%%%%%%%%%`;;,;;'%%%%%%%%%%%%%'%%' `;;;;;,;, %;;; - ;;;,`%%%%%%%%%%%,; ..`%%%%%%%%;'%%%' `;;;;,;; %%;; - `;;;;;,`%%%%%,;;/, .. `"""'',%%%%% `;;;;;; %%;;, - `;;;;;;;,;;/////,. ,;%%%%%%% `;;;;,`%%;; - ;;;/%%%%,%///;;;';%%%%%%, `;;;%%;;, - ;;;/%%%,%%%%%/;;;';;'%%%%%, `%%;; - .;;/%%,%%%%%//;;' ;;;'%%%%%, %%;;, - ;;//%,%%%%//;;;' `;;;;'%%%% `%;;; - ;;//%,%//;;;;' `;;;;'%%% %;;;, - `;;//,/;;;' `;;;'%%' `%;;; - `;;;;' `;'%' `;;;; - ' .,,,. `;;;; - ,;;;;;;;;;;, `;;;; - ;;;' ;;;,;;, `;;;; - ;;; ;;;;,;;. `;;;; - `;; ;;;;;,;; ;;;; - `' `;;;;,;; ;;;; - `;;,;, ;;;; - ;;, ;;;; - ';;;;; - ;;;;; - .;;;;' - .;;;;' - ;;;;;' - ,;;;;' Index: inim/binarization/proof-of-concept/scripts/todo.sh --- inim/binarization/proof-of-concept/scripts/todo.sh (revision 3756) +++ inim/binarization/proof-of-concept/scripts/todo.sh (working copy) @@ -1,26 +0,0 @@ -#! /bin/sh - -IFS=" -" -KEYWORD="TODO -FIXME" - -print () -{ - for k in $KEYWORD ; do - for line in `find src -type f | fgrep -v ".svn" | xargs fgrep -nH $k` ; do - info=`echo $line | sed 's/\([^:]*\):\([^:]*\):[ ]*\(.*\)/in \1 at line \2:/'` - text=`echo $line | sed 's/\([^:]*\):\([^:]*\):[ ]*\(.*\)/\3/'` - size=`echo $info | wc -c` - - void="" - for i in `seq $size 80` ; do - void="$void " - done - - echo "$info$void$text" - done - done -} - -print | sort Index: inim/binarization/proof-of-concept/src/gradient.cc --- inim/binarization/proof-of-concept/src/gradient.cc (revision 3756) +++ inim/binarization/proof-of-concept/src/gradient.cc (working copy) @@ -1,109 +0,0 @@ -// -// main.cc for INIM -// Made by nicuveo <crucuny@gmail.com> -// - - - -//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH -// Includes - -#include <cassert> -#include <string> -#include <vector> - -#include <mln/core/image/image2d.hh> -#include <mln/histo/all.hh> -#include <mln/io/pgm/all.hh> -#include <mln/accu/histo.hh> -#include <mln/arith/revert.hh> -#include <mln/convert/to_image.hh> -#include <mln/morpho/meyer_wst.hh> -#include <mln/core/alias/neighb1d.hh> -#include <mln/core/alias/window2d.hh> -#include <mln/geom/all.hh> -#include <mln/morpho/closing_area.hh> -#include <mln/morpho/gradient.hh> -#include <mln/data/fill.hh> -#include <mln/opt/at.hh> - -// DEBUG -#include <mln/debug/all.hh> - -#include <cmath> - -#include "util.hxx" - - - -//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH -// Implementation - -template <int P, int Q> -double -strength_of (mln::value::int_u8 x) -{ - double xprime = 1 - pow (x / 255., P); - - return 255 * log10 (1 + 9 * xprime); -} - -template <int P> -double -strength_of (mln::value::int_u8 x) -{ - return strength_of<P, 1> (x); -} - -int -main (int argc, char** argv) -{ - using namespace mln; - - if (argc != 5) - return 1; - std::string file_in = argv[1]; - std::string file_out = argv[2]; - std::string file_hist = argv[3]; - std::istringstream is(argv[4]); - int strength; - is >> strength; - - image2d<value::int_u8> in; - image2d<value::int_u8> grad; - image1d<unsigned long> hist(256); - image1d<unsigned long> hist_close(256); - - io::pgm::load (in, file_in); - - initialize(grad, in); - grad = morpho::gradient(in, win_c4p()); - - data::fill(hist, 0); - image2d<value::int_u8>::fwd_piter p (in.domain ()); - for_all (p) - opt::at(hist, in(p)) += (unsigned) strength_of<2> (grad (p)); - - // Histo - print_histo (hist, file_hist + "_1.histo"); - - hist = arith::revert(hist); - morpho::closing_area(hist, c2(), strength, hist_close); - - // Closed reverted histo - print_histo (arith::revert(hist_close), file_hist + "_2.histo"); - - image1d<size_t> wst = morpho::meyer_wst<size_t, image1d<unsigned long>, neighb1d> (hist_close, c2()); - std::vector<value::int_u8> colors = colors_init (wst); - - image2d<value::int_u8> cla; - initialize(cla, in); - - image2d<value::int_u8>::fwd_piter q (in.domain ()); - for_all (q) - cla (q) = colors_match (colors, in (q)); - - image2d<value::int_u8> out = binarization(cla, 20); - - mln::io::pgm::save (out, file_out); -} Index: inim/binarization/proof-of-concept/src/util.hxx --- inim/binarization/proof-of-concept/src/util.hxx (revision 3756) +++ inim/binarization/proof-of-concept/src/util.hxx (working copy) @@ -1,97 +0,0 @@ -// -// util.hxx for inim -// Made by nicuveo <crucuny@gmail.com> -// - -#ifndef UTIL_HXX_ -# define UTIL_HXX_ - - - -//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH -// Includes - -# include <cassert> -# include <string> -# include <vector> - -# include <mln/core/image/image2d.hh> -# include <mln/core/image/image1d.hh> -# include <mln/value/all.hh> -# include <mln/accu/maj_h.hh> -# include <mln/border/resize.hh> -# include <mln/win/rectangle2d.hh> -# include "snake2d.hh" - - - -//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH -// Declarations - -std::vector<mln::value::int_u8> -colors_init (const mln::image1d<size_t>& wst) -{ - std::vector<mln::value::int_u8> res; - mln::image1d<size_t>::fwd_piter p (wst.domain ()); - - for_all (p) - { - if (wst (p) != 0) - continue; - - if (p[0] != 0) - { - res.push_back (p[0]); - } - } - - if (res.empty() || res.back () != 255u) - res.push_back (255u); - - return res; -} - -mln::value::int_u8 -colors_match (const std::vector<mln::value::int_u8>& vec, mln::value::int_u8 x) -{ - unsigned i; - - for (i = 0; i < vec.size (); ++i) - if (x <= vec[i]) - break; - - if (vec.size() == 1) - return (127); - return (i * 255) / (vec.size () - 1); -} - -template <typename T> -void -print_histo (const mln::image1d<T>& hist, const std::string& f) -{ - std::ofstream fo; - typename mln::image1d<T>::fwd_piter p (hist.domain ()); - - fo.open (f.c_str ()); - - for_all (p) - fo << p[0] << "\t" << hist (p) << std::endl; - - fo.close (); -} - -mln::image2d<mln::value::int_u8> -binarization(mln::image2d<mln::value::int_u8>& input, int size) -{ - mln::image2d<mln::value::int_u8> output; - initialize(output, input); - - mln::border::resize(input, 0); - mln::image2d<mln::value::int_u8> maj = snake2d(mln::accu::maj_h<mln::value::int_u8>(), input, mln::win::rectangle2d(size,size)); - mln::image2d<mln::value::int_u8>::fwd_piter p (input.domain()); - for_all (p) - output(p) = (input(p) != maj(p)) * 255; - return output; -} - -#endif /* !UTIL_HH_ */ Index: inim/binarization/proof-of-concept/src/basic.cc --- inim/binarization/proof-of-concept/src/basic.cc (revision 3756) +++ inim/binarization/proof-of-concept/src/basic.cc (working copy) @@ -1,75 +0,0 @@ -// -// main.cc for INIM -// Made by nicuveo <crucuny@gmail.com> -// - - - -//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH -// Includes - -#include <mln/core/image/image2d.hh> -#include <mln/core/image/image1d.hh> -#include <mln/histo/all.hh> -#include <mln/io/pgm/all.hh> -#include <mln/value/all.hh> -#include <mln/accu/histo.hh> -#include <mln/arith/revert.hh> -#include <mln/convert/to_image.hh> -#include <mln/morpho/meyer_wst.hh> -#include <mln/core/alias/neighb1d.hh> -#include <mln/geom/all.hh> -#include <mln/morpho/closing_area.hh> - -#include "util.hxx" - - - -//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH -// Implementation - -int -main (int argc, char** argv) -{ - using namespace mln; - - if (argc != 5) - return 1; - std::string file_in = argv[1]; - std::string file_out = argv[2]; - std::string file_hist = argv[3]; - std::istringstream is(argv[4]); - int strength; - is >> strength; - - image2d<value::int_u8> in; - - io::pgm::load (in, file_in); - histo::data<value::int_u8> histo = histo::compute (in); - - image1d<size_t> hist = convert::to_image (histo); - - // Histo - print_histo (hist, file_hist + "_1.histo"); - - image1d<size_t> hist_close; - initialize(hist_close, hist); - morpho::closing_area(arith::revert(hist), c2(), strength, hist_close); - - // Closed reverted histo - print_histo (arith::revert(hist_close), file_hist + "_2.histo"); - - image1d<size_t> wst = morpho::meyer_wst<size_t, image1d<size_t>, neighb1d> (hist_close, c2()); - std::vector<value::int_u8> colors = colors_init (wst); - - image2d<value::int_u8> cla; - initialize(cla, in); - - image2d<value::int_u8>::fwd_piter p (in.domain ()); - for_all (p) - cla (p) = colors_match (colors, in (p)); - - image2d<value::int_u8> out = binarization(cla, 20); - - mln::io::pgm::save (out, file_out); -} Index: inim/binarization/proof-of-concept/src/snake2d.hh --- inim/binarization/proof-of-concept/src/snake2d.hh (revision 3756) +++ inim/binarization/proof-of-concept/src/snake2d.hh (working copy) @@ -1,190 +0,0 @@ -#include <mln/core/alias/neighb2d.hh> -#include <mln/win/diff.hh> -#include <mln/win/shift.hh> -#include <mln/extension/adjust_fill.hh> -#include <mln/canvas/browsing/snake_generic.hh> - -namespace mln -{ - - template <typename I, typename W, typename A> - struct snake2d_functor - { - typedef snake2d_functor<I,W, A> self; - typedef void (self::*move_fun)(); - typedef mln_deduce(I, psite, delta) dpsite; - - const I& input; - const W& win; - mln_ch_value(I, mln_result(A)) output; - A accu; - - mln_psite(I) p; - - window2d - win_left_fwd, - win_right_fwd, - win_left_bkd, - win_right_bkd, - win_bot_up, - win_top_up, - win_bot_down, - win_top_down; - - mln_qiter(window2d) - q_l_fwd, - q_r_fwd, - q_l_bkd, - q_r_bkd, - q_top_up, - q_bot_up, - q_top_down, - q_bot_down; - - std::vector<move_fun> moves; - std::vector<dpsite> dps; - - snake2d_functor(const I& input, const W& win) - : input(input), - win(win), - accu(), - - win_left_fwd(win::shift(win, mln::left) - win), - win_right_fwd(win - win::shift(win, mln::left)), - win_left_bkd(win::shift(win_left_fwd, mln::right)), - win_right_bkd(win::shift(win_right_fwd, mln::right)), - - win_bot_up(win::shift(win, mln::down) - win), - win_top_up(win - win::shift(win, mln::down)), - win_bot_down(win::shift(win_bot_up, mln::up)), - win_top_down(win::shift(win_top_up, mln::up)), - - q_l_fwd(win_left_fwd, p), - q_r_fwd(win_right_fwd, p), - q_l_bkd(win_left_bkd, p), - q_r_bkd(win_right_bkd, p), - - q_top_up(win_top_up, p), - q_bot_up(win_bot_up, p), - q_top_down(win_top_down, p), - q_bot_down(win_bot_down, p), - - moves(3), - dps(3) - { - if (win_bot_up.size() + win_top_up.size() + - win_bot_down.size() + win_top_down.size() < - win_left_fwd.size() + win_right_fwd.size() + - win_left_bkd.size() + win_right_bkd.size()) - { - // Vertical snake - dps[0] = mln::right; - dps[1] = mln::down; - dps[2] = mln::up; - moves[0] = &self::right; - moves[1] = &self::down; - moves[2] = &self::up; - } - else - { - // Horizontal snake - dps[0] = mln::down; - dps[1] = mln::right; - dps[2] = mln::left; - moves[0] = &self::down; - moves[1] = &self::right; - moves[2] = &self::left; - } - } - - void init() - { - initialize(output, input); - accu.init(); - p = input.domain().pmin() - dps[0]; - mln_qiter(W) q(win, p); - for_all(q) - if (input.has(q)) - accu.take(input(q)); - p = input.domain().pmin(); - } - - void right() - { - for_all(q_l_fwd) - if (input.has(q_l_fwd)) - accu.untake(input(q_l_fwd)); - for_all(q_r_fwd) - if (input.has(q_r_fwd)) - accu.take(input(q_r_fwd)); - output(p) = accu; - } - - void left() - { - for_all(q_r_bkd) - if (input.has(q_r_bkd)) - accu.untake(input(q_r_bkd)); - for_all(q_l_bkd) - if (input.has(q_l_bkd)) - accu.take(input(q_l_bkd)); - output(p) = accu; - } - - void down() - { - for_all(q_top_down) - if (input.has(q_top_down)) - accu.untake(input(q_top_down)); - for_all(q_bot_down) - if (input.has(q_bot_down)) - accu.take(input(q_bot_down)); - output(p) = accu; - } - - void up() - { - for_all(q_bot_up) - if (input.has(q_bot_up)) - accu.untake(input(q_bot_up)); - for_all(q_top_up) - if (input.has(q_top_up)) - accu.take(input(q_top_up)); - output(p) = accu; - } - - }; - - template <typename A, typename I, typename W> - inline - mln_ch_value(I, mln_result(A)) - snake2d(const Accumulator<A>&, const Image<I>& input, const Window<W>& win) - { - trace::entering("accu::snake2d"); - - typedef snake2d_functor<I, W, A> F; - F f(exact(input), exact(win)); - canvas::browsing::snake_generic(f); - - trace::exiting("accu::snake2d"); - - return f.output; - } - - template <typename A, typename I, typename W> - inline - mln_ch_value(I, mln_accu_with(A, mln_value(I))::result) - snake2d(const Meta_Accumulator<A>&, const Image<I>& input, const Window<W>& win) - { - trace::entering("accu::snake2d"); - - typedef mln_accu_with(A, mln_value(I)) A_; - typedef snake2d_functor<I, W, A_> F; - F f(exact(input), exact(win)); - canvas::browsing::snake_generic(f); - - trace::exiting("accu::snake2d"); - return f.output; - } - -} // mln Index: inim/binarization/proof-of-concept/ChangeLog --- inim/binarization/proof-of-concept/ChangeLog (revision 3756) +++ inim/binarization/proof-of-concept/ChangeLog (working copy) @@ -1,69 +0,0 @@ -2008-11-01 Vivien Delmon <vivien.delmon@lrde.epita.fr> - - Add snake2d and apply it on the classified image. - * src/basic.cc: . - * src/gradient.cc: . - * src/snake2d.hh: New. - * src/util.hxx: . - -2008-10-31 Vivien Delmon <vivien.delmon@lrde.epita.fr> - - Fix bugs and improve histogram io. - * build/configure.in: . - * configure.in: . - * src/basic.cc: . - * src/gradient.cc: . - * src/util.cc: Remove. - * src/util.hh: Remove. - * src/util.hxx: New. - -2008-10-27 Vivien Delmon <vivien.delmon@lrde.epita.fr> - - Remove debug. - * src/gradient/gradient.cc: remove std::cout. - -2008-10-27 Vivien Delmon <vivien.delmon@lrde.epita.fr> - - Add gradient implementation. - * Makefile, - * configure, - * src/gradient/gradient.cc: do it. - -2008-10-27 Vivien Delmon <vivien.delmon@lrde.epita.fr> - - Update svn:ignore. - -2008-10-27 Vivien Delmon <vivien.delmon@lrde.epita.fr> - - Add kind of a real Makefile. - * Makefile: TC-11 Makefile. - * configure: New. - * main.cc: Remove. - * src/basic/basic.cc: New. - * src/basic: New. - * src/gradient/gradient.cc: New. - * src/gradient: New. - * src: New. - -2008-10-27 Vivien Delmon <vivien.delmon@lrde.epita.fr> - - Remove debug and make some cosmetic rewriting. - * main.cc: . - -2008-10-17 Vivien Delmon <vivien.delmon@lrde.epita.fr> - - Add - 1. - * main.cc: Fix - 1. - -2008-10-15 Vivien Delmon <vivien.delmon@lrde.epita.fr> - - Add closing area. - * main.cc: add closing area on the reverted histo and correct the - neighborhood usage. - -2008-10-15 Vivien Delmon <vivien.delmon@lrde.epita.fr> - - Make main.cc compatible with cleanup branch of milena. - * ChangeLog: New. - * main.cc: Fix include paths. - Index: inim/binarization/proof-of-concept/check/graph.sh --- inim/binarization/proof-of-concept/check/graph.sh (revision 3756) +++ inim/binarization/proof-of-concept/check/graph.sh (working copy) @@ -1,27 +0,0 @@ -#! /bin/sh -## graph.sh for memory -## Made by leblanc <nicuveo@lrde.epita.fr> -## - - -## Vars - -in=$1 -out=$2 -w=$3 -h=$4 -if [ -z "$w" ] ; then - w=800 -fi -if [ -z "$h" ] ; then - h=600 -fi - -## Code - -export w -export h -export in -export out - -gnuplot histo.gp Index: inim/binarization/proof-of-concept/check/histo.gp --- inim/binarization/proof-of-concept/check/histo.gp (revision 3756) +++ inim/binarization/proof-of-concept/check/histo.gp (working copy) @@ -1,19 +0,0 @@ -# group.gp -# print epsilon evolution for a game at a fixed complexity - - -set term png enhanced size `echo "$w,$h"` - -set style data boxes - -set xlabel "color" - -set xrange [0:255] -set yrange [0:*] - -set xtics border nomirror -set ytics border nomirror - -set output "`echo "$out"`" - -plot "`echo "$in"`" using 1:2 notitle Index: inim/binarization/proof-of-concept/check/Makefile --- inim/binarization/proof-of-concept/check/Makefile (revision 3756) +++ inim/binarization/proof-of-concept/check/Makefile (working copy) @@ -1,71 +0,0 @@ -# Vars - -PROGS := $(notdir $(wildcard ../bin/*)) -IMG := $(wildcard *.pgm) -HISTS := $(shell seq 2) -PARAM := 5 10 20 40 - -all: check - - - -# Histo rule generation - -define HISTO_RULE -$1-$2/$4.png: $1-$2/$4.histo histo.gp graph.sh - ./graph.sh $$< $$@ "$(W)" "$(H)" -$1-$2/$4.histo: $3 ../bin/$1 - ../bin/$1 $3 $1-$2/$3 $1-$2/$(3:.pgm=) $2 - -TODO += $1-$2/$4.png -endef - - - -# Images rule generation - -define IMG_RULE -$1-$2/$3: $3 ../bin/$1 - ../bin/$1 $$< $$@ $$(@:.pgm=) $2 -TODO += $1-$2/$3 -$(foreach num,$(HISTS),$(eval $(call HISTO_RULE,$1,$2,$3,$(3:.pgm=_$(strip $(num)))))) -endef - - - -# Folder rule generation - -define PROG_RULE -FOLDS += $1-$2 -$1-$2: ../bin/$1 -$(foreach img,$(IMG),$(eval $(call IMG_RULE,$1,$2,$(strip $(img))))) -endef - - - -# Param rule generation - -define PARAM_RULE -$(foreach param,$(PARAM),$(eval $(call PROG_RULE,$1,$(strip $(param))))) -endef - - - -# Main - -$(foreach prog,$(PROGS),$(eval $(call PARAM_RULE,$(strip $(prog))))) - - - -# Main - -check: $(FOLDS) $(TODO) - -$(FOLDS): - mkdir -p $@ - -clean: - find . -name "*.histo" -delete - -distclean: clean - find * -type d \! -path '*svn*' | xargs rm -Rf Index: inim/binarization/proof-of-concept/Makefile --- inim/binarization/proof-of-concept/Makefile (revision 3756) +++ inim/binarization/proof-of-concept/Makefile (working copy) @@ -1,87 +0,0 @@ -## -## Makefile for inim -## Made by nicuveo <nicuveo@lrde.epita.fr> -## - -include Makefile.rules - - - -# VARS - -PROJ = binarisation - -TB = $(PROJ) -TB_TGZ = $(TB).tgz -TB_BZ2 = $(TB).bz2 -TB_TAR.GZ = $(TB).tar.gz -TB_TAR.BZ2 = $(TB).tar.bz2 - -CLEAN = '*~' '\#*' '.\#*' '.DS_Store' '.gdb_history' '*.stackdump'\ -'.gdb_history' 'gmon.out' - - - -# MAIN - -all: - cd ./build/ && make all - -basic: - cd ./build/ && make basic - -gradient: - cd ./build/ && make gradient - -clean: do_clean - cd ./build/ && make -k clean - cd ./check/ && make -k clean - -distclean: do_distclean - cd ./build/ && make -k distclean - cd ./check/ && make -k distclean - -check: all - cd ./check/ && make check - -recheck: all - cd ./check/ && make clean check - -flower: - cat ./scripts/flower - -todo: - ./scripts/todo.sh - -dist tar tarball: $(TB_TAR.BZ2) - - - -# CLEAN - -do_clean: - for f in ${CLEAN} ; do find . -name "$$f" | xargs rm -f ; done - -do_distclean: do_clean - rm -f $(TB_TGZ) $(TB_BZ2) $(TB_TAR.GZ) $(TB_TAR.BZ2) - rm -f Makefile.rules - - - -# TARBALLS - -$(TB_TAR.GZ) $(TB_TGZ) : distclean - ./scripts/init_tar.sh "$(TB)" - tar -hcvzf $@ --exclude=".svn" "$(TB)" - rm -Rf "$(TB)" - -$(TB_TAR.BZ2) $(TB_BZ2) : distclean - ./scripts/init_tar.sh "$(TB)" - tar -hcvjf $@ --exclude=".svn" "$(TB)" - rm -Rf "$(TB)" - - - -# SPECIALS - -.PHONY: todo Index: inim/binarization/snake2d.hh --- inim/binarization/snake2d.hh (revision 3756) +++ inim/binarization/snake2d.hh (working copy) @@ -1,190 +0,0 @@ -#include <mln/core/alias/neighb2d.hh> -#include <mln/win/diff.hh> -#include <mln/win/shift.hh> -#include <mln/extension/adjust_fill.hh> -#include <mln/canvas/browsing/snake_generic.hh> - -namespace mln -{ - - template <typename I, typename W, typename A> - struct snake2d_functor - { - typedef snake2d_functor<I,W, A> self; - typedef void (self::*move_fun)(); - typedef mln_deduce(I, psite, delta) dpsite; - - const I& input; - const W& win; - mln_ch_value(I, mln_result(A)) output; - A accu; - - mln_psite(I) p; - - window2d - win_left_fwd, - win_right_fwd, - win_left_bkd, - win_right_bkd, - win_bot_up, - win_top_up, - win_bot_down, - win_top_down; - - mln_qiter(window2d) - q_l_fwd, - q_r_fwd, - q_l_bkd, - q_r_bkd, - q_top_up, - q_bot_up, - q_top_down, - q_bot_down; - - std::vector<move_fun> moves; - std::vector<dpsite> dps; - - snake2d_functor(const I& input, const W& win) - : input(input), - win(win), - accu(), - - win_left_fwd(win::shift(win, mln::left) - win), - win_right_fwd(win - win::shift(win, mln::left)), - win_left_bkd(win::shift(win_left_fwd, mln::right)), - win_right_bkd(win::shift(win_right_fwd, mln::right)), - - win_bot_up(win::shift(win, mln::down) - win), - win_top_up(win - win::shift(win, mln::down)), - win_bot_down(win::shift(win_bot_up, mln::up)), - win_top_down(win::shift(win_top_up, mln::up)), - - q_l_fwd(win_left_fwd, p), - q_r_fwd(win_right_fwd, p), - q_l_bkd(win_left_bkd, p), - q_r_bkd(win_right_bkd, p), - - q_top_up(win_top_up, p), - q_bot_up(win_bot_up, p), - q_top_down(win_top_down, p), - q_bot_down(win_bot_down, p), - - moves(3), - dps(3) - { - if (win_bot_up.size() + win_top_up.size() + - win_bot_down.size() + win_top_down.size() < - win_left_fwd.size() + win_right_fwd.size() + - win_left_bkd.size() + win_right_bkd.size()) - { - // Vertical snake - dps[0] = mln::right; - dps[1] = mln::down; - dps[2] = mln::up; - moves[0] = &self::right; - moves[1] = &self::down; - moves[2] = &self::up; - } - else - { - // Horizontal snake - dps[0] = mln::down; - dps[1] = mln::right; - dps[2] = mln::left; - moves[0] = &self::down; - moves[1] = &self::right; - moves[2] = &self::left; - } - } - - void init() - { - initialize(output, input); - accu.init(); - p = input.domain().pmin() - dps[0]; - mln_qiter(W) q(win, p); - for_all(q) - if (input.has(q)) - accu.take(input(q)); - p = input.domain().pmin(); - } - - void right() - { - for_all(q_l_fwd) - if (input.has(q_l_fwd)) - accu.untake(input(q_l_fwd)); - for_all(q_r_fwd) - if (input.has(q_r_fwd)) - accu.take(input(q_r_fwd)); - output(p) = accu; - } - - void left() - { - for_all(q_r_bkd) - if (input.has(q_r_bkd)) - accu.untake(input(q_r_bkd)); - for_all(q_l_bkd) - if (input.has(q_l_bkd)) - accu.take(input(q_l_bkd)); - output(p) = accu; - } - - void down() - { - for_all(q_top_down) - if (input.has(q_top_down)) - accu.untake(input(q_top_down)); - for_all(q_bot_down) - if (input.has(q_bot_down)) - accu.take(input(q_bot_down)); - output(p) = accu; - } - - void up() - { - for_all(q_bot_up) - if (input.has(q_bot_up)) - accu.untake(input(q_bot_up)); - for_all(q_top_up) - if (input.has(q_top_up)) - accu.take(input(q_top_up)); - output(p) = accu; - } - - }; - - template <typename A, typename I, typename W> - inline - mln_ch_value(I, mln_result(A)) - snake2d(const Accumulator<A>&, const Image<I>& input, const Window<W>& win) - { - trace::entering("accu::snake2d"); - - typedef snake2d_functor<I, W, A> F; - F f(exact(input), exact(win)); - canvas::browsing::snake_generic(f); - - trace::exiting("accu::snake2d"); - - return f.output; - } - - template <typename A, typename I, typename W> - inline - mln_ch_value(I, mln_accu_with(A, mln_value(I))::result) - snake2d(const Meta_Accumulator<A>&, const Image<I>& input, const Window<W>& win) - { - trace::entering("accu::snake2d"); - - typedef mln_accu_with(A, mln_value(I)) A_; - typedef snake2d_functor<I, W, A_> F; - F f(exact(input), exact(win)); - canvas::browsing::snake_generic(f); - - trace::exiting("accu::snake2d"); - return f.output; - } - -} // mln Index: inim/binarization/binarization.hh --- inim/binarization/binarization.hh (revision 3756) +++ inim/binarization/binarization.hh (working copy) @@ -1,78 +0,0 @@ -#include <mln/histo/all.hh> -#include <mln/convert/to_image.hh> -#include <mln/core/image/image1d.hh> -#include <mln/core/alias/neighb1d.hh> -#include <mln/arith/revert.hh> -#include <mln/morpho/closing_area.hh> -#include <mln/morpho/meyer_wst.hh> -#include <mln/border/resize.hh> -#include <mln/accu/maj_h.hh> -#include <mln/opt/at.hh> -#include "snake2d.hh" - -namespace mln -{ - - namespace binarization - { - template<typename I, typename W> - mln_concrete_ch_value(I, bool) - binarization(const Image<I>& input, const Window<W>& win, int strength); - -# ifndef MLN_INCLUDE_ONLY - namespace impl - { - template<typename I, typename W> - mln_concrete_ch_value(I, bool) - binarization_(const I& input, const W& win, int strength) - { - trace::entering("binarisation_"); - mln_concrete_ch_value(I, bool) output(input.domain()); - - histo::data<mln_value(I)> hist = histo::compute (input); - image1d<std::size_t> hist_img = convert::to_image(hist); - image1d<std::size_t> hist_revert_closed; - initialize(hist_revert_closed, hist_img); - morpho::closing_area(arith::revert(hist_img), c2(), strength, hist_revert_closed); - int nbasins; - image1d<int> wst = morpho::meyer_wst(hist_revert_closed, c2(), nbasins); -// if (wst(wst.nelements() - 1) == 0) -// wst(p) = wst(p++); - I cla; - initialize(cla, input); - typename I::fwd_piter q (input.domain()); - for_all (q) - if (opt::at(wst, input(q)) == 0) - cla(q) = opt::at(wst, input(q) + 1); - else - cla(q) = opt::at(wst, input(q)); - border::resize(cla, 0); - I maj = snake2d(accu::meta::maj_h(), cla, win); - typename I::fwd_piter r (cla.domain()); - for_all (r) - output(r) = (cla(r) != maj(r)); - - trace::exiting("binarisation_"); - return output; - } - } - - template<typename I, typename W> - mln_concrete_ch_value(I, bool) - binarization(const Image<I>& input, const Window<W>& win, int strength) - { - trace::entering("binarisation"); - mln_precondition(exact(input).is_valid()); - - mln_concrete_ch_value(I, bool) output(exact(input).domain()); - output = impl::binarization_(exact(input), exact(win), strength); - - trace::exiting("binarisation"); - return output; - } - -# endif // ! MLN_INCLUDE_ONLY - - } // end of namespace mln::binarization - -} // end of namespace mln Index: inim/binarization/snake2d.cc --- inim/binarization/snake2d.cc (revision 3756) +++ inim/binarization/snake2d.cc (working copy) @@ -1,39 +0,0 @@ -#include <mln/win/rectangle2d.hh> -#include <mln/accu/maj_h.hh> -#include <mln/value/int_u8.hh> -#include <mln/level/compare.hh> -#include <mln/make/image2d.hh> -#include <mln/border/thickness.hh> -#include "snake2d.hh" - -#include <mln/debug/all.hh> - -int main() -{ - using namespace mln; - using value::int_u8; - - int_u8 vals [5][5] = { - {0, 0, 0, 1, 1}, - {0, 0, 0, 1, 1}, - {0, 0, 1, 1, 1}, - {2, 3, 3, 3, 3}, - {5, 4, 4, 5, 5} - }; - - int_u8 valres [5][5] = { - {0, 0, 0, 1, 1}, - {0, 0, 0, 1, 1}, - {0, 0, 0, 1, 1}, - {0, 0, 1, 1, 1}, - {0, 3, 3, 3, 3} - }; - - border::thickness = 0; - image2d<int_u8> ima = make::image2d(vals); - image2d<int_u8> res = snake2d(accu::maj_h<int_u8>(), ima, win::rectangle2d(5,5)); - mln_assertion (res == make::image2d(valres)); - image2d<int_u8> res2 = snake2d(accu::maj_h<int_u8>(), ima, win::rectangle2d(5,5)); - mln_assertion (res2 == make::image2d(valres)); - return 0; -} Index: inim/binarization/binarization.cc --- inim/binarization/binarization.cc (revision 3756) +++ inim/binarization/binarization.cc (working copy) @@ -1,36 +0,0 @@ -#include <iostream> -#include <string> -#include <mln/io/pgm/all.hh> -#include <mln/win/rectangle2d.hh> -#include <mln/value/all.hh> -#include <mln/core/image/image2d.hh> -#include "binarization.hh" - - -int main(int argc, char** argv) -{ - if (argc != 5) - { - std::cerr << argv[0] << " in out strength size" << std::endl; - return 42; - } - std::string in(argv[1]); - std::string out(argv[2]); - std::istringstream is(argv[3]); - int strength; - is >> strength; - std::istringstream iss(argv[4]); - int size; - iss >> size; - - mln::image2d<mln::value::int_u8> input; - mln::image2d<mln::value::int_u8> to_print; - mln::io::pgm::load(input, in); - mln::image2d<bool> output = mln::binarization::binarization(input, mln::win::rectangle2d(size,size), strength); - initialize(to_print, output); - mln::image2d<mln::value::int_u8>::fwd_piter p(input.domain()); - for_all (p) - to_print(p) = output(p) * 255; - mln::io::pgm::save(to_print, out); - return 0; -} Property changes on: inim/2009/classif ___________________________________________________________________ Added: svn:mergeinfo Property changes on: inim/2009/binarization ___________________________________________________________________ Added: svn:mergeinfo Index: inim/color/min_tree_volume_filter.cc --- inim/color/min_tree_volume_filter.cc (revision 3756) +++ inim/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: inim/color/reference.cc --- inim/color/reference.cc (revision 3756) +++ inim/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: inim/color/min_tree_area_filter.cc --- inim/color/min_tree_area_filter.cc (revision 3756) +++ inim/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: inim/color/min_tree_height_filter.cc --- inim/color/min_tree_height_filter.cc (revision 3756) +++ inim/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: inim/color/min_tree_color.cc --- inim/color/min_tree_color.cc (revision 3756) +++ inim/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: inim/color/reference2.cc --- inim/color/reference2.cc (revision 3756) +++ inim/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: inim/color/src/graph.hh --- inim/color/src/graph.hh (revision 3756) +++ inim/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: inim/color/src/io.hh --- inim/color/src/io.hh (revision 3756) +++ inim/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: inim/color/src/distance.hh --- inim/color/src/distance.hh (revision 3756) +++ inim/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: inim/color/src/convert.hh --- inim/color/src/convert.hh (revision 3756) +++ inim/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: inim/color/min_tree_color_v2.cc --- inim/color/min_tree_color_v2.cc (revision 3756) +++ inim/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: inim/color/laplacien.cc --- inim/color/laplacien.cc (revision 3756) +++ inim/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: inim/color/README --- inim/color/README (revision 3756) +++ inim/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. Index: inim/nature/gradient.cc --- inim/nature/gradient.cc (revision 3756) +++ inim/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: inim/nature/erosion.cc --- inim/nature/erosion.cc (revision 3756) +++ inim/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: inim/nature/mco.cc --- inim/nature/mco.cc (revision 3756) +++ inim/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: inim/nature/closing.cc --- inim/nature/closing.cc (revision 3756) +++ inim/nature/closing.cc (working copy) @@ -1,61 +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/pgm/save.hh> - -#include <mln/value/int_u8.hh> -#include <mln/morpho/closing/structural.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::structural(ima, rect), name.append("_closed.pgm")); - } -} Index: inim/nature/nature.cc --- inim/nature/nature.cc (revision 3756) +++ inim/nature/nature.cc (working copy) @@ -1,499 +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/thru.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/structural.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::data<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); - - thru<mln::meta::hue<hsi_f>, image2d<hsi_f> > hue(hsi); - thru<mln::meta::sat<hsi_f>, image2d<hsi_f> > sat(hsi); - thru<mln::meta::inty<hsi_f>, image2d<hsi_f> > inty(hsi); - - cast_image_<float01_8, thru<mln::meta::hue<hsi_f>, image2d<hsi_f> > > qhue(hue); // quantified hue - cast_image_<float01_8, thru<mln::meta::sat<hsi_f>, image2d<hsi_f> > > qsat(sat); // quantified sat - cast_image_<float01_8, thru<mln::meta::inty<hsi_f>, image2d<hsi_f> > > qinty(inty); // quantified inty - - histo::data<float01_8> hhue = histo::compute(qhue); - histo::data<float01_8> hsat = histo::compute(qsat); - histo::data<float01_8> hinty = histo::compute(qinty); - - - // 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] += 50 + max / 2; - score[DRAWING] += 50 + max / 2; - - std::cout << "Test 2 : co-occurence matrix diag_max[" << max << "]" << std::endl - << "Photo : +" << 100 - max << std::endl; - - std::cout << "Screenshot : +" << 50 + max / 2 << std::endl; - - std::cout << "Text : +" << max * 2 << std::endl; - - std::cout << "Drawing : +" << 50 + 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::structural(inter, win::hline2d(20)); - final += morpho::opening::structural(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 * 5; - score[TEXT] += 50 + cpt * max / 10; - score[DRAWING] += 2 * (50 - cpt); - - std::cout << "Test 3 : rectangle detection[" << cpt << "]" << std::endl - << "Photo : +" << 50 - cpt << std::endl - << "Screenshot : +" << cpt * 8 << std::endl - << "Text : +" << 50 + cpt * max / 10 << std::endl - << "Drawing : +" << 2 * (50 - cpt) << std::endl << std::endl; - - - // Last but not least : text detection thanks to FFT - - transform::fft<double> fourier(morpho::opening::structural(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 * 25; - score[TEXT] += (1 + cos(arg)) * 2 * (4 - dist) * 50; - score[DRAWING] += dist * 25; - - std::cout << "Test 4 : Fourier distance[" << dist << "]" << std::endl - << "Photo : +" << dist * 25 << std::endl - << "Screenshot : +" << dist * 25 << std::endl - << "Text : +" << (1 + cos(arg)) * (4 - dist) * 25 << std::endl - << "Drawing : +" << dist * 25 << std::endl << std::endl; - - - // 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: inim/nature/opening.cc --- inim/nature/opening.cc (revision 3756) +++ inim/nature/opening.cc (working copy) @@ -1,61 +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/pgm/save.hh> - -#include <mln/value/int_u8.hh> -#include <mln/morpho/opening/structural.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::structural(ima, rect), name.append("_opened.pgm")); - } -} Index: inim/nature/fft.cc --- inim/nature/fft.cc (revision 3756) +++ inim/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: inim/nature/co_occurence.hh --- inim/nature/co_occurence.hh (revision 3756) +++ inim/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: inim/nature/hom.cc --- inim/nature/hom.cc (revision 3756) +++ inim/nature/hom.cc (working copy) @@ -1,316 +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/structural.hh> - -#include <mln/win/hline2d.hh> -#include <mln/win/vline2d.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, 10); - - - - window2d winout; - window2d winin; - -// static const bool matout [] = {0, 0, 0, 0, 0, 0, 0, -// 0, 0, 1, 0, 0, 0, 0, -// 0, 0, 1, 0, 0, 0, 0, -// 0, 0, 1, 0, 0, 0, 0, -// 0, 0, 1, 1, 1, 1, 0, -// 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0}; - - static const bool blmatout [] = {0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0}; - -// static const bool blmatout [] = {0, 0, 0, -// 1, 0, 0, -// 1, 1, 0}; - - - convert::from_to(blmatout, winout); - -// static const bool matin [] = {0, 0, 0, 1, 0, 0, 0, -// 0, 0, 0, 1, 0, 0, 0, -// 0, 0, 0, 1, 0, 0, 0, -// 0, 0, 0, 1, 1, 1, 1, -// 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0}; - - static const bool blmatin [] = {0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 1, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0}; - -// static const bool blmatin [] = {0, 1, 0, -// 0, 1, 1, -// 0, 0, 0}; - - convert::from_to(blmatin, winin); - image2d<bool> bottom_left = morpho::hit_or_miss(imab, winout, winin); - - -// static const bool brmatout [] = {0, 0, 0, -// 0, 0, 1, -// 0, 1, 1}; - -// static const bool brmatin [] = {0, 1, 0, -// 1, 1, 0, -// 0, 0, 0}; - - static const bool brmatout [] = {0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, - 0, 0, 0, 1, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0}; - - static const bool brmatin [] = {0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 1, 1, 1, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0}; - - - convert::from_to(brmatout, winout); - convert::from_to(brmatin, winin); - image2d<bool> bottom_right = morpho::hit_or_miss(imab, winout, winin); - -// static const bool urmatout [] = {0, 1, 1, -// 0, 0, 1, -// 0, 0, 0}; - -// static const bool urmatin [] = {0, 0, 0, -// 1, 1, 0, -// 0, 1, 0}; - - static const bool urmatout [] = {0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 1, 0, - 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0}; - - static const bool urmatin [] = {0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0}; - - - convert::from_to(urmatout, winout); - convert::from_to(urmatin, winin); - image2d<bool> up_right = morpho::hit_or_miss(imab, winout, winin); - - -// static const bool ulmatout [] = {1, 1, 0, -// 1, 0, 0, -// 0, 0, 0}; - -// static const bool ulmatin [] = {0, 0, 0, -// 0, 1, 1, -// 0, 1, 0}; - - static const bool ulmatout [] = {0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0}; - - static const bool ulmatin [] = {0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 1, 1, 1, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0}; - - - convert::from_to(ulmatout, winout); - convert::from_to(ulmatin, winin); - image2d<bool> up_left = morpho::hit_or_miss(imab, winout, winin); - - - static const bool umatout [] = {0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0}; - - static const bool umatin [] = {0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0}; - - - convert::from_to(umatout, winout); - convert::from_to(umatin, winin); - image2d<bool> up = morpho::hit_or_miss(imab, winout, winin); - - - static const bool bmatout [] = {0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0}; - - static const bool bmatin [] = {0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0}; - - - convert::from_to(bmatout, winout); - convert::from_to(bmatin, winin); - image2d<bool> bottom = morpho::hit_or_miss(imab, winout, winin); - - - static const bool lmatout [] = {0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 1, 0, 0, 0}; - - static const bool lmatin [] = {0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0}; - - - convert::from_to(lmatout, winout); - convert::from_to(lmatin, winin); - image2d<bool> left = morpho::hit_or_miss(imab, winout, winin); - - - static const bool rmatout [] = {0, 0, 0, 1, 0, - 0, 0, 0, 1, 0, - 0, 0, 0, 1, 0, - 0, 0, 0, 1, 0, - 0, 0, 0, 1, 0}; - - static const bool rmatin [] = {0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0}; - - - convert::from_to(rmatout, winout); - convert::from_to(rmatin, winin); - image2d<bool> right = morpho::hit_or_miss(imab, winout, winin); - - - - - std::string name(argv[i]); - name.erase(name.length() - 4); - io::pbm::save( imab, name.append("_bin.pbm")); - - name = argv[i]; - name.erase(name.length() - 4); - // image2d<bool> final(right.domain()); - // data::fill(final, false); - // mln_piter_(image2d<bool>) p(final.domain()); - // for_all(p) - // final(p) = up_left(p) || up_right(p) || bottom_right(p) || bottom_left(p) || up(p) || bottom(p) || left(p) || right(p); - - image2d<bool> inter (up_left + up_right + bottom_right + bottom_left + up + bottom + left + right); - - static const bool vert [] = {0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0}; - - static const bool hori [] = {0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0}; - - convert::from_to(vert, winin); - convert::from_to(hori, winout); - - image2d<bool> final = morpho::opening::structural(inter, win::hline2d(20)); - final += morpho::opening::structural(inter, win::vline2d(20)); - - io::pbm::save( final, - name.append("_hom.pbm")); - } -} Index: inim/nature/proj.hh --- inim/nature/proj.hh (revision 3756) +++ inim/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: inim/nature/test.sh --- inim/nature/test.sh (revision 3756) +++ inim/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: inim/nature/Makefile --- inim/nature/Makefile (revision 3756) +++ inim/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: inim/nature/histo_hsi.cc --- inim/nature/histo_hsi.cc (revision 3756) +++ inim/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: inim/nature/proj.cc --- inim/nature/proj.cc (revision 3756) +++ inim/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")); - } -}