
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2009-05-15 Etienne FOLIO <folio@lrde.epita.fr> Big cleanup. * Makefile: Remove. Not needed. * README: New explainations. * configure: To build the Makefile. * dilation-n.hh: New algorithm. * erosion-n.hh: New algorithm. * main_dilation-n.cc: New test file. * morpho.cc: Cleanup in here. * treat.sh: Adaptation. --- README | 16 +++++ configure | 23 ------- dilation-n.hh | 41 ++++++++++++++ erosion-n.hh | 41 ++++++++++++++ main_dilation-n.cc | 54 ++++++++++++++++++ morpho.cc | 153 +++++++++++++++++++++-------------------------------- treat.sh | 35 ++---------- 7 files changed, 224 insertions(+), 139 deletions(-) Index: trunk/milena/sandbox/inim/2010/morpho/Makefile (deleted) =================================================================== Index: trunk/milena/sandbox/inim/2010/morpho/configure =================================================================== --- trunk/milena/sandbox/inim/2010/morpho/configure (revision 3845) +++ trunk/milena/sandbox/inim/2010/morpho/configure (revision 3846) @@ -1,34 +1,17 @@ #! /bin/bash - - if [ "$1" = "--debug" ]; then - DEBUG_FLAGS=" -g -ggdb " OPT_FLAGS="" else - OPT_FLAGS=" -DNDEBUG -O3 " DEBUG_FLAGS="" fi - - -if [ "$2" = "--duma" ]; then - LIB_PATH="-L/lrde/beyrouth/lrde-2011/da-mota/utils/duma " - LIB=" -lduma " -else - LIB_PATH=" " - LIB=" " -fi - - -CXXFLAGS="-Wall -Wextra -W -Werror -pedantic " - +CXXFLAGS="-Wall -Wextra -W -pedantic " echo -n ' => Generating Makefile... ' - echo 'CXX=g++' > Makefile echo 'CXXFLAGS='${CXXFLAGS} >> Makefile echo '' >> Makefile @@ -57,8 +40,6 @@ echo '' >> Makefile echo '' >> Makefile echo '%.o: %.cc' >> Makefile -echo ' $(CXX) $(CXXFLAGS) ' -I/work/$USER/milena '-c $< -o $@' >> Makefile +echo ' $(CXX) $(CXXFLAGS) ' -I../../../../ '-c $< -o $@' >> Makefile echo '' >> Makefile - - echo ' [DONE]' \ No newline at end of file Index: trunk/milena/sandbox/inim/2010/morpho/main_dilation-n.cc =================================================================== --- trunk/milena/sandbox/inim/2010/morpho/main_dilation-n.cc (revision 0) +++ trunk/milena/sandbox/inim/2010/morpho/main_dilation-n.cc (revision 3846) @@ -0,0 +1,54 @@ +#include <iostream> +#include <sstream> +#include <string> +#include <mln/debug/println.hh> +#include <mln/data/fill.hh> + +#include <mln/io/pbm/load.hh> +#include <mln/io/pgm/save.hh> + +#include <mln/level/convert.hh> +#include <mln/level/stretch.hh> + +#include <mln/core/alias/window2d.hh> + +#include "dilation-n.hh" +#include "erosion-n.hh" + +int main(int argc, char** argv) +{ + using namespace mln; + + // check arguments + if (argc != 5) + { + std::cerr << "Usage:" << std::endl + << " ./a.out <in.pbm> <out.pbm> <k> <lambda>" << std::endl; + exit(1); + } + + // build test image + std::cout << " => loading " << argv[1] << "..." << std::endl; + image2d<bool> in; + io::pbm::load(in, argv[1]); + + value::int_u8 k = 1; + image2d<value::int_u8> ima = level::convert(k, in); + ima = level::stretch(k, ima); + + std::cout << " => create window..." << std::endl; + window2d it; + it.insert(0, 0); + for (unsigned i = 1; i <= atoi(argv[3]); ++i) + { + it.insert(0, -i); + it.insert(0, i); + } + + std::cout << " => applying dilation..." << std::endl; + image2d<value::int_u8> out; + out = morpho::erosion_n(ima, it, atoi(argv[4])); + + std::cout << " => saving " << argv[2] << "..." << std::endl; + io::pgm::save(out, argv[2]); +} Index: trunk/milena/sandbox/inim/2010/morpho/erosion-n.hh =================================================================== --- trunk/milena/sandbox/inim/2010/morpho/erosion-n.hh (revision 0) +++ trunk/milena/sandbox/inim/2010/morpho/erosion-n.hh (revision 3846) @@ -0,0 +1,41 @@ +#include <mln/core/concept/image.hh> + +namespace mln +{ + + namespace morpho + { + + template <typename I, typename W> + inline + I + erosion_n(const Image<I>& ima_, + const W& win, + const unsigned lambda) + { + const I& ima = exact(ima_); + mln_precondition(ima.is_valid()); + + I out; + initialize(out, ima); + + mln_piter(I) p(ima.domain()); + mln_qiter(W) q(win, p); + + for_all(p) + { + unsigned i = 0; + for_all(q) + if (ima.has(q) && ima(q) != mln_max(mln_value(I))) + ++i; + + out(p) = (i >= lambda) + ? mln_min(mln_value(I)) + : ima(p); + } + + return out; + } + + } +} Index: trunk/milena/sandbox/inim/2010/morpho/morpho.cc =================================================================== --- trunk/milena/sandbox/inim/2010/morpho/morpho.cc (revision 3845) +++ trunk/milena/sandbox/inim/2010/morpho/morpho.cc (revision 3846) @@ -1,124 +1,93 @@ #include <iostream> #include <sstream> #include <string> -#include <mln/debug/println.hh> +#include <mln/arith/revert.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/core/alias/window2d.hh> #include <mln/io/pbm/load.hh> #include <mln/io/pgm/save.hh> - - -#include <mln/core/alias/neighb2d.hh> -#include <mln/accu/max.hh> -#include <mln/value/label_8.hh> #include <mln/labeling/regional_maxima.hh> -#include <mln/data/fill.hh> -#include <mln/literal/all.hh> -#include <mln/arith/revert.hh> #include <mln/level/convert.hh> #include <mln/level/stretch.hh> -#include <mln/morpho/closing/structural.hh> -#include <mln/core/alias/window2d.hh> -#include <mln/make/win_chamfer.hh> #include <mln/linear/gaussian.hh> - #include <mln/morpho/rank_filter.hh> +#include <mln/value/label_8.hh> using namespace mln; using namespace mln::value; void -load_img(image2d<bool>& in, const char* filename) +load_img(image2d<int_u8>& ima, const char* filename) { - using namespace mln; - - // build test image - std::cout << " => loading " << filename << "..."; + std::cout << " => loadimag " << filename << "..."; std::cout.flush(); + + // load. + image2d<bool> in; io::pbm::load(in, filename); + + // convert and stretch. + int_u8 k = 1; + ima = level::convert(k, in); + ima = level::stretch(k, ima); + std::cout << "................[DONE]" << std::endl; } - void -revert_img(image2d<int_u8>& out, - const image2d<bool>& in) +revert_img(image2d<int_u8>& ima) { - using namespace mln; - - int_u8 k = 1; - out = level::convert(k, in); - out = level::stretch(k, out); - std::cout << " => revert image..."; std::cout.flush(); - out = arith::revert(out); - std::cout << "...................[DONE]" << std::endl; + // revert. + ima = arith::revert(ima); + std::cout << "...................[DONE]" << std::endl; } - - - void -gaussian_filter(image2d<int_u8>& out, int gaussian_force) +gaussian_filter(image2d<int_u8>& ima, float gaussian_force) { - using namespace mln; - std::cout << " => applying gaussian filter..."; std::cout.flush(); - out = linear::gaussian(out, gaussian_force, 1); - // out = linear::gaussian_1st_derivative(out, gaussian_force, 1); + + // gaussian filter. + ima = linear::gaussian(ima, gaussian_force, 1); std::cout << ".......[DONE]" << std::endl; } - - - - - -image2d<int_u8> -rank_filter(const image2d<int_u8>& out, - window2d it, int k, unsigned int lambda) +void +rank_filter(image2d<int_u8>& ima, + const window2d& it, + const unsigned k, + const unsigned lambda) { - using namespace mln; - std::cout << " => applying rank k filter..."; std::cout.flush(); - image2d<int_u8> rank_filtered = morpho::rank_filter(out, it, k); + // rank filter. + ima = morpho::rank_filter(ima, it, k); - for (unsigned int y = 0; y <= rank_filtered.ncols () - 1; ++y) - for (unsigned int x = 0; x <= rank_filtered.nrows() - 1; ++x) - { - if (rank_filtered(point2d(x, y)) < lambda) - rank_filtered(point2d(x, y)) = 0; + mln_fwd_piter_(image2d<int_u8>) p(ima.domain()); + for_all(p) + if (ima(p) < lambda) + ima(p) = mln_min(int_u8); else - rank_filtered(point2d(x, y)) = 255; - } + ima(p) = mln_max(int_u8); std::cout << ".........[DONE]" << std::endl; - - return rank_filtered; } - - - - void -look_for_lines(const image2d<label_8>& labels, image2d<int_u8>& ima) +replace_with_labels(const image2d<label_8>& labels, image2d<int_u8>& ima) { mln_fwd_piter_(image2d<int_u8>) p(ima.domain()); for_all(p) - { if (ima(p) == mln_max(int_u8)) - { - ima(p) = labels(p); - } - } + ima(p) = labels(p); // replace with label at p. } - int main(int argc, char** argv) { @@ -126,46 +95,50 @@ if (argc != 7) { std::cerr << "Usage:" << std::endl - << " ./morpho <in.pbm> <gaussian_force> <k> " + << " ./morpho <ima.pbm> <gaussian_force> <k> " << "<window_width> <lambda> " - << "<output_filename>" << std::endl; + << "<input_filename>" << std::endl; exit(1); } + // get argv variables. const char* input_filename = argv[1]; - float gaussian_force = atof(argv[2]); - - unsigned int k = atoi(argv[3]); - unsigned int w_width = atoi(argv[4]); - unsigned int lambda = atoi(argv[5]); + const float gaussian_force = atof(argv[2]); + const unsigned k = atoi(argv[3]); + const unsigned w_width = atoi(argv[4]); + const unsigned lambda = atoi(argv[5]); const char* output_filename = argv[6]; + // load and revert image. + image2d<int_u8> ima; + load_img(ima, input_filename); + image2d<int_u8> in(ima); + //revert_img(ima); + io::pgm::save(ima, "1.pgm"); + + // apply gaussian filter. + gaussian_filter(ima, gaussian_force); + io::pgm::save(ima, "2.pgm"); - image2d<bool> in; - load_img(in, input_filename); - - int_u8 i = 1; - image2d<int_u8> in_u8 = level::convert(i, in); - in_u8 = level::stretch(i, in_u8); - - image2d<int_u8> out = in_u8; - gaussian_filter(out, gaussian_force); - + // create window. window2d window; window.insert(0, 0); - for (unsigned i = 1; i <= w_width; ++i) { window.insert(0, -i); window.insert(0, i); } - image2d<int_u8> ima = - rank_filter(out, window, k, lambda); + // apply k-rank filter. + rank_filter(ima, window, k, lambda); + io::pgm::save(ima, "3.pgm"); + // labelize. label_8 nlabels = 0; image2d<label_8> labels = labeling::regional_maxima(ima, c4(), nlabels); + io::pgm::save(labels, "4.pgm"); - look_for_lines(labels, in_u8); - io::pgm::save(in_u8, output_filename); + // compute output image. + replace_with_labels(labels, in); + io::pgm::save(in, output_filename); } Index: trunk/milena/sandbox/inim/2010/morpho/treat.sh =================================================================== --- trunk/milena/sandbox/inim/2010/morpho/treat.sh (revision 3845) +++ trunk/milena/sandbox/inim/2010/morpho/treat.sh (revision 3846) @@ -1,42 +1,21 @@ #!/bin/sh - - gaussian_force=20 # best with values around 20 k=5 # best with values in [|1..10|] window_width=20 # best with small values in [|10..30|] lambda=5 # best with small values like 5-10 -OUTPUT_DIR=output - -if [ $# -eq 0 ] +if [ $# -ne 2 ] then + echo "Usage: ./run.sh <input_image.pbm> <output_image.pgm>" + exit 1 +fi - echo -n 'Cleaning output directory........' - rm -f /lrde/beyrouth/lrde-2011/da-mota/images_INIM/result/* - echo '......[DONE]' - - mkdir -p ${OUTPUT_DIR} - - for filename in `echo *.pbm` - do - output_filename=${OUTPUT_DIR}/${filename} - - ~/morpho/morpho \ - ${filename} \ +./morpho \ + $1 \ ${gaussian_force} \ ${k} \ ${window_width} \ ${lambda} \ - ${output_filename} \ + $2 \ || exit $? - - done - -fi - - -for i in `ls ${OUTPUT_DIR}/*.pbm` -do - display $i -done Index: trunk/milena/sandbox/inim/2010/morpho/dilation-n.hh =================================================================== --- trunk/milena/sandbox/inim/2010/morpho/dilation-n.hh (revision 0) +++ trunk/milena/sandbox/inim/2010/morpho/dilation-n.hh (revision 3846) @@ -0,0 +1,41 @@ +#include <mln/core/concept/image.hh> + +namespace mln +{ + + namespace morpho + { + + template <typename I, typename W> + inline + I + dilation_n(const Image<I>& ima_, + const W& win, + const unsigned lambda) + { + const I& ima = exact(ima_); + mln_precondition(ima.is_valid()); + + I out; + initialize(out, ima); + + mln_piter(I) p(ima.domain()); + mln_qiter(W) q(win, p); + + for_all(p) + { + unsigned i = 0; + for_all(q) + if (ima.has(q) && ima(q) != mln_min(mln_value(I))) + ++i; + + out(p) = (i >= lambda) + ? mln_max(mln_value(I)) + : ima(p); + } + + return out; + } + + } +} Index: trunk/milena/sandbox/inim/2010/morpho/README =================================================================== --- trunk/milena/sandbox/inim/2010/morpho/README (revision 0) +++ trunk/milena/sandbox/inim/2010/morpho/README (revision 3846) @@ -0,0 +1,16 @@ +== Dilation and erosion== + +Dilation and erosion: how to make a k-rank filter when it already exists: + +We developed those algorithms in erosion-n.hh and dilation-n.hh. +You can test those by running main_dilation-n.cc. + + +== Main morpho work == + +The code is located in morpho.cc. You can run it by following those steps: +- type ./configure in the shell +- then make +- then ./run.sh <input_image.pbm> <output_image.pgm> + +You can customize the input variables by editing the run.sh script.