proto-1.0 398: Update Anisotropic diffusion for a generic use.

https://svn/svn/oln/prototypes/proto-1.0/olena Index: ChangeLog from Nicolas Widynski <nicolas.widynski@lrde.epita.fr> Update Anisotropic diffusion for a generic use. * oln/level/anisotropic_diffusion.hh: Update. * oln/makefile.src: Update. level/anisotropic_diffusion.hh | 90 ++++++++++++++++++++++++++--------------- makefile.src | 5 +- 2 files changed, 62 insertions(+), 33 deletions(-) Index: oln/level/anisotropic_diffusion.hh --- oln/level/anisotropic_diffusion.hh (revision 397) +++ oln/level/anisotropic_diffusion.hh (working copy) @@ -31,6 +31,7 @@ # include <oln/basics.hh> # include <oln/utils/clone.hh> # include <oln/morpho/gradient_morpho.hh> +# include <oln/utils/clean_boundaries.hh> # define SQR(u) u*u # define ABS(u) u >= 0 ? u : -u @@ -41,59 +42,82 @@ namespace impl { - template <typename I> - oln_ch_concrete_type(I, std::vector<double>) - gradient_on_each_side_(const abstract::image<I>& input) + // version 2d of the 4nbhs gradient + template <typename T> + image2d<std::vector<double> > + gradient_on_each_side_(const image2d<T>& input) { - oln_ch_concrete_type(I, std::vector<double>) g(input.size(), "gradient"); - oln_type_of(I, fwd_piter) p(input.size()); - oln_type_of(I, point) pt; + image2d<std::vector<double> > g(input.size(), "gradient"); + fwd_piter2d p(input.size()); + point2d pt; for_all_p(p) { pt = p; // N - g.at(p).push_back((double)input[oln_type_of(I, point)((coord_t)(pt.row() - 1), pt.col())].value() - - input[oln_type_of(I, point)((coord_t)(pt.row()), pt.col())].value()); + g.at(p).push_back((input(pt.row() - 1, pt.col()) - input[p]) / 2); // S - g.at(p).push_back((double)input[oln_type_of(I, point)((coord_t)(pt.row() + 1), pt.col())].value() - - input[oln_type_of(I, point)((coord_t)(pt.row()), pt.col())].value()); + g.at(p).push_back((input(pt.row() + 1, pt.col()) - input[p]) / 2); // E - g.at(p).push_back((double)input[oln_type_of(I, point)(pt.row(), (coord_t)(pt.col() + 1))].value() - - input[oln_type_of(I, point)(pt.row(), (coord_t)(pt.col()))].value()); + g.at(p).push_back((input(pt.row(), pt.col() + 1) - input[p]) / 2); // W - g.at(p).push_back((double)input[oln_type_of(I, point)(pt.row(), (coord_t)(pt.col() - 1))].value() - - input[oln_type_of(I, point)(pt.row(), (coord_t)(pt.col()))].value()); + g.at(p).push_back((input(pt.row(), pt.col() - 1) - input[p]) / 2); } return g; } - template <typename T> - void clean_ima(image2d<T>& ima) + template <typename I> + double compute_capa(const abstract::image<I>& input) { - for (int j = 0; j < ima.size().ncols(); j++) + // static version of cappa (near the variance) + return 6; + + + // 4 nbhs version of gradient + + /* + double K = 0; + double seuil = 0; + + oln_type_of(I, concrete) grad(input.size()); + oln_type_of(I, fwd_piter) p(input.size()); + oln_type_of(I, point) pt; + + for_all_p(p) { - ima(-1, j) = ima(0, j); - ima(ima.size().nrows(), j) = ima(ima.size().nrows() - 1, j); + pt = p; + + grad[p] = (double) ((ABS((double) (input[oln_type_of(I, point)(pt.row() - 1, pt.col())].value()))) + + (ABS((double) (input[oln_type_of(I, point)(pt.row() + 1, pt.col())].value()))) + + (ABS((double) (input[oln_type_of(I, point)(pt.row(), pt.col() + 1)].value()))) + + (ABS((double) (input[oln_type_of(I, point)(pt.row(), pt.col() - 1)].value()))) + + (ABS((double) (- 4 * input[oln_type_of(I, point)((coord_t)(pt.row()), pt.col())].value())))) / 8; + + seuil = grad[p] > seuil ? grad[p] : seuil; } - for (int j = 0; j < ima.size().nrows(); j++) + seuil *= 0.9; + + for_all_p(p) { - ima(j, -1) = ima(j, 0); - ima(j, ima.size().ncols()) = ima(j, ima.size().ncols() - 1); - } + // if (grad[p] < (int)seuil) + if (grad[p] > (int)seuil) + K++; } + std::cout << K << std::endl; + return K; + */ - template <typename I> - double compute_capa(const abstract::image<I>& input) - { + // morphologic version of gradient + + /* double K = 0; double seuil = 0.9 * 255; @@ -103,9 +127,11 @@ for_all_p(p) { if (grad[p] < (int)seuil) + // if (grad[p] > (int)seuil) K++; } return K; + */ } @@ -114,6 +140,7 @@ return 1 / (1 + SQR(grad / K)); } + // generic function of the anisotropic diffusion template <typename I> oln_type_of(I, concrete) anisotropic_diffusion_(const abstract::image<I>& input, unsigned nb_it) @@ -134,8 +161,8 @@ while (conv == false) { - clean_ima(a_d.exact()); - grad = gradient_on_each_side_(a_d); + utils::clean_boundaries(a_d.exact()); + grad = gradient_on_each_side_(a_d.exact()); K = compute_capa(a_d); change = false; error = 0; @@ -162,7 +189,7 @@ std::cout << "error " << error << std::endl; - if (it >= nb_it or error < 0.1 or change == false) + if ((it >= nb_it and nb_it != 0) or error < 0.1 or change == false) conv = true; it++; @@ -171,14 +198,13 @@ return a_d; } - - } // end of namespace oln::level::impl + // nb_it = 0 signifies until algorithm convergence. template <typename I> oln_type_of(I, concrete) - anisotropic_diffusion(const abstract::image<I>& input, unsigned nb_it) + anisotropic_diffusion(const abstract::image<I>& input, unsigned nb_it = 0) { return impl::anisotropic_diffusion_(input.exact(), nb_it); } Index: oln/makefile.src --- oln/makefile.src (revision 397) +++ oln/makefile.src (working copy) @@ -12,6 +12,8 @@ \ appli/denoising/nl_means.hh \ \ + appli/inpainting/image_inpainting.hh \ + \ basics1d.hh \ basics2d.hh \ basics3d.hh \ @@ -170,6 +172,7 @@ io/vectorial.hh \ io/write_image.hh \ \ + level/anisotropic_diffusion.hh \ level/arith.hh \ level/compare.hh \ level/extrema_components.hh \ @@ -177,7 +180,6 @@ level/invert.hh \ level/level_components.hh \ level/logic.hh \ - level/anisotropic_diffusion.hh \ \ morpho/closing.hh \ morpho/dilation.hh \ @@ -209,6 +211,7 @@ \ utils/buffer.hh \ utils/clone.hh \ + utils/clean_boundaries.hh \ utils/invert.hh \ utils/key.hh \ utils/md5.hh \
participants (1)
-
Nicolas Widynski