Je ne suis pas sûr des définitions de hit_or_miss_closing et de
hit_or_miss_opening_bg (Soille est assez laconique là-dessus).
ChangeLog | 11 ++
oln/morpho/hit_or_miss.hh | 168 ++++++++++++++++++++++++++++++++-
tests/morpho/tests/hit_or_miss_closing | 43 ++++++++
tests/morpho/tests/hit_or_miss_opening | 43 ++++++++
4 files changed, 264 insertions(+), 1 deletion(-)
Index: olena/ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add hit-or-miss opening/closing and hit-or-miss opening/closing of
the background.
* oln/morpho/hit_or_miss.hh: More documentation.
(hit_or_miss_opening, hit_or_miss_opening_bg)
(hit_or_miss_closing, hit_or_miss_closing_bg): New.
* tests/morpho/tests/hit_or_miss_opening,
* tests/morpho/tests/hit_or_miss_closing: New tests.
2005-07-08 Roland Levillain <roland(a)lrde.epita.fr>
Index: olena/tests/morpho/tests/hit_or_miss_closing
--- olena/tests/morpho/tests/hit_or_miss_closing (révision 0)
+++ olena/tests/morpho/tests/hit_or_miss_closing (révision 0)
@@ -0,0 +1,43 @@
+ // -*- C++ -*-
+#include "data.hh"
+#include <oln/utils/md5.hh>
+
+#include <ntg/bin.hh>
+#include <oln/io/read_image.hh>
+#include <oln/basics2d.hh>
+#include <oln/morpho/hit_or_miss.hh>
+
+using namespace oln;
+
+bool check()
+{
+ utils::key::value_type data_key_hom_closing[16] =
+ { 0x9d, 0x9d, 0xbb, 0xd7, 0x6b, 0x5, 0x38, 0x29,
+ 0x69, 0x6e, 0x30, 0xd4, 0x30, 0x99, 0x13, 0x29 };
+ utils::key key_hom_closing(data_key_hom_closing);
+
+ utils::key::value_type data_key_hom_closing_bg[16] =
+ { 0xfa, 0x7, 0x26, 0x34, 0x16, 0x36, 0xc, 0xf4,
+ 0x5e, 0x19, 0x53, 0xa2, 0x89, 0x1e, 0xdb, 0xae };
+ utils::key key_hom_closing_bg(data_key_hom_closing_bg);
+
+ image2d<ntg::bin> ima;
+ ima = io::read(rdata("object.pbm"));
+
+ oln::window2d win1;
+ win1
+ .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 win2 = -win1;
+
+ if (utils::md5(morpho::hit_or_miss_closing(ima, win1, win2)) !=
+ key_hom_closing)
+ return true;
+
+ if (utils::md5(morpho::hit_or_miss_closing_bg(ima, win1, win2)) !=
+ key_hom_closing_bg)
+ return true;
+
+ return false;
+}
Index: olena/tests/morpho/tests/hit_or_miss_opening
--- olena/tests/morpho/tests/hit_or_miss_opening (révision 0)
+++ olena/tests/morpho/tests/hit_or_miss_opening (révision 0)
@@ -0,0 +1,43 @@
+ // -*- C++ -*-
+#include "data.hh"
+#include <oln/utils/md5.hh>
+
+#include <ntg/bin.hh>
+#include <oln/io/read_image.hh>
+#include <oln/basics2d.hh>
+#include <oln/morpho/hit_or_miss.hh>
+
+using namespace oln;
+
+bool check()
+{
+ utils::key::value_type data_key_hom_opening[16] =
+ { 0x90, 0xda, 0x98, 0x5a, 0xef, 0x2e, 0x8d, 0x54,
+ 0xa5, 0x6, 0xd, 0x7a, 0x6f, 0x63, 0x55, 0x7 };
+ utils::key key_hom_opening(data_key_hom_opening);
+
+ utils::key::value_type data_key_hom_opening_bg[16] =
+ { 0xd6, 0x45, 0x11, 0xed, 0xdd, 0xf, 0x42, 0x59,
+ 0x95, 0x57, 0x4, 0x66, 0x59, 0x97, 0x6c, 0x8d };
+ utils::key key_hom_opening_bg(data_key_hom_opening_bg);
+
+ image2d<ntg::bin> ima;
+ ima = io::read(rdata("object.pbm"));
+
+ oln::window2d win1;
+ win1
+ .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 win2 = -win1;
+
+ if (utils::md5(morpho::hit_or_miss_opening(ima, win1, win2)) !=
+ key_hom_opening)
+ return true;
+
+ if (utils::md5(morpho::hit_or_miss_opening_bg(ima, win1, win2)) !=
+ key_hom_opening_bg)
+ return true;
+
+ return false;
+}
Index: olena/oln/morpho/hit_or_miss.hh
--- olena/oln/morpho/hit_or_miss.hh (révision 237)
+++ olena/oln/morpho/hit_or_miss.hh (copie de travail)
@@ -32,9 +32,12 @@
# include <oln/utils/record.hh>
# include <oln/morpho/erosion.hh>
+# include <oln/morpho/dilation.hh>
# include <oln/level/arith.hh>
# include <oln/level/invert.hh>
+// FIXME: More documentation (in particular, code snippets). See Olena
+// 0.10's doc.
namespace oln {
@@ -83,7 +86,17 @@
} // end of namespace oln::morpho::impl
- /// Generic hit-or-miss transform (facade).
+ /*! \brief Preform a hit-or-miss transform (generic facade)
+
+ REF: Soille, 2nd ed., p.140.
+
+ \arg \c I exact type of the input image.
+ \arg \c W1 exact type of the first structuring element.
+ \arg \c W2 exact type of the second structuring element.
+
+ \param input image to process.
+ \param win1 first structuring element.
+ \param win2 second structuring element. */
template<class I, class W1, class W2>
oln_type_of(I, concrete)
hit_or_miss(const abstract::image<I>& input,
@@ -101,6 +114,159 @@
return output;
}
+
+ /*! \brief Perform an hit-or-miss opening.
+
+ Compute the hit-or-miss opening of input by the composite
+ structuring element (win1, win2).
+
+ REF: Soille, 2nd ed., p.149.
+
+ By definition \a win1 and \a win2 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 binary.
+
+ \arg \c I Exact type of the input image.
+ \arg \c W1 Exact type of the first structuring element.
+ \arg \c W2 Exact type of the second structuring element.
+
+ \param input image to process.
+ \param win1 first structuring element.
+ \param win2 second structuring element. */
+ template<class I, class W1, class W2>
+ oln_type_of(I, concrete)
+ hit_or_miss_opening(const abstract::image<I>& input,
+ const abstract::window<W1>& win1,
+ const abstract::window<W2>& win2)
+ {
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W1, grid)>::ensure();
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W2, grid)>::ensure();
+ entering("morpho::hit_or_miss_opening");
+
+ oln_type_of(I, concrete) output("output");
+ output = dilation(hit_or_miss(input, win1, win2), -win1);
+
+ exiting("morpho::hit_or_miss_opening");
+ return output;
+ }
+
+ /*! \brief Perform an hit-or-miss opening of background.
+
+ Compute the hit-or-miss opening of the background of input by
+ the composite structuring element (win1, win2).
+
+ REF: Soille, 2nd ed., p.149.
+
+ By definition win1 and win2 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.
+
+ \arg \c I exact type of the input image.
+ \arg \c W1 exact type of the first structuring element.
+ \arg \c W2 exact type of the second structuring element.
+
+ \param input image to process.
+ \param win1 first structuring element.
+ \param win2 second structuring element. */
+ template<class I, class W1, class W2>
+ oln_type_of(I, concrete)
+ hit_or_miss_opening_bg(const abstract::image<I>& input,
+ const abstract::window<W1>& win1,
+ const abstract::window<W2>& win2)
+ {
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W1, grid)>::ensure();
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W2, grid)>::ensure();
+ entering("morpho::hit_or_miss_opening_bg");
+
+ oln_type_of(I, concrete) output("output");
+ output = dilation(hit_or_miss(input, win1, win2), -win2);
+
+ exiting("morpho::hit_or_miss_opening_bg");
+ return output;
+ }
+
+ /*! \brief Perform an hit-or-miss closing.
+
+ Compute the hit-or-miss closing of input by the composite
+ structuring element (win1, win2). This is the dual
+ transformation of hit-or-miss opening with respect to set
+ complementation.
+
+ REF: Soille, 2nd ed., p.149.
+
+ By definition \a win1 and \a win2 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 binary.
+
+ \arg \c I Exact type of the input image.
+ \arg \c W1 Exact type of the first structuring element.
+ \arg \c W2 Exact type of the second structuring element.
+
+ \param input image to process.
+ \param win1 first structuring element.
+ \param win2 second structuring element. */
+ template<class I, class W1, class W2>
+ oln_type_of(I, concrete)
+ hit_or_miss_closing(const abstract::image<I>& input,
+ const abstract::window<W1>& win1,
+ const abstract::window<W2>& win2)
+ {
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W1, grid)>::ensure();
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W2, grid)>::ensure();
+ entering("morpho::hit_or_miss_closing");
+
+ oln_type_of(I, concrete) output("output");
+ // FIXME: Is this correct? Soille doesn't detail the definition
+ // of the hit-or-miss closing in his book.
+ output = hit_or_miss_opening(level::invert(input), win1, win2);
+
+ exiting("morpho::hit_or_miss_closing");
+ return output;
+ }
+
+ /*! \brief Perform an hit-or-miss closing of the background.
+
+ Compute the hit-or-miss closing of the background of input by
+ the composite structuring element (win1, win2). This is the
+ dual transformation of hit-or-miss opening of the background
+ with respect to set complementation.
+
+ REF: Soille, 2nd ed., p.149.
+
+ By definition \a win1 and \a win2 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 binary.
+
+ \arg \c I Exact type of the input image.
+ \arg \c W1 Exact type of the first structuring element.
+ \arg \c W2 Exact type of the second structuring element.
+
+ \param input image to process.
+ \param win1 first structuring element.
+ \param win2 second structuring element. */
+ template<class I, class W1, class W2>
+ oln_type_of(I, concrete)
+ hit_or_miss_closing_bg(const abstract::image<I>& input,
+ const abstract::window<W1>& win1,
+ const abstract::window<W2>& win2)
+ {
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W1, grid)>::ensure();
+ mlc::eq<oln_type_of(I, grid), oln_wn_type_of(W2, grid)>::ensure();
+ entering("morpho::hit_or_miss_closing_bg");
+
+ oln_type_of(I, concrete) output("output");
+ // FIXME: Is this correct? Soille doesn't detail the definition
+ // of the hit-or-miss closing of the background in his book.
+ output = hit_or_miss_opening_bg(level::invert(input), win1, win2);
+
+ exiting("morpho::hit_or_miss_closing_bg");
+ return output;
+ }
+
} // end of namespace oln::morpho
} // end of namespace oln