oln::morpho Namespace Reference

Algorithm based on morphological mathematic. More...


Classes

struct  sort_dimensions
 functor to sort dimensions. More...

struct  cmp_queue_elt

Functions

template<class I, class E> oln::mute< I >::ret closing (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Processing closing.

template<class I, class E> oln::mute< I >::ret dilation (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Processing dilation.

template<class I, class E> oln::mute< I >::ret n_dilation (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se, unsigned n)
 Perform morphological dilation iterated n times.

template<class I, class E> oln::mute< I >::ret erosion (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Perform a morphological erosion.

template<class I, class E> oln::mute< I >::ret n_erosion (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se, unsigned n)
 Perform morphological erosion iterated n times.

template<class I, class N> mute< I, ntg::bin >::ret internal_kill_cc_area (const abstract::binary_image_with_dim< 2, I > &input, const unsigned int area, const abstract::neighborhood< N > &Ng)
 Kill connex components smaller than a given area.

template<class I, class N> oln::mute< I >::ret sure_maxima_killer (const abstract::non_vectorial_image< I > &input, const unsigned int area, const abstract::neighborhood< N > &Ng)
 Maxima killer.

template<class I, class N> image2d< ntg::int_u8 > sure_minima_killer (const abstract::non_vectorial_image< I > &input, const unsigned int area, const abstract::neighborhood< N > &Ng)
 Minima killer.

template<class P, class I, class N> bool is_a_strict_minimum (const abstract::point< P > &p, const abstract::non_vectorial_image< I > &input, const abstract::neighborhood< N > &Ng)
 Check if a point is a strict minimum.

template<class P, class I, class N> bool is_a_strict_maximum (const abstract::point< P > &p, const abstract::non_vectorial_image< I > &input, const abstract::neighborhood< N > &Ng)
 Check if a point is a strict maximum.

template<class I, class N> oln::mute< I >::ret fast_minima_killer (const abstract::non_vectorial_image< I > &input, const unsigned int area, const abstract::neighborhood< N > &Ng)
 Minima killer.

template<class I, class N> oln::mute< I >::ret fast_maxima_killer (const abstract::non_vectorial_image< I > &input, const unsigned int area, const abstract::neighborhood< N > &Ng)
 Maxima killer.

template<class I, class E> oln::mute< I >::ret fast_morpho (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se, typename mlc::exact< I >::ret::value_type(*func)(const utils::histogram< typename mlc::exact< I >::ret::value_type > &))
template<class I, class E, class H> oln::mute< I >::ret fast_morpho (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Fast morpho algorithm.

template<class I1, class I2, class N> oln::mute< I1 >::ret geodesic_dilation (const abstract::non_vectorial_image< I1 > &marker, const abstract::non_vectorial_image< I2 > &mask, const abstract::neighborhood< N > &Ng)
 Processing a geodesic dilation.

template<class I1, class I2, class N> oln::mute< I1 >::ret geodesic_erosion (const abstract::non_vectorial_image< I1 > &marker, const abstract::non_vectorial_image< I2 > &mask, const abstract::neighborhood< N > &Ng)
 Processing a geodesic erosion.

template<class C, class B, class I, class E> mute< I, typename convoutput<
C, B, typename mlc::exact<
I >::ret::value_type >::ret
>::ret 
beucher_gradient (const convert::abstract::conversion< C, B > &c, const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Process a morphological beucher gradient.

template<class I, class E> oln::mute< I >::ret external_gradient (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Process a morphological beucher gradient.

template<class C, class B, class I, class E1, class E2> mute< I, typename convoutput<
C, B, typename mlc::exact<
I >::ret::value_type >::ret
>::ret 
hit_or_miss (const convert::abstract::conversion< C, B > &c, const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E1 > &se1, const abstract::struct_elt< E2 > &se2)
 Preform a 'hit or miss' transform.

template<class I, class E1, class E2> oln::mute< I >::ret hit_or_miss (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E1 > &se1, const abstract::struct_elt< E2 > &se2)
 Preform a 'hit or miss' transform.

template<class I, class E1, class E2> oln::mute< I >::ret hit_or_miss_opening (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E1 > &se1, const abstract::struct_elt< E2 > &se2)
 Perform an hit or miss opening.

template<class I, class E1, class E2> oln::mute< I >::ret hit_or_miss_opening_bg (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E1 > &se1, const abstract::struct_elt< E2 > &se2)
 Perform an hit or miss opening of background.

template<class I, class E1, class E2> oln::mute< I >::ret hit_or_miss_closing (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E1 > &se1, const abstract::struct_elt< E2 > &se2)
 Perform an hit or miss closing.

template<class I, class E1, class E2> oln::mute< I >::ret hit_or_miss_closing_bg (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E1 > &se1, const abstract::struct_elt< E2 > &se2)
 Perform an hit or miss closing of background.

template<class C, class B, class I, class E> mute< I, typename convoutput<
C, B, typename mlc::exact<
I >::ret::value_type >::ret
>::ret 
laplacian (const convert::abstract::conversion< C, B > &c, const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Compute the laplacian of an image.

template<class DestValue, class I, class E> mute< I, DestValue >::ret laplacian (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Compute the laplacian of an image.

template<class I, class E> oln::mute< I >::ret opening (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Perform a morphological opening.

template<class E> mlc::exact< E >::ret get_plus_se_only (const abstract::struct_elt< E > &se)
 Get a sub part of a structuring element.

template<class E> mlc::exact< E >::ret get_plus_se_p (const abstract::struct_elt< E > &se)
 Get a sub part of a structuring element.

template<class E> mlc::exact< E >::ret get_minus_se_only (const abstract::struct_elt< E > &se)
 Get a sub part of a structuring element.

template<class E> mlc::exact< E >::ret get_minus_se_p (const abstract::struct_elt< E > &se)
 Get a sub part of a structuring element.

template<class I, class E> mlc::exact< I >::ret::value_type max (const abstract::non_vectorial_image< I > &input, const typename mlc::exact< I >::ret::point_type &p, const abstract::struct_elt< E > &se)
 Maximum of a structuring element.

template<class I, class E> mlc::exact< I >::ret::value_type min (const abstract::non_vectorial_image< I > &input, const typename mlc::exact< I >::ret::point_type &p, const abstract::struct_elt< E > &se)
 Minimum of a structuring element.

template<class I, class E1, class E2> oln::mute< I >::ret thickening (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E1 > &se1, const abstract::struct_elt< E2 > &se2)
 Thicken an image.

template<class I, class E1, class E2> oln::mute< I >::ret thinning (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E1 > &se1, const abstract::struct_elt< E2 > &se2)
 Thin an image.

template<class C, class B, class I, class E> mute< I, typename convoutput<
C, B, typename mlc::exact<
I >::ret::value_type >::ret
>::ret 
white_top_hat (const convert::abstract::conversion< C, B > &c, const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Compute the white top hat of an image.

template<class I, class E> oln::mute< I >::ret white_top_hat (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Compute the white top hat of an image.

template<class C, class B, class I, class E> mute< I, typename convoutput<
C, B, typename mlc::exact<
I >::ret::value_type >::ret
>::ret 
black_top_hat (const convert::abstract::conversion< C, B > &c, const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Compute the black top hat of an image.

template<class I, class E> oln::mute< I >::ret black_top_hat (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Compute the black top hat of an image.

template<class C, class B, class I, class E> mute< I, typename convoutput<
C, B, typename mlc::exact<
I >::ret::value_type >::ret
>::ret 
self_complementary_top_hat (const convert::abstract::conversion< C, B > &c, const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Compute the self complementary top hat of an image.

template<class I, class E> oln::mute< I >::ret self_complementary_top_hat (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Compute the self complementary top hat of an image.

template<class C, class B, class I, class E> mute< I, typename convoutput<
C, B, typename mlc::exact<
I >::ret::value_type >::ret
>::ret 
top_hat_contrast_op (const convert::abstract::conversion< C, B > &c, const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Top hat contrast operator.

template<class I, class E> oln::mute< I >::ret top_hat_contrast_op (const abstract::non_vectorial_image< I > &input, const abstract::struct_elt< E > &se)
 Top hat contrast operator.

template<class DestValue, class I, class N> mute< I, DestValue >::ret watershed_seg (const abstract::non_vectorial_image< I > &im_i, const abstract::neighborhood< N > &Ng)
 Segmented watershed.

template<class DestValue, class I, class N> mute< I, DestValue >::ret watershed_con (const abstract::non_vectorial_image< I > &im_i, const abstract::neighborhood< N > &Ng)
 Connected watershed.

template<class I1, class I2, class N> oln::mute< I2 >::retwatershed_seg_or (const abstract::non_vectorial_image< I1 > &D, abstract::non_vectorial_image< I2 > &M, const abstract::neighborhood< N > &Ng)
 Segmented watershed with user-supplied starting points.


Detailed Description

Algorithm based on morphological mathematic.

Function Documentation

template<class C, class B, class I, class E>
mute<I, typename convoutput<C, B,typename mlc::exact< I >::ret::value_type>::ret>::ret beucher_gradient const convert::abstract::conversion< C, B > &  c,
const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Process a morphological beucher gradient.

Compute the arithmetic difference between the diltation and the erosion of input using se as structural element. Soille, p67.

  • c Conversion functor.
  • input Image to process.
  • se Structuring element.

Definition at line 79 of file gradient.hh.

template<class I, class E>
oln::mute< I >::ret black_top_hat const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Compute the black top hat of an image.

Parameters:
I Exact type of the image.
E Exact type of the structuring element.
  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/top_hat.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::save(oln::morpho::fast::black_top_hat(im1, oln::win_c8p()), IMG_OUT "oln_morpho_fast_black_top_hat_overload.pbm"); }

lena256_pgm.png
=>
oln_morpho_fast_black_top_hat_overload.png

Definition at line 233 of file top_hat.hh.

template<class C, class B, class I, class E>
mute<I, typename convoutput<C, B,typename mlc::exact< I >::ret::value_type>::ret>::ret black_top_hat const convert::abstract::conversion< C, B > &  c,
const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Compute the black top hat of an image.

Compute black top hat of input using se as structuring element. Soille p.105.

  • c Conversion object.
  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/top_hat.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::save(oln::morpho::fast::black_top_hat (oln::convert::bound<ntg::int_u8>(), im1, oln::win_c8p()), IMG_OUT "oln_morpho_fast_black_top_hat.pbm"); }

lena256_pgm.png
=>
oln_morpho_fast_black_top_hat.png

Definition at line 191 of file top_hat.hh.

template<class I, class E>
oln::mute< I >::ret closing const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Processing closing.

Compute the morphological closing of input using se as structuring element.

Parameters:
I Exact type of the input image.
E Exact type of the structuring element.
  • input Input image to close.
  • se Structuring element to use.
#include <oln/basics2d.hh> #include <oln/morpho/closing.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); save(oln::morpho::closing(im1, oln::win_c8p()), IMG_OUT "oln_morpho_closing.pbm"); return 0; }
object_pbm.png
=>
oln_morpho_closing.png

Definition at line 118 of file closing.hh.

template<class I, class E>
oln::mute< I >::ret dilation const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Processing dilation.

Compute the morphological dilation of input using se as structural element.

On grey-scale images, each point is replaced by the maximum value of its neighbors, as indicated by se. On binary images, a logical or is performed between neighbors.

The morpho::fast version of this function use a different algorithm: This algorithm is described in Implementation of morphological operations from: M. Van Droogenbroeck and H. Talbot. "Fast computation of morphological operations with arbitrary structuring elements". Pattern Recognition Letters, 17(14):1451-1460, 1996.

An histogram of the value of the neighborhood indicated by se is updated while iterating over all point of the image. Doing so is more efficient when the structural element is large.

Parameters:
I Exact type of the input image.
E Exact type of the neighborhood.
  • input The input image.
  • se Structuring element to use.
#include <oln/basics2d.hh> #include <oln/morpho/dilation.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); save(oln::morpho::dilation(im1, oln::win_c8p()), IMG_OUT "oln_morpho_dilation.pbm"); }

object_pbm.png
=>
oln_morpho_dilation.png

Definition at line 92 of file dilation.hh.

References oln::abstract::image< Exact >::border_adapt_copy(), oln::abstract::struct_elt< Exact >::delta(), and oln::abstract::image< Exact >::size().

Referenced by geodesic_dilation(), and n_dilation().

00094     {
00095       mlc::eq<I::dim, E::dim>::ensure();
00096 
00097       oln_concrete_type(I) output(input.size());
00098       input.border_adapt_copy(se.delta());
00099       oln_iter_type(I) p(input);
00100 
00101       for_all (p)
00102         output[p] = morpho::max(input, p, se);
00103       return output;
00104     }

template<class I, class E>
oln::mute< I >::ret erosion const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Perform a morphological erosion.

Compute the morphological erosion of input using se as structuring element.

On grey-scale images, each point is replaced by the minimum value of its neighbors, as indicated by se. On binary images, a logical and is performed between neighbors. The morpho::fast version of this function use a different algorithm: an histogram of the value of the neighborhood indicated by se is updated while iterating over all point of the image. Doing so is more efficient when the structuring element is large.

Parameters:
I Exact type of the input image.
E Exact type of the structuring element.
  • input Input image.
  • se Structuring element to use.
#include <oln/basics2d.hh> #include <oln/morpho/erosion.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); save(oln::morpho::erosion(im1, oln::win_c8p()), IMG_OUT "oln_morpho_erosion.pbm"); }

object_pbm.png
=>
oln_morpho_erosion.png
See also:
oln::morpho::fast::erosion()

Definition at line 86 of file erosion.hh.

References oln::abstract::image< Exact >::border_adapt_copy(), oln::abstract::struct_elt< Exact >::delta(), and oln::abstract::image< Exact >::size().

Referenced by geodesic_erosion(), and n_erosion().

00088     {
00089       mlc::eq<I::dim, E::dim>::ensure();
00090       oln_concrete_type(I) output(input.size());
00091       se.delta();
00092       input.border_adapt_copy(se.delta());
00093       oln_iter_type(I) p(input);
00094       for_all (p)
00095         output[p] = morpho::min(input, p, se);
00096       return output;
00097     }

template<class I, class E>
oln::mute< I >::ret external_gradient const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Process a morphological beucher gradient.

Parameters:
I Exact type of the input image.
E Exact type of the structuring element.
Returns:
The beucher gradient of the input.
  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/gradient.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena128.pgm")); save(oln::morpho::beucher_gradient(im1, oln::win_c8p()), IMG_OUT "oln_morpho_beucher_gradient.pbm"); return 0; } \encode \image html lena128_pgm.png \image latex lena128_pgm.png => \image html oln_morpho_beucher_gradient.png \image latex oln_morpho_beucher_gradient.png */ template<class I, class E> typename oln::mute< I >::ret beucher_gradient(const abstract::non_vectorial_image<I>& input, const abstract::struct_elt<E>& se) { return beucher_gradient(convert::force<typename mlc::exact< I >::ret::value_type>(), input, se); } template<class C, class B, class I, class E> typename mute<I, typename convoutput<C, B,typename mlc::exact< I >::ret::value_type>::ret>::ret internal_gradient(const convert::abstract::conversion<C, B>& c, const abstract::non_vectorial_image<I>& input, const abstract::struct_elt<E>& se) { return arith::minus(c, input, erosion(input, se)); } template<class I, class E> typename oln::mute< I >::ret internal_gradient(const abstract::non_vectorial_image<I>& input, const abstract::struct_elt<E>& se) { return internal_gradient(convert::force<typename mlc::exact< I >::ret::value_type>(), input, se); } template<class C, class B, class I, class E> typename mute<I, typename convoutput<C, B,typename mlc::exact< I >::ret::value_type>::ret>::ret external_gradient(const convert::abstract::conversion<C, B>& c, const abstract::non_vectorial_image<I>& input, const abstract::struct_elt<E>& se) { return arith::minus(c, dilation(input, se), input); }

lena256_pgm.png
=>
oln_morpho_external_gradient.png

Definition at line 252 of file gradient.hh.

template<class I, class N>
oln::mute< I >::ret fast_maxima_killer const abstract::non_vectorial_image< I > &  input,
const unsigned int  area,
const abstract::neighborhood< N > &  Ng
 

Maxima killer.

It removes the small (in area) connected components of the upper level sets of input using Ng as neighboorhood. The implementation is based on stak. Guichard and Morel, Image iterative smoothing and PDE's. Book in preparation. p 265.

See also:
oln::morpho::fast::card_opening.
Parameters:
I Image exact type.
N Neighborhood exact type.
  • input The input image.
  • area Threshold to use.
  • Ng The neighborhood to use.
#include <oln/basics2d.hh> #include <oln/morpho/extrema_killer.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im(oln::load(IMG_IN "lena128.pgm")); oln::save(oln::morpho::fast_maxima_killer(im, 200, oln::neighb_c4()), IMG_OUT "oln_morpho_fast_maxima_killer.pgm"); return 0; }
lena128_pgm.png
=>
oln_morpho_fast_maxima_killer.png
Warning:
Even if it is called fast maxima killer, this algorithm is slow. Please use card closing instead.

Definition at line 486 of file extrema_killer.hh.

References oln::abstract::image< Exact >::clone(), is_a_strict_maximum(), and oln::abstract::image< Exact >::size().

00489     {
00490       mlc::eq<I::dim, N::dim>::ensure();
00491 
00492       std::vector<oln_point_type(I)> cur_maximum;
00493       oln_concrete_type(I) working_input = input.clone();
00494       typename mute<I, ntg::bin>::ret not_processed_map(input.size());
00495       level::fill(not_processed_map, true);
00496 
00497       // STEP 2: search for a local miminum
00498       oln_iter_type(I) p(working_input);
00499       for_all(p)
00500         {
00501           if (is_a_strict_maximum(p.cur(), working_input, Ng)
00502               && not_processed_map[p])
00503             {
00504               cur_maximum.push_back(p);
00505               oln_value_type(I) lambda = working_input[p];
00506 
00507               typename mute<I, ntg::bin>::ret is_visited(input.size());
00508               level::fill(is_visited, false);
00509               is_visited[p] = true;
00510               //STEP 3
00511               bool go_on = true; // FIXME: ditto
00512               while (go_on)
00513                 {
00514                   typedef oln_value_type(I) I_type;
00515                   oln_point_type(I) arg_max = p;
00516                   oln_value_type(I) max =  ntg_min_val(I_type);
00517                   for (unsigned i = 0; i < cur_maximum.size(); ++i)
00518                     {
00519                       oln_neighb_type(N) p_prime(Ng, cur_maximum[i]);
00520                       for_all(p_prime) if (working_input.hold(p_prime) &&
00521                                            (is_visited[p_prime] == false))
00522                         {
00523                           if (working_input[p_prime] >= max)
00524                             {
00525                               max = working_input[p_prime];
00526                               arg_max = p_prime;
00527                             }
00528                         }
00529                     }
00530                   // go to step 4
00531                   if (working_input[arg_max] <= lambda)
00532                     {
00533                       // step 5
00534                       if (cur_maximum.size() < area)
00535                         {
00536                           lambda = working_input[arg_max]; // END MODIF2
00537                           cur_maximum.push_back(arg_max); //MODIF 1
00538                           is_visited[arg_max] = true;
00539                           // go to step 3
00540                         }
00541                       else
00542                         {
00543                           go_on = false;
00544                           //go to step 6
00545                         }
00546                     }
00547                   else
00548                     {
00549                       go_on = false;
00550                       //go to step 6
00551                     }
00552                 } // end while "go on"
00553 
00554               // going  to step 6
00555               for (unsigned i = 0; i < cur_maximum.size(); ++i)
00556                 {
00557                   //          cout << cur_minimum[i] << "   " << lambda << endl;
00558                   working_input[cur_maximum[i]] = lambda;
00559                   not_processed_map[cur_maximum[i]] = false;
00560                 }
00561               cur_maximum.erase(cur_maximum.begin(), cur_maximum.end());
00562 
00563               // STEP 7: look for a new minimum
00564             } // end processing current minimum
00565 
00566         } // END looking for minimum
00567       return working_input;
00568     }

template<class I, class N>
oln::mute< I >::ret fast_minima_killer const abstract::non_vectorial_image< I > &  input,
const unsigned int  area,
const abstract::neighborhood< N > &  Ng
 

Minima killer.

It removes the small (in area) connected components of the lower level sets of input using Ng as neighboorhood. The implementation is based on stak. Guichard and Morel, Image iterative smoothing and PDE's. Book in preparation. p 265.

See also:
oln::morpho::fast::card_closing
Parameters:
I Image exact type.
N Neighborhood exact type.
  • input The input image.
  • area Threshold to use.
  • Ng The neighborhood to use.
#include <oln/basics2d.hh> #include <oln/morpho/extrema_killer.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im(oln::load(IMG_IN "lena128.pgm")); oln::save(oln::morpho::fast_minima_killer(im, 200, oln::neighb_c4()), IMG_OUT "oln_morpho_fast_minima_killer.pgm"); return 0; }
lena128_pgm.png
=>
oln_morpho_fast_minima_killer.png
Warning:
Even if it is called fast minima killer, this algorithm is slow. Please use card opening instead.

Definition at line 359 of file extrema_killer.hh.

References oln::abstract::image< Exact >::clone(), is_a_strict_minimum(), and oln::abstract::image< Exact >::size().

00362     {
00363       mlc::eq<I::dim, N::dim>::ensure();
00364 
00365       std::vector<oln_point_type(I)> cur_minimum;
00366       cur_minimum.reserve(15000);
00367       oln_concrete_type(I) working_input = input.clone();
00368       typename mute<I, ntg::bin>::ret not_processed_map(input.size());
00369       level::fill(not_processed_map, true);
00370 
00371       // STEP 2: search for a local miminum
00372       oln_iter_type(I) p(working_input);
00373       for_all(p)
00374         {
00375           if (is_a_strict_minimum(p.cur(), working_input, Ng)
00376               && not_processed_map[p])
00377             {
00378               cur_minimum.push_back(p);
00379               oln_value_type(I) lambda = working_input[p];
00380 
00381               // FIXME: This should better be moved out of the loop.
00382               typename mute<I, ntg::bin>::ret is_visited(input.size());
00383               level::fill(is_visited, false);
00384               is_visited[p] = true;
00385               //STEP 3
00386               bool go_on = true; // FIXME: Use break instead of go_on = false.
00387               while (go_on)
00388                 {
00389                   typedef oln_value_type(I) I_type;
00390                   oln_point_type(I) arg_min = p;
00391                   oln_value_type(I) min =  ntg_max_val(I_type);
00392                   for (unsigned i = 0; i < cur_minimum.size(); ++i)
00393                     {
00394                       oln_neighb_type(N) p_prime(Ng, cur_minimum[i]);
00395                       for_all(p_prime) if (working_input.hold(p_prime) &&
00396                                            (is_visited[p_prime] == false))
00397                         {
00398                           if (working_input[p_prime] <= min)
00399                             {
00400                               min = working_input[p_prime];
00401                               arg_min = p_prime;
00402                             }
00403                         }
00404                     }
00405                   // go to step 4
00406                   if (working_input[arg_min] >= lambda)
00407                     {
00408                       // step 5
00409                       if (cur_minimum.size() < area)
00410                         {
00411                           lambda = working_input[arg_min]; // END MODIF2
00412                           cur_minimum.push_back(arg_min); //MODIF 1
00413                           is_visited[arg_min] = true;
00414                           // go to step 3
00415                         }
00416                       else
00417                         {
00418                           go_on = false;
00419                           //go to step 6
00420                         }
00421                     }
00422                   else
00423                     {
00424                       go_on = false; //go to step 6
00425                     }
00426                 } // end while "go on"
00427 
00428               // going  to step 6
00429               for (unsigned i = 0; i < cur_minimum.size(); ++i)
00430                 {
00431                   working_input[cur_minimum[i]] = lambda;
00432                   not_processed_map[cur_minimum[i]] = false;
00433                 }
00434               cur_minimum.erase(cur_minimum.begin(), cur_minimum.end());
00435 
00436               // STEP 7: look for a new minimum
00437             } // end processing current minimum
00438 
00439         } // END looking for minimum
00440       return working_input;
00441     }

template<class I, class E, class H>
oln::mute< I >::ret fast_morpho const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Fast morpho algorithm.

Todo:
FIXME: This algorithm should be moved to the namespace oln::morpho::fast.

FIXME: add tests.

#include <oln/basics2d.hh> #include <oln/morpho/erosion.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); save(oln::morpho::fast_morpho<im_type, oln::window2d, oln::utils::histogram_min<ntg::bin> > (im1, oln::win_c8p()), IMG_OUT "oln_morpho_fast_morpho.pbm"); }
object_pbm.png
=>
oln_morpho_fast_morpho.png

Definition at line 316 of file fast_morpho.hxx.

References oln::abstract::image< Exact >::border_adapt_copy(), oln::abstract::struct_elt< Exact >::delta(), and oln::abstract::image< Exact >::size().

00318     {
00319       enum { dim = E::dim };
00320 
00321       // prepare output
00322       oln_concrete_type(I) output(input.size());
00323       input.border_adapt_copy(se.delta());
00324 
00325       // compute delta structuring elements for forward movements
00326       E se_add[dim];
00327       E se_rem[dim];
00328       internal::find_struct_elts(se, se_add, se_rem);
00329 
00330       // compute delta structuring elements for backward movements
00331       E se_add_back[dim];
00332       E se_rem_back[dim];
00333       for (unsigned n = 0; n < dim; ++n)
00334         for (unsigned i = 0; i < se_add[n].card(); ++i)
00335         {
00336           oln_dpoint_type(I) dp = se_add[n].dp(i);
00337           dp.nth(n) += 1;
00338           se_rem_back[n].add(dp);
00339 
00340           dp = se_rem[n].dp(i);
00341           dp.nth(n) += 1;
00342           se_add_back[n].add(dp);
00343         }
00344 
00345       // Order dimensions
00346       unsigned dims[dim];
00347       for (unsigned n = 0; n < dim; ++n)
00348         dims[n] = n;
00349       sort_dimensions<E> s(se_add);
00350       std::sort(dims, dims + dim, s);
00351 
00352       const typename I::size_type size = input.size();
00353 
00354       // Initialize the histogram with the values around the first point.
00355       H hist;
00356       oln_point_type(I) p;
00357 
00358       //     oln_iter_type(E) dp(se);
00359       typename E::iter_type     dp(se);
00360       for_all(dp)
00361         ++hist[input[p + dp]];
00362 
00363       // Process the image.
00364       // ------------------
00365 
00366       output[p] = hist.res();   // First point.
00367 
00368       internal::fast_morpho_inner<1, E::dim, const I,
00369         const typename I::size_type, H,
00370         const E,oln_point_type(I),oln_concrete_type(I)>::doit(input.exact(), size, hist,
00371                                                               se_add, se_rem,
00372                                                               se_add_back, se_rem_back,
00373                                                               p, output, dims);
00374       return output;
00375     }

template<class I, class E>
oln::mute< I >::ret fast_morpho const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se,
typename mlc::exact< I >::ret::value_type(*  func)(const utils::histogram< typename mlc::exact< I >::ret::value_type > &)
[inline]
 

Do not exist !!!

Todo:
FIXME: REMOVE ME.

template<class I1, class I2, class N>
oln::mute< I1 >::ret geodesic_dilation const abstract::non_vectorial_image< I1 > &  marker,
const abstract::non_vectorial_image< I2 > &  mask,
const abstract::neighborhood< N > &  Ng
 

Processing a geodesic dilation.

Parameters:
I1 Exact type of image marker.
I2 Exact type of image mask.
N Exact type of neighborhood.
  • marker Image to work on.
  • mask Image used for geodesic dilation.
  • Ng Neighborhood to use.
Compute the geodesic dilation of marker with respect to the mask image using se as structuring element. Soille p.156.
Precondition:
Mask must be greater or equal than marker.
#include <oln/basics2d.hh> #include <oln/morpho/opening.hh> #include <oln/morpho/geodesic_dilation.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena128.pgm")); im_type im2 = oln::morpho::opening(im1, oln::win_c4p()); save(oln::morpho::geodesic_dilation(im2, im1, oln::neighb_c4()), IMG_OUT "oln_morpho_geodesic_dilation.pbm"); return 0; }

lena128_pgm.png
=>
oln_morpho_geodesic_dilation.png

Definition at line 89 of file geodesic_dilation.hh.

References dilation(), and oln::abstract::image< Exact >::size().

00092     {
00093       mlc::eq<I1::dim, I2::dim>::ensure();
00094       mlc::eq<I1::dim, N::dim>::ensure();
00095       precondition(marker.size() == mask.size());
00096       precondition(level::is_greater_or_equal(mask, marker));
00097       return arith::min<oln_concrete_type(I1)>(dilation(marker,
00098                                                         convert::ng_to_cse(Ng)),
00099                                                mask);
00100     }

template<class I1, class I2, class N>
oln::mute< I1 >::ret geodesic_erosion const abstract::non_vectorial_image< I1 > &  marker,
const abstract::non_vectorial_image< I2 > &  mask,
const abstract::neighborhood< N > &  Ng
 

Processing a geodesic erosion.

Parameters:
I1 Exact type of image marker.
I2 Exact type of image mask.
N Exact type of neighborhood.
  • marker Image to work on.
  • mask Image used for geodesic dilation.
  • Ng Neighborhood to use.
Compute the geodesic erosion of marker with respect to the mask mask image using se as structural element. Soille p.158.

Precondition:
Marker must be greater or equal than mask.
#include <oln/basics2d.hh> #include <oln/morpho/opening.hh> #include <oln/morpho/geodesic_erosion.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena128.pgm")); im_type im2 = oln::morpho::opening(im1, oln::win_c4p()); save(oln::morpho::geodesic_erosion(im1, im2, oln::neighb_c4()), IMG_OUT "oln_morpho_geodesic_erosion.pbm"); return 0; }

lena128_pgm.png
=>
oln_morpho_geodesic_erosion.png

Definition at line 87 of file geodesic_erosion.hh.

References erosion(), and oln::abstract::image< Exact >::size().

00090     {
00091       mlc::eq<I1::dim, I2::dim>::ensure();
00092       mlc::eq<I1::dim, N::dim>::ensure();
00093       precondition(marker.size() == mask.size());
00094       precondition(level::is_greater_or_equal(marker, mask));
00095       return arith::max<oln_concrete_type(I1)>(erosion(marker, convert::ng_to_cse(Ng)), mask);
00096     }

template<class E>
mlc::exact< E >::ret get_minus_se_only const abstract::struct_elt< E > &  se  ) 
 

Get a sub part of a structuring element.

Parameters:
E Exact type of the structuring element.
  • se The structuring element.
A point p take part of the new structuring element if it exists a i that belongs to [[0..dim-1]] like p(i) > 0 and for all j that belongs to [[0..i-1]] p(j) = 0.

Definition at line 120 of file splitse.hh.

00121     {
00122       oln_iter_type(E) dp(se);
00123       E out;
00124 
00125       for_all (dp)
00126         {
00127           unsigned n;
00128           for (n = 0; n < E::dim; ++n)
00129             if (dp.cur().nth(n) > 0) {
00130               out.add(dp);
00131               break;
00132             } else if (dp.cur().nth(n) < 0) {
00133               break;
00134             }
00135         }
00136       return out;
00137     }

template<class E>
mlc::exact< E >::ret get_minus_se_p const abstract::struct_elt< E > &  se  ) 
 

Get a sub part of a structuring element.

Parameters:
E Exact type of the structuring element.
  • se The structuring element.
A point p take part of the new structuring element if it exists a i that belongs to [[0..dim-1]] like p(i) > 0 and for all j that belongs to [[0..i-1]] p(j) = 0 or if for all i that belongs to [[0..dim-1]] p(i) = 0.

Definition at line 154 of file splitse.hh.

Referenced by oln::morpho::hybrid::geodesic_reconstruction_dilation(), oln::morpho::sequential::geodesic_reconstruction_dilation(), oln::morpho::hybrid::geodesic_reconstruction_erosion(), and oln::morpho::sequential::geodesic_reconstruction_erosion().

00155     {
00156       oln_iter_type(E) dp(se);
00157       E out;
00158 
00159       for_all (dp)
00160         {
00161           unsigned n;
00162           for (n = 0; n < E::dim; ++n)
00163             if (dp.cur().nth(n) > 0) {
00164               out.add(dp);
00165               break;
00166             } else if (dp.cur().nth(n) < 0) {
00167               break;
00168             }
00169           // All p.nth(n) are 0.
00170           if (n == E::dim)
00171             out.add(dp);
00172         }
00173       return out;
00174     }

template<class E>
mlc::exact< E >::ret get_plus_se_only const abstract::struct_elt< E > &  se  ) 
 

Get a sub part of a structuring element.

Parameters:
E Exact type of the structuring element.
  • se The structuring element.
A point p take part of the new structuring element if it exists a i that belongs to [[0..dim-1]] like p(i) < 0 and for all j that belongs to [[0..i-1]] p(j) = 0.

Definition at line 50 of file splitse.hh.

00051     {
00052       oln_iter_type(E) dp(se);
00053       E out;
00054 
00055       for_all (dp)
00056         {
00057           unsigned n;
00058           for (n = 0; n < E::dim; ++n)
00059             if (dp.cur().nth(n) < 0) {
00060               out.add(dp);
00061               break;
00062             } else if (dp.cur().nth(n) > 0) {
00063               break;
00064             }
00065         }
00066       return out;
00067     }

template<class E>
mlc::exact< E >::ret get_plus_se_p const abstract::struct_elt< E > &  se  ) 
 

Get a sub part of a structuring element.

Parameters:
E Exact type of the structuring element.
  • se The structuring element.
A point p take part of the new structuring element if it exists a i that belongs to [[0..dim-1]] like p(i) < 0 and for all j that belongs to [[0..i-1]] p(j) = 0 or if for all i that belongs to [[0..dim-1]] p(i) = 0.

Definition at line 84 of file splitse.hh.

Referenced by oln::morpho::hybrid::geodesic_reconstruction_dilation(), oln::morpho::sequential::geodesic_reconstruction_dilation(), oln::morpho::hybrid::geodesic_reconstruction_erosion(), and oln::morpho::sequential::geodesic_reconstruction_erosion().

00085     {
00086       oln_iter_type(E) dp(se);
00087       E out;
00088 
00089       for_all (dp)
00090         {
00091           unsigned n;
00092           for (n = 0; n < E::dim; ++n)
00093             if (dp.cur().nth(n) < 0) {
00094               out.add(dp);
00095               break;
00096             } else if (dp.cur().nth(n) > 0) {
00097               break;
00098             }
00099           // All p.nth(n) are 0.
00100           if (n == E::dim)
00101             out.add(dp);
00102         }
00103       return out;
00104     }

template<class I, class E1, class E2>
oln::mute< I >::ret hit_or_miss const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E1 > &  se1,
const abstract::struct_elt< E2 > &  se2
 

Preform a 'hit or miss' transform.

Parameters:
I Exact type of the input image.
E1 Exact type of the first structuring element.
E2 Exact type of the second structuring element.
  • input Image to process.
  • se1 First structuring element.
  • se2 Second structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/hit_or_miss.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); oln::window2d mywin; mywin .add(-3,-2).add(-3,-1).add(-3,0).add(-3,1).add(-3,2) .add(-2,-1).add(-2,0).add(-2,1) .add(-1,0); oln::window2d mywin2 = - mywin; oln::save(oln::morpho::fast::hit_or_miss(im1, mywin, mywin2), IMG_OUT "oln_morpho_fast_hit_or_miss_overload.pbm"); }

object_pbm.png
=>
oln_morpho_fast_hit_or_miss_overload.png

Definition at line 184 of file hit_or_miss.hh.

template<class C, class B, class I, class E1, class E2>
mute<I, typename convoutput<C, B,typename mlc::exact< I >::ret::value_type>::ret>::ret hit_or_miss const convert::abstract::conversion< C, B > &  c,
const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E1 > &  se1,
const abstract::struct_elt< E2 > &  se2
 

Preform a 'hit or miss' transform.

  • c Conversion object.
  • input Image to process.
  • se1 First structuring element.
  • se2 Second structuring element.
Compute the hit_or_miss transform of input by the composite structuring element (se1, se2). Soille p.131.

By definition se1 and se2 must have the same origin, and need to be disjoint. This algorithm has been extended to every data types (although it is not increasing). Beware the result depends upon the image data type if it is not bin.

#include <oln/basics2d.hh> #include <oln/morpho/hit_or_miss.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); oln::window2d mywin; mywin .add(-3,-2).add(-3,-1).add(-3,0).add(-3,1).add(-3,2) .add(-2,-1).add(-2,0).add(-2,1) .add(-1,0); oln::window2d mywin2 = - mywin; oln::save(oln::morpho::fast::hit_or_miss (oln::convert::bound<ntg::int_u8>(), im1, mywin, mywin2), IMG_OUT "oln_morpho_fast_hit_or_miss.pbm"); }

object_pbm.png
=>
oln_morpho_fast_hit_or_miss.png

Definition at line 122 of file hit_or_miss.hh.

template<class I, class E1, class E2>
oln::mute< I >::ret hit_or_miss_closing const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E1 > &  se1,
const abstract::struct_elt< E2 > &  se2
 

Perform an hit or miss closing.

Compute the hit_or_miss closing of input by the composite structuring element (se1, se2). This is the dual transformation of hit-or-miss opening with respect to set complementation. Soille p.135.

By definition se1 and se2 must have the same origin, and need to be disjoint. This algorithm has been extended to every data types (althought it is not increasing). Beware the result depends upon the image data type if it is not bin.

Parameters:
I Exact type of the input image.
E1 Exact type of the first structuring element.
E2 Exact type of the second structuring element.
  • input Image to process.
  • se1 First structuring element.
  • se2 Second structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/hit_or_miss.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); oln::window2d mywin; mywin .add(-3,-2).add(-3,-1).add(-3,0).add(-3,1).add(-3,2) .add(-2,-1).add(-2,0).add(-2,1) .add(-1,0); oln::window2d mywin2 = - mywin; oln::save(oln::morpho::fast::hit_or_miss_closing(im1, mywin, mywin2), IMG_OUT "oln_morpho_fast_hit_or_miss_closing.pbm"); }

object_pbm.png
=>
oln_morpho_fast_hit_or_miss_closing.png

Definition at line 374 of file hit_or_miss.hh.

template<class I, class E1, class E2>
oln::mute< I >::ret hit_or_miss_closing_bg const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E1 > &  se1,
const abstract::struct_elt< E2 > &  se2
 

Perform an hit or miss closing of background.

Compute the hit_or_miss closing of the background of input by the composite structuring element (se1, se2). This is the dual transformation of hit-or-miss opening with respect to set complementation. Soille p.135.

By definition se1 and se2 must have the same origin, and need to be disjoint. This algorithm has been extended to every data types (althought it is not increasing). Beware the result depends upon the image data type if it is not bin.

Parameters:
I Exact type of the input image.
E1 Exact type of the first structuring element.
E2 Exact type of the second structuring element.
  • input Image to process.
  • se1 First structuring element.
  • se2 Second structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/hit_or_miss.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); oln::window2d mywin; mywin .add(-3,-2).add(-3,-1).add(-3,0).add(-3,1).add(-3,2) .add(-2,-1).add(-2,0).add(-2,1) .add(-1,0); oln::window2d mywin2 = - mywin; oln::save(oln::morpho::fast::hit_or_miss_closing_bg(im1, mywin, mywin2), IMG_OUT "oln_morpho_fast_hit_or_miss_closing_bg.pbm"); }

object_pbm.png
=>
oln_morpho_fast_hit_or_miss_closing_bg.png

Definition at line 437 of file hit_or_miss.hh.

template<class I, class E1, class E2>
oln::mute< I >::ret hit_or_miss_opening const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E1 > &  se1,
const abstract::struct_elt< E2 > &  se2
 

Perform an hit or miss opening.

Compute the hit_or_miss opening of input by the composite structuring element (se1, se2). Soille p.134.

By definition se1 and se2 must have the same origin, and need to be disjoint. This algorithm has been extended to every data types (althought it is not increasing). Beware the result depends upon the image data type if it is not bin.

Parameters:
I Exact type of the input image.
E1 Exact type of the first structuring element.
E2 Exact type of the second structuring element.
  • input Image to process.
  • se1 First structuring element.
  • se2 Second structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/hit_or_miss.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); oln::window2d mywin; mywin .add(-3,-2).add(-3,-1).add(-3,0).add(-3,1).add(-3,2) .add(-2,-1).add(-2,0).add(-2,1) .add(-1,0); oln::window2d mywin2 = - mywin; oln::save(oln::morpho::fast::hit_or_miss_opening(im1, mywin, mywin2), IMG_OUT "oln_morpho_fast_hit_or_miss_opening.pbm"); }

object_pbm.png
=>
oln_morpho_fast_hit_or_miss_opening.png

Definition at line 248 of file hit_or_miss.hh.

template<class I, class E1, class E2>
oln::mute< I >::ret hit_or_miss_opening_bg const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E1 > &  se1,
const abstract::struct_elt< E2 > &  se2
 

Perform an hit or miss opening of background.

Compute the hit_or_miss opening of the background of input by the composite structuring element (se1, se2). Soille p.135.

By definition se1 and se2 must have the same origin, and need to be disjoint. This algorithm has been extended to every data types (although it is not increasing). Beware the result depends upon the image data type if it is not bin.

Parameters:
I Exact type of the input image.
E1 Exact type of the first structuring element.
E2 Exact type of the second structuring element.
  • input Image to process.
  • se1 First structuring element.
  • se2 Second structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/hit_or_miss.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); oln::window2d mywin; mywin .add(-3,-2).add(-3,-1).add(-3,0).add(-3,1).add(-3,2) .add(-2,-1).add(-2,0).add(-2,1) .add(-1,0); oln::window2d mywin2 = - mywin; oln::save(oln::morpho::fast::hit_or_miss_opening_bg(im1, mywin, mywin2), IMG_OUT "oln_morpho_fast_hit_or_miss_opening_bg.pbm"); }

object_pbm.png
=>
oln_morpho_fast_hit_or_miss_opening_bg.png

Definition at line 308 of file hit_or_miss.hh.

template<class I, class N>
mute<I, ntg::bin>::ret internal_kill_cc_area const abstract::binary_image_with_dim< 2, I > &  input,
const unsigned int  area,
const abstract::neighborhood< N > &  Ng
 

Kill connex components smaller than a given area.

Parameters:
I E xact type of the input image.
N Exact type of the neighborhood.
  • input The input image.
  • area The threshold to use.
  • Ng The neighborhood to use.

Definition at line 63 of file extrema_killer.hh.

References oln::level::hlut_def< T, T2 >::set().

Referenced by sure_maxima_killer(), and sure_minima_killer().

00066     {
00067       typename mute<I, ntg::int_u<20> >::ret cc = level::connected_component<ntg::int_u<20> >(input, Ng);
00068       // label 0 is background
00069       ntg::int_u<20> max_label = 0;
00070       image2d<ntg::int_u<20> >::iter_type p(cc);
00071       for_all(p)
00072         if (cc[p] > max_label)
00073           max_label = cc[p];
00074       level::hlut_def<ntg::int_u<20> > region_area;
00075       for_all(p)
00076         region_area.set(cc[p], ntg::cast::force<ntg::int_u<20> >(region_area(cc[p]) + 1));
00077       image2d<ntg::bin> output(input.size());
00078       for_all(p)
00079         if (input[p] == true)
00080           {
00081             if (region_area(cc[p]) >= ntg::int_u<20> (area))
00082               output[p] = true;
00083             else
00084               output[p] = false;
00085           }
00086         else
00087           output[p] = false;
00088       return output;
00089     }

template<class P, class I, class N>
bool is_a_strict_maximum const abstract::point< P > &  p,
const abstract::non_vectorial_image< I > &  input,
const abstract::neighborhood< N > &  Ng
[static]
 

Check if a point is a strict maximum.

Parameters:
P Exact type of the point.
I Exact type of the image.
N Exact type of the neighborhood.
  • p The point to consider.
  • input The image where to get the value of the point to consider.
  • Ng Type of neighborhood to use.

Definition at line 295 of file extrema_killer.hh.

References oln::abstract::image< Exact >::hold().

Referenced by fast_maxima_killer().

00298     {
00299       mlc::eq<I::dim, N::dim>::ensure();
00300       mlc::eq<P::dim, N::dim>::ensure();
00301 
00302       bool is_p_upper = true;
00303       bool is_p_at_least_one_stricly_upper = false;
00304       oln_neighb_type(N) p_prime(Ng, p);
00305       for_all(p_prime) if (input.hold(p_prime))
00306         {
00307           if (input[p] > input[p_prime])
00308             is_p_at_least_one_stricly_upper = true;
00309           if (input[p] < input[p_prime])
00310             is_p_upper = false;
00311         }
00312       return (is_p_upper && is_p_at_least_one_stricly_upper);
00313     }

template<class P, class I, class N>
bool is_a_strict_minimum const abstract::point< P > &  p,
const abstract::non_vectorial_image< I > &  input,
const abstract::neighborhood< N > &  Ng
[static]
 

Check if a point is a strict minimum.

Parameters:
P Exact type of the point.
I Exact type of the image.
N Exact type of the neighborhood.
  • p The point to consider.
  • input The image where to get the value of the point to consider.
  • Ng Type of neighborhood to use.

Definition at line 260 of file extrema_killer.hh.

References oln::abstract::image< Exact >::hold().

Referenced by fast_minima_killer().

00263     {
00264       mlc::eq<I::dim, N::dim>::ensure();
00265       mlc::eq<P::dim, N::dim>::ensure();
00266 
00267       bool is_p_lower = true;
00268       bool is_p_at_least_one_stricly_lower = false;
00269       oln_neighb_type(N) p_prime(Ng, p);
00270       for_all(p_prime) if (input.hold(p_prime))
00271         {
00272           if (input[p] < input[p_prime])
00273             is_p_at_least_one_stricly_lower = true;
00274           if (input[p] > input[p_prime])
00275             is_p_lower = false;
00276         }
00277       return (is_p_lower && is_p_at_least_one_stricly_lower);
00278     }

template<class DestValue, class I, class E>
mute<I, DestValue>::ret laplacian const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Compute the laplacian of an image.

Compute the laplacian of input using se as structural element.

  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/laplacian.hh> #include <oln/convert/stretch.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::image2d<ntg::int_s<10> > i10 = oln::morpho::fast::laplacian(oln::convert::bound<ntg::int_s<10> >(), im1, oln::win_c8p()); oln::image2d<ntg::int_s<10> > f10 = oln::morpho::fast::laplacian<ntg::int_s<10> >(im1, oln::win_c8p()); oln::save(apply(oln::convert::stretch<ntg::int_u8>(),(f10)), IMG_OUT "oln_morpho_fast_laplacian_overload.pgm"); }

lena256_pgm.png
=>
oln_morpho_fast_laplacian_overload.png

Todo:
FIXME: Not instantiated in swilena (see tools/swilena/generate_morpho_instantiations.py)

Definition at line 158 of file laplacian.hh.

template<class C, class B, class I, class E>
mute<I, typename convoutput<C, B,typename mlc::exact< I >::ret::value_type>::ret>::ret laplacian const convert::abstract::conversion< C, B > &  c,
const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Compute the laplacian of an image.

Compute the laplacian of input using se as structural element.

  • c Conversion object.
  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/laplacian.hh> #include <oln/convert/stretch.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::image2d<ntg::int_s<10> > i10 = oln::morpho::fast::laplacian(oln::convert::bound<ntg::int_s<10> >(), im1, oln::win_c8p()); oln::save(apply(oln::convert::stretch<ntg::int_u8>(), i10), IMG_OUT "oln_morpho_fast_laplacian.pgm"); }

lena256_pgm.png
=>
oln_morpho_fast_laplacian.png

Definition at line 105 of file laplacian.hh.

template<class I, class E>
mlc::exact< I >::ret::value_type max const abstract::non_vectorial_image< I > &  input,
const typename mlc::exact< I >::ret::point_type &  p,
const abstract::struct_elt< E > &  se
 

Maximum of a structuring element.

Look for the maximum in the structuring element se disposed on the image input, at the point p.

Parameters:
I Image exact type.
E Structuring element type.
  • input Input image.
  • p Point of the image to move the structuring element on.
  • se The structuring element to use.

Definition at line 148 of file morpho/stat.hh.

00151     {
00152       mlc::eq<I::dim, E::dim>::ensure();
00153       return internal::stat_<I, E>::max(input.exact(), p, se.exact());
00154     }

template<class I, class E>
mlc::exact< I >::ret::value_type min const abstract::non_vectorial_image< I > &  input,
const typename mlc::exact< I >::ret::point_type &  p,
const abstract::struct_elt< E > &  se
 

Minimum of a structuring element.

**

Look for the minimum in the structuring element se disposed on the image input, at the point p.

Parameters:
I Image exact type.
E Structuring element type.
  • input Input image.
  • p Point of the image to move the structuring element on.
  • se The structuring element to use.

Definition at line 170 of file morpho/stat.hh.

00174     {
00175       mlc::eq<I::dim, E::dim>::ensure();
00176       return internal::stat_<I, E>::min(input.exact(), p, se.exact());
00177     }

template<class I, class E>
oln::mute< I >::ret n_dilation const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se,
unsigned  n
 

Perform morphological dilation iterated n times.

Parameters:
I Exact type of the input image.
E Exact type of the structuring element.
  • input Input image.
  • se Structuring element to use.
  • n Number of iterations.
#include <oln/basics2d.hh> #include <oln/morpho/dilation.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); save(oln::morpho::n_dilation(im1, oln::win_c8p(), 5), IMG_OUT "oln_morpho_n_dilation.pbm"); }

object_pbm.png
=>
oln_morpho_n_dilation.png

Definition at line 141 of file dilation.hh.

References oln::abstract::image< Exact >::clone(), and dilation().

00144     {
00145       precondition(n > 0);
00146       oln_concrete_type(I) output = input.clone();
00147       for (unsigned i = 0; i < n; ++i)
00148         {
00149          oln_concrete_type(I) work = dilation(output, se);
00150           output = work;
00151         }
00152       return output;
00153     }

template<class I, class E>
oln::mute< I >::ret n_erosion const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se,
unsigned  n
 

Perform morphological erosion iterated n times.

Parameters:
I Exact type of the input image.
E Exact type of the structuring element.
  • input Input image.
  • se Structuring element to use.
  • n Number of iterations.
#include <oln/basics2d.hh> #include <oln/morpho/erosion.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im1(oln::load(IMG_IN "object.pbm")); save(oln::morpho::n_erosion(im1, oln::win_c8p(), 5), IMG_OUT "oln_morpho_n_erosion.pbm"); }

object_pbm.png
=>
oln_morpho_n_erosion.png

Definition at line 134 of file erosion.hh.

References oln::abstract::image< Exact >::clone(), and erosion().

00137     {
00138       //mlc::eq<I::dim, E::dim>::ensure();
00139       precondition(n > 0);
00140       oln_concrete_type(I) output = input.clone();
00141       for (unsigned i = 0; i < n; ++i)
00142         {
00143           oln_concrete_type(I) work = erosion(output, se);
00144           output = work;
00145         }
00146       return output;
00147     }

template<class I, class E>
oln::mute< I >::ret opening const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Perform a morphological opening.

Compute the morphological opening of input using se as structuring element.

Parameters:
I Exact type of the input image.
E Exact type of the structuring element.
  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/opening.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::bin> im_type; im_type im(oln::load(IMG_IN "object.pbm")); oln::save(oln::morpho::fast::opening(im, oln::win_c8p()), IMG_OUT "oln_morpho_fast_opening.pbm"); }

object_pbm.png
=>
oln_morpho_fast_opening.png

Definition at line 102 of file opening.hh.

template<class I, class E>
oln::mute< I >::ret self_complementary_top_hat const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Compute the self complementary top hat of an image.

  • c Conversion object.
  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/top_hat.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::save(oln::morpho::fast::self_complementary_top_hat(im1, oln::win_c8p()), IMG_OUT "oln_morpho_fast_self_complementary_top_hat_overload.pbm"); }

lena256_pgm.png
=>
oln_morpho_fast_self_complementary_top_hat_overload.png

Definition at line 323 of file top_hat.hh.

template<class C, class B, class I, class E>
mute<I, typename convoutput<C, B,typename mlc::exact< I >::ret::value_type>::ret>::ret self_complementary_top_hat const convert::abstract::conversion< C, B > &  c,
const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Compute the self complementary top hat of an image.

Compute self complementary top hat of input using se as structuring element. Soille p.106.

  • c Conversion object.
  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/top_hat.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::save(oln::morpho::fast::self_complementary_top_hat (oln::convert::bound<ntg::int_u8>(), im1, oln::win_c8p()), IMG_OUT "oln_morpho_fast_self_complementary_top_hat.pbm"); }

lena256_pgm.png
=>
oln_morpho_fast_self_complementary_top_hat.png

Definition at line 283 of file top_hat.hh.

template<class I, class N>
oln::mute< I >::ret sure_maxima_killer const abstract::non_vectorial_image< I > &  input,
const unsigned int  area,
const abstract::neighborhood< N > &  Ng
 

Maxima killer.

It removes the small (in area) connected components of the upper level sets of input using se as structuring element. The implementation uses the threshold superposition principle; so it is very slow ! it works only for int_u8 images.

Parameters:
I Image exact type.
N Neighborhood exact type.
  • input The input image.
  • area Threshold to use.
  • Ng The neighborhood to use.
#include <oln/basics2d.hh> #include <oln/morpho/extrema_killer.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im(oln::load(IMG_IN "lena128.pgm")); oln::save(oln::morpho::sure_maxima_killer(im, 200, oln::neighb_c4()), IMG_OUT "oln_morpho_sure_maxima_killer.pgm"); return 0; }
lena128_pgm.png
=>
oln_morpho_sure_maxima_killer.png

Definition at line 132 of file extrema_killer.hh.

References internal_kill_cc_area(), and oln::abstract::image< Exact >::size().

00135     {
00136       mlc::eq<I::dim, N::dim>::ensure();
00137       typedef typename mute<I, ntg::bin >::ret ima_bin_type;
00138 
00139       ima_bin_type* cc_level_sets = new (image2d<ntg::bin> [256]);
00140       for (unsigned int i=0; i <= 255; ++i)
00141         {
00142           image2d<ntg::bin> level_sets_i(input.size());
00143           image2d<ntg::int_u8>::iter_type p(input);
00144           for_all(p)
00145             if (input[p] >=oln_value_type(I) (i))
00146               level_sets_i[p] = true;
00147             else
00148               level_sets_i[p] = false;
00149           cc_level_sets[i] = internal_kill_cc_area(level_sets_i, area, Ng);
00150         }
00151       image2d<ntg::int_u8> output(input.size());
00152       for (int i=0; i < 255 ; ++i)
00153         {
00154           image2d<ntg::int_u8>::iter_type p(input);
00155           for_all(p)
00156             {
00157               if ((cc_level_sets[i])[p] == true)
00158                 output[p] = i;
00159             }
00160         }
00161       delete[] cc_level_sets;
00162 
00163       return output;
00164     }

template<class I, class N>
image2d<ntg::int_u8> sure_minima_killer const abstract::non_vectorial_image< I > &  input,
const unsigned int  area,
const abstract::neighborhood< N > &  Ng
 

Minima killer.

It removes the small (in area) connected components of the lower level sets of input using se as structuring element. The implementation uses the threshold superposition principle; so it is very slow ! it works only for int_u8 images.

Parameters:
I Image exact type.
N Neighborhood exact type.
  • input The input image.
  • area Threshold to use.
  • Ng The neighborhood to use.
#include <oln/basics2d.hh> #include <oln/morpho/extrema_killer.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im(oln::load(IMG_IN "lena128.pgm")); oln::save(oln::morpho::sure_minima_killer(im, 200, oln::neighb_c4()), IMG_OUT "oln_morpho_sure_minima_killer.pgm"); return 0; }
lena128_pgm.png
=>
oln_morpho_sure_minima_killer.png

Definition at line 205 of file extrema_killer.hh.

References internal_kill_cc_area(), and oln::abstract::image< Exact >::size().

00208     {
00209       mlc::eq<I::dim, N::dim>::ensure();
00210 
00211       typedef image2d<ntg::bin> ima_bin_type;
00212 
00213       ima_bin_type* cc_level_sets = new (image2d<ntg::bin> [256]);
00214       for (unsigned int i=0; i <= 255; ++i)
00215         {
00216           image2d<ntg::bin> level_sets_i(input.size());
00217           image2d<ntg::int_u8>::iter_type p(input);
00218           for_all(p)
00219             if (input[p] <=oln_value_type(I) (i))
00220               level_sets_i[p] = true;
00221             else
00222               level_sets_i[p] = false;
00223           cc_level_sets[i] = internal_kill_cc_area(level_sets_i, area, Ng);
00224         }
00225       image2d<ntg::int_u8> output(input.size());
00226       for (int i=255; i >= 0 ; --i)
00227         {
00228           image2d<ntg::int_u8>::iter_type p(input);
00229           for_all(p)
00230             {
00231               if ((cc_level_sets[i])[p] == true)
00232                 output[p] = i;
00233             }
00234         }
00235       delete[] cc_level_sets;
00236 
00237       return output;
00238     }

template<class I, class E1, class E2>
oln::mute< I >::ret thickening const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E1 > &  se1,
const abstract::struct_elt< E2 > &  se2
 

Thicken an image.

Parameters:
I Exact type of the image.
E1 Exact type of the first structuring element.
E2 Exact type of the second structuring element.
  • input Image to process.
  • se1 First structuring element.
  • se2 Second structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/thickening.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::save(oln::morpho::fast::thickening(im1, oln::win_c8p(), oln::win_c8p()), IMG_OUT "oln_morpho_fast_thickening.pbm"); return 0; }

lena256_pgm.png
=>
oln_morpho_fast_thickening.png

Definition at line 106 of file thickening.hh.

template<class I, class E1, class E2>
oln::mute< I >::ret thinning const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E1 > &  se1,
const abstract::struct_elt< E2 > &  se2
 

Thin an image.

Parameters:
I Exact type of the image.
E1 Exact type of the first structuring element.
E2 Exact type of the second structuring element.
  • input Image to process.
  • se1 First structuring element.
  • se2 Second structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/thinning.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::save(oln::morpho::fast::thinning(im1, oln::win_c8p(), oln::win_c8p()), IMG_OUT "oln_morpho_fast_thinning.pbm"); return 0; }

lena256_pgm.png
=>
oln_morpho_fast_thinning.png

Definition at line 106 of file thinning.hh.

template<class I, class E>
oln::mute< I >::ret top_hat_contrast_op const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Top hat contrast operator.

Enhance contrast input by adding the white top hat, then subtracting the black top hat to input. Top hats are computed using se as structuring element. Soille p.109.

  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/top_hat.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::save(oln::morpho::fast::top_hat_contrast_op(im1, oln::win_c8p()), IMG_OUT "oln_morpho_fast_top_hat_contrast_op_overload.pbm"); }

lena256_pgm.png
=>
oln_morpho_fast_top_hat_contrast_op_overload.png

Definition at line 418 of file top_hat.hh.

template<class C, class B, class I, class E>
mute<I, typename convoutput<C, B,typename mlc::exact< I >::ret::value_type>::ret>::ret top_hat_contrast_op const convert::abstract::conversion< C, B > &  c,
const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Top hat contrast operator.

Enhance contrast input by adding the white top hat, then subtracting the black top hat to input. Top hats are computed using se as structuring element. Soille p.109.

  • c Conversion object.
  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/top_hat.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::save(oln::morpho::fast::top_hat_contrast_op (oln::convert::bound<ntg::int_u8>(), im1, oln::win_c8p()), IMG_OUT "oln_morpho_fast_top_hat_contrast_op.pbm"); }

lena256_pgm.png
=>
oln_morpho_fast_top_hat_contrast_op.png

Definition at line 371 of file top_hat.hh.

template<class DestValue, class I, class N>
mute< I, DestValue >::ret oln::morpho::watershed_con const abstract::non_vectorial_image< I > &  im_i,
const abstract::neighborhood< N > &  Ng
 

Connected watershed.

Compute the connected watershed for image im using neighborhood ng.

watershed_con creates an ouput image whose values have type DestValue (which should be discrete). In this output all basins are labeled using values from DestValue::min() to DestValue::max() - 4 (the remaining values are used internally by the algorithm).

When there are more basins than DestValue can hold, wrapping occurs (i.e., the same label is used for several basin). This is potentially harmful, because if two connected basins are labeled with the same value they will appear as one basin.

This is based on the original algorithm presented by Vincent and Soille, but modified to not output watersheds.

Parameters:
DestValue Type of the data in output image.
I Exact type of the image.
N Exact type of the neighborhood.
  • input Image of levels.
  • Ng Neighborhood to consider.
Precondition:
DestValue should be large enough.
#include <oln/basics2d.hh> #include <oln/morpho/watershed.hh> #include <ntg/all.hh> #include <oln/morpho/attribute_closing_opening.hh> #include <oln/morpho/gradient.hh> #include <oln/convert/stretch.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); // Gradient of the image im1 = oln::morpho::beucher_gradient(im1, oln::win_c8p()); // Remove local minima smaller than 200 pixels im1 = oln::morpho::fast::card_closing(im1, oln::neighb_c8(), 200); oln::save(im1, IMG_OUT "oln_morpho_watershed_con_tmp.pgm"); // Use the watershed to conment the image im_type w = oln::morpho::watershed_con<ntg::int_u8>(im1, oln::neighb_c8()); oln::save(oln::convert::stretch_balance<ntg::int_u8>(w), IMG_OUT "oln_morpho_watershed_con.pgm"); }

lena256_pgm.png
=>
oln_morpho_watershed_con_tmp.png
=>
oln_morpho_watershed_con.png

Definition at line 286 of file watershed.hxx.

00287     {
00288       return internal::soille_watershed_<
00289         internal::watershed_con_point_handler_, DestValue> (im_i, Ng);
00290     }
00291 

template<class DestValue, class I, class N>
mute< I, DestValue >::ret oln::morpho::watershed_seg const abstract::non_vectorial_image< I > &  im_i,
const abstract::neighborhood< N > &  Ng
 

Segmented watershed.

Compute the segmented watershed for image im using neighborhood ng.

watershed_seg creates an ouput image whose values have type DestValue (which should be discrete). In this output image, DestValue::max() indicates a watershed, and all basins are labeled using values from DestValue::min() to DestValue::max() - 4 (the remaining values are used internally by the algorithm).

When there are more basins than DestValue can hold, wrapping occurs (i.e., the same label is used for several basin).

This is based on the original algorithm presented by Vincent and Soille. (FIXME: ref?)

Parameters:
DestValue Type of the data in output image.
I Exact type of the image.
N Exact type of the neighborhood.
  • im_i Image of levels.
  • Ng Neighborhood to consider.
Precondition:
DestValue should be large enough.
#include <oln/basics2d.hh> #include <oln/morpho/watershed.hh> #include <ntg/all.hh> #include <oln/morpho/attribute_closing_opening.hh> #include <oln/morpho/gradient.hh> #include <oln/convert/stretch.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); // Gradient of the image im1 = oln::morpho::beucher_gradient(im1, oln::win_c8p()); // Remove local minima smaller than 200 pixels im1 = oln::morpho::fast::card_closing(im1, oln::neighb_c8(), 200); oln::save(im1, IMG_OUT "oln_morpho_watershed_seg_tmp.pgm"); // Use the watershed to segment the image im_type w = oln::morpho::watershed_seg<ntg::int_u8>(im1, oln::neighb_c8()); oln::save(oln::convert::stretch_balance<ntg::int_u8>(w), IMG_OUT "oln_morpho_watershed_seg.pgm"); }

lena256_pgm.png
=>
oln_morpho_watershed_seg_tmp.png
=>
oln_morpho_watershed_seg.png

Definition at line 277 of file watershed.hxx.

00278     {
00279       return internal::soille_watershed_<
00280         internal::watershed_seg_point_handler_, DestValue> (im_i, Ng);
00281     }
00282 

template<class I1, class I2, class N>
oln::mute< I2 >::ret & oln::morpho::watershed_seg_or const abstract::non_vectorial_image< I1 > &  D,
abstract::non_vectorial_image< I2 > &  M,
const abstract::neighborhood< N > &  Ng
[inline]
 

Segmented watershed with user-supplied starting points.

Compute a segmented watershed for image levels using neighborhood ng, and markers as starting point for the flooding algorithm.

markers is an image of the same size as levels and containing discrete values indicating label associated to each basin. On input, fill markers with oln_value_type(I2)min() (this is the unknown label) and mark the starting points or regions (usually these are minima in levels) using a value between oln_value_type(I2)min() + 1 and oln_value_type(I2)max() - 1.

watershed_seg_or will flood levels from these non-unknown starting points, labeling basins using the value you assigned to them, and markining watershed lines with oln_value_type(I2)max(). markers should not contains any oln_value_type(I2)min() value on output.

This is based on the original algorithm presented by D'Ornellas et al. (FIXME: ref?)

Parameters:
I1 Exact type of the D image.
I2 Exact type of the M image.
N Exact type of the neighborhood.
  • D Input image.
  • M Image of labels.
  • Ng Neighborhood to consider.

Todo:
FIXME: Not instantiated in swilena (see tools/swilena/generate_morpho_instantiations.py)

Definition at line 314 of file watershed.hxx.

References oln::abstract::image< Exact >::hold().

00316     {
00317 
00318       typedef oln_value_type(I2) value_type;
00319       const oln_value_type(I2) wshed   = ntg_max_val(value_type);
00320       const oln_value_type(I2) unknown = ntg_min_val(value_type);
00321 
00322       typedef std::pair<oln_point_type(I1), oln_value_type(I1)> queue_elt_type;
00323       std::priority_queue< queue_elt_type, std::vector< queue_elt_type >,
00324         cmp_queue_elt<I1> > PQ;
00325 
00326       // Initialization
00327       // Enqueue all labeled points which have a unlabeled neighbor.
00328       {
00329         oln_iter_type(I2) p(Labels);
00330         oln_neighb_type(N) p_prime(Ng, p);
00331         for_all(p)
00332           if (Labels[p] != unknown)
00333             for_all (p_prime)
00334               if (Labels.hold(p_prime) && Labels[p_prime] == unknown)
00335                 {
00336                   PQ.push(queue_elt_type(p, In[p]));
00337                   break;
00338                 }
00339       }
00340 
00341       // Propagation
00342 
00343       oln_point_type(I1) p;
00344       oln_neighb_type(N) p_prime(Ng, p);
00345       oln_neighb_type(N) p_second(Ng, p_prime);
00346       while (! PQ.empty())
00347         {
00348           // Get the lowest point in the queue.
00349           p = PQ.top().first;
00350           PQ.pop();
00351           // Consider all neighbors of p.
00352           for_all (p_prime) if (Labels.hold(p_prime))
00353             {
00354               // Focus on unlabeled neighbors of p.
00355               if (Labels[p_prime] == unknown)
00356                 {
00357                   // Since p_prime is a neighbor of p, it should
00358                   // be either labeled using the same label as p,
00359                   // or marked as watershed.
00360 
00361                   // It's a watershed if, among the neighbors of
00362                   // p_prime (which itself is a neighbor of p), there
00363                   // exists a point with a label different from the
00364                   // label of pt.  EXISTS is set to true in this case.
00365                   bool exists = false;
00366                   for_all (p_second)
00367                     // FIXME: We should not need the iterate over
00368                     // the neighbors of p_prime which are also
00369                     // neighbors of p, since none of these can have
00370                     // have a different label.  It should be possible
00371                     // to precompute an array of the resulting windows
00372                     // for each neighbor (of p).
00373                     if (Labels.hold(p_second)
00374                         && Labels[p_second] != unknown
00375                         && Labels[p_second] != wshed
00376                         && Labels[p_second] != Labels[p])
00377                       {
00378                         exists = true;
00379                         break;
00380                       }
00381                   if (exists)
00382                     Labels[p_prime] = wshed;
00383                   else
00384                     {
00385                       Labels[p_prime] = Labels[p];
00386                       PQ.push(queue_elt_type(p_prime, In[p_prime]));
00387                     }
00388                 }
00389             }
00390         }
00391       return Labels.exact();
00392     }
00393 

template<class I, class E>
oln::mute< I >::ret white_top_hat const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Compute the white top hat of an image.

Parameters:
I Exact type of the image.
E Exact type of the structuring element.
  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/top_hat.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::save(oln::morpho::fast::white_top_hat(im1, oln::win_c8p()), IMG_OUT "oln_morpho_fast_white_top_hat_overload.pbm"); }

lena256_pgm.png
=>
oln_morpho_fast_white_top_hat_overload.png

Definition at line 145 of file top_hat.hh.

template<class C, class B, class I, class E>
mute<I, typename convoutput<C, B,typename mlc::exact< I >::ret::value_type>::ret>::ret white_top_hat const convert::abstract::conversion< C, B > &  c,
const abstract::non_vectorial_image< I > &  input,
const abstract::struct_elt< E > &  se
 

Compute the white top hat of an image.

Compute white top hat of input using se as structuring element. Soille p.105.

  • c Conversion object.
  • input Image to process.
  • se Structuring element.
#include <oln/basics2d.hh> #include <oln/morpho/top_hat.hh> #include <oln/level/compare.hh> #include <ntg/all.hh> int main() { typedef oln::image2d<ntg::int_u8> im_type; im_type im1(oln::load(IMG_IN "lena256.pgm")); oln::save(oln::morpho::fast::white_top_hat (oln::convert::bound<ntg::int_u8>(), im1, oln::win_c8p()), IMG_OUT "oln_morpho_fast_white_top_hat.pbm"); }

lena256_pgm.png
=>
oln_morpho_fast_white_top_hat.png

Definition at line 104 of file top_hat.hh.


Generated on Thu Apr 15 20:16:46 2004 for Olena by doxygen 1.3.6-20040222