breadth_first_thinning.hh 5.18 KB
Newer Older
1
// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory (LRDE)
2
//
3
// This file is part of Olena.
4
//
5
6
7
8
9
// Olena is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, version 2 of the License.
//
// Olena is distributed in the hope that it will be useful,
10
11
12
13
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
15
// along with Olena.  If not, see <http://www.gnu.org/licenses/>.
16
17
//
// As a special exception, you may use this file as part of a free
18
// software project without restriction.  Specifically, if other files
19
// instantiate templates or use macros or inline functions from this
20
21
22
23
24
// file, or you compile this file and link it with other files to produce
// an executable, this file does not by itself cause the resulting
// executable to be covered by the GNU General Public License.  This
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
25
26
27
28

#ifndef MLN_TOPO_SKELETON_BREADTH_FIRST_THINNING_HH
# define MLN_TOPO_SKELETON_BREADTH_FIRST_THINNING_HH

29
/// \file
30
31
32
33
34
35
36
/// \brief Computing a skeleton by using breadth-first thinning on a
/// binary image.

# include <algorithm>

# include <mln/core/routine/duplicate.hh>

37
38
39
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>

40
# include <mln/core/site_set/p_queue_fast.hh>
41
42
43
44
45
46
47
48
49
50
51
52

# include <mln/fun/p2b/tautology.hh>

namespace mln
{

  namespace topo
  {

    namespace skeleton
    {

53
      /** \brief Skeleton by Breadth-First Thinning.
54

55
	  A generic implementation of the computation of a skeleton
56
	  using a breadth-first thinning on a binary image.
57

58
59
60
61
62
	  \param input      The input image.
	  \param nbh        The adjacency relation between triangles.
	  \param is_simple  The predicate on the simplicity of points
			    (sites).  This functor must provide a method
			    <tt>void set_image(const Image<I>&)</tt>.
63
	  \param detach     A function used to detach a cell from \a input.
64
65
66
	  \param constraint A constraint on point (site); if it
			    returns \c false for a point, this point
			    will not be removed.  */
67
68
69
      template <typename I, typename N, typename F, typename G, typename H>
      mln_concrete(I)
      breadth_first_thinning(const Image<I>& input,
70
			     const Neighborhood<N>& nbh,
71
			     Function_v2b<F>& is_simple,
72
			     G detach,
73
74
75
76
77
78
			     const Function_v2b<H>& constraint);


      /** \brief Skeleton by Breadth-First Thinning with no constraint.

	  A generic implementation of the computation of a skeleton
79
	  using a breadth-first thinning on a binary image.
80

81
82
83
84
85
	  \param input      The input image.
	  \param nbh        The adjacency relation between triangles.
	  \param is_simple  The predicate on the simplicity of points
			    (sites).  This functor must provide a method
			    <tt>void set_image(const Image<I>&)</tt>.
86
	  \param detach     A function used to detach a cell from
87
			    \a input.  */
88
89
90
91
92
93
      template <typename I, typename N, typename F, typename G>
      mln_concrete(I)
      breadth_first_thinning(const Image<I>& input,
			     const Neighborhood<N>& nbh,
			     Function_v2b<F>& is_simple,
			     G detach);
94
95
96
97


# ifndef MLN_INCLUDE_ONLY

98
      template <typename I, typename N, typename F, typename G, typename H>
99
      inline
100
101
      mln_concrete(I)
      breadth_first_thinning(const Image<I>& input_,
102
			     const Neighborhood<N>& nbh_,
103
			     Function_v2b<F>& is_simple_,
104
			     G detach,
105
			     const Function_v2b<H>& constraint_)
106
      {
107
108
	trace::entering("topo::skeleton::breadth_first_thinning");

109
	const I& input = exact(input_);
110
111
	const N& nbh = exact(nbh_);
	F& is_simple = exact(is_simple_);
112
	const H& constraint = exact(constraint_);
113

114
	mln_concrete(I) output = duplicate(input);
115
116
117
	// Attach the work image to IS_SIMPLE.
	is_simple.set_image(output);

118
	typedef mln_psite(I) psite;
119
120
121
	typedef p_queue_fast<psite> queue_t;
	queue_t queue;
	// Populate QUEUE with candidate simple points.
122
123
	mln_piter(I) p(output.domain());
	for_all(p)
124
125
	{
	  if (output(p) && constraint(p) && is_simple(p))
126
	    queue.push(p);
127
128
	}

129
	while (!queue.is_empty())
130
	  {
131
132
133
134
	    psite p = queue.pop_front();
	    if (output(p) && constraint(p) && is_simple(p))
	      {
		detach(p, output);
135
136
		mln_niter(N) n(nbh, p);
		for_all(n)
137
		{
138
139
140
		  if (output.domain().has(n)
		      && output(n) && constraint(n) && is_simple(n))
		    queue.push(n);
141
		}
142
	      }
143
	  }
144
145

	trace::exiting("topo::skeleton::breadth_first_thinning");
146
147
148
	return output;
      }

149
150
151
152
153
154
155
156
157
158
159
160
161

      template <typename I, typename N, typename F, typename G>
      inline
      mln_concrete(I)
      breadth_first_thinning(const Image<I>& input,
			     const Neighborhood<N>& nbh,
			     Function_v2b<F>& is_simple,
			     G detach)
      {
	return breadth_first_thinning(input, nbh, is_simple, detach,
				      fun::p2b::tautology());
      }

162
163
164
165
166
167
168
169
170
# endif // MLN_INCLUDE_ONLY

    } // end of namespace mln::topo::skeleton

  } // end of namespace mln::topo

} // end of namespace mln

#endif // ! MLN_TOPO_SKELETON_BREADTH_FIRST_THINNING_HH