boundary.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 
34 
35 #ifndef __INCLUDE_MIST_BOUNDARY__
36 #define __INCLUDE_MIST_BOUNDARY__
37 
38 #ifndef __INCLUDE_MIST_H__
39 #include "../mist.h"
40 #endif
41 
42 
43 // mist名前空間の始まり
45 
46 
47 namespace __boundary_controller__
48 {
49  template < int nc >
50  struct neighbors
51  {
52  template < class Array >
53  static inline typename Array::size_type neighbor( Array &in, const typename Array::size_type i[ 4 ], const typename Array::size_type j[ 4 ], const typename Array::size_type k[ 4 ] )
54  {
55  return( 0 );
56  }
57  };
58 
59  template < >
60  struct neighbors< 26 >
61  {
62  template < class Array >
63  static inline typename Array::size_type neighbor( Array &in, const typename Array::size_type i[ 4 ], const typename Array::size_type j[ 4 ], const typename Array::size_type k[ 4 ] )
64  {
65  typedef typename Array::size_type size_type;
66 
67  size_type count;
68 
69  count = in( i[ 0 ], j[ 0 ], k[ 0 ] ); // -1, -1, -1
70  count *= in( i[ 1 ], j[ 0 ], k[ 0 ] ); // 0, -1, -1
71  count *= in( i[ 2 ], j[ 0 ], k[ 0 ] ); // +1, -1, -1
72  count *= in( i[ 0 ], j[ 1 ], k[ 0 ] ); // -1, 0, -1
73  count *= in( i[ 1 ], j[ 1 ], k[ 0 ] ); // 0, 0, -1
74  count *= in( i[ 2 ], j[ 1 ], k[ 0 ] ); // +1, 0, -1
75  count *= in( i[ 0 ], j[ 2 ], k[ 0 ] ); // -1, +1, -1
76  count *= in( i[ 1 ], j[ 2 ], k[ 0 ] ); // 0, +1, -1
77  count *= in( i[ 2 ], j[ 2 ], k[ 0 ] ); // +1, +1, -1
78 
79  count *= in( i[ 0 ], j[ 0 ], k[ 1 ] ); // -1, -1, 0
80  count *= in( i[ 1 ], j[ 0 ], k[ 1 ] ); // 0, -1, 0
81  count *= in( i[ 2 ], j[ 0 ], k[ 1 ] ); // +1, -1, 0
82  count *= in( i[ 0 ], j[ 1 ], k[ 1 ] ); // -1, 0, 0
83  count *= in( i[ 2 ], j[ 1 ], k[ 1 ] ); // +1, 0, 0
84  count *= in( i[ 0 ], j[ 2 ], k[ 1 ] ); // -1, +1, 0
85  count *= in( i[ 1 ], j[ 2 ], k[ 1 ] ); // 0, +1, 0
86  count *= in( i[ 2 ], j[ 2 ], k[ 1 ] ); // +1, +1, 0
87 
88  count *= in( i[ 0 ], j[ 0 ], k[ 2 ] ); // -1, -1, +1
89  count *= in( i[ 1 ], j[ 0 ], k[ 2 ] ); // 0, -1, +1
90  count *= in( i[ 2 ], j[ 0 ], k[ 2 ] ); // +1, -1, +1
91  count *= in( i[ 0 ], j[ 1 ], k[ 2 ] ); // -1, 0, +1
92  count *= in( i[ 1 ], j[ 1 ], k[ 2 ] ); // 0, 0, +1
93  count *= in( i[ 2 ], j[ 1 ], k[ 2 ] ); // +1, 0, +1
94  count *= in( i[ 0 ], j[ 2 ], k[ 2 ] ); // -1, +1, +1
95  count *= in( i[ 1 ], j[ 2 ], k[ 2 ] ); // 0, +1, +1
96  count *= in( i[ 2 ], j[ 2 ], k[ 2 ] ); // +1, +1, +1
97 
98  count *= i[ 3 ] * j[ 3 ] * k[ 3 ];
99 
100  return( count );
101  }
102  };
103 
104  template < >
105  struct neighbors< 18 >
106  {
107  template < class Array >
108  static inline typename Array::size_type neighbor( Array &in, const typename Array::size_type i[ 4 ], const typename Array::size_type j[ 4 ], const typename Array::size_type k[ 4 ] )
109  {
110  typedef typename Array::size_type size_type;
111 
112  size_type count;
113 
114  count = in( i[ 1 ], j[ 0 ], k[ 0 ] ); // 0, -1, -1
115  count *= in( i[ 0 ], j[ 1 ], k[ 0 ] ); // -1, 0, -1
116  count *= in( i[ 1 ], j[ 1 ], k[ 0 ] ); // 0, 0, -1
117  count *= in( i[ 2 ], j[ 1 ], k[ 0 ] ); // +1, 0, -1
118  count *= in( i[ 1 ], j[ 2 ], k[ 0 ] ); // 0, +1, -1
119 
120  count *= in( i[ 0 ], j[ 0 ], k[ 1 ] ); // -1, -1, 0
121  count *= in( i[ 1 ], j[ 0 ], k[ 1 ] ); // 0, -1, 0
122  count *= in( i[ 2 ], j[ 0 ], k[ 1 ] ); // +1, -1, 0
123  count *= in( i[ 0 ], j[ 1 ], k[ 1 ] ); // -1, 0, 0
124  count *= in( i[ 2 ], j[ 1 ], k[ 1 ] ); // +1, 0, 0
125  count *= in( i[ 0 ], j[ 2 ], k[ 1 ] ); // -1, +1, 0
126  count *= in( i[ 1 ], j[ 2 ], k[ 1 ] ); // 0, +1, 0
127  count *= in( i[ 2 ], j[ 2 ], k[ 1 ] ); // +1, +1, 0
128 
129  count *= in( i[ 1 ], j[ 0 ], k[ 2 ] ); // 0, -1, +1
130  count *= in( i[ 0 ], j[ 1 ], k[ 2 ] ); // -1, 0, +1
131  count *= in( i[ 1 ], j[ 1 ], k[ 2 ] ); // 0, 0, +1
132  count *= in( i[ 2 ], j[ 1 ], k[ 2 ] ); // +1, 0, +1
133  count *= in( i[ 1 ], j[ 2 ], k[ 2 ] ); // 0, +1, +1
134 
135  count *= i[ 3 ] * j[ 3 ] * k[ 3 ];
136 
137  return( count );
138  }
139  };
140 
141  template < >
142  struct neighbors< 6 >
143  {
144  template < class Array >
145  static inline typename Array::size_type neighbor( Array &in, const typename Array::size_type i[ 4 ], const typename Array::size_type j[ 4 ], const typename Array::size_type k[ 4 ] )
146  {
147  typedef typename Array::size_type size_type;
148 
149  size_type count;
150 
151  count = in( i[ 1 ], j[ 1 ], k[ 0 ] ); // 0, 0, -1
152  count *= in( i[ 1 ], j[ 0 ], k[ 1 ] ); // 0, -1, 0
153  count *= in( i[ 0 ], j[ 1 ], k[ 1 ] ); // -1, 0, 0
154  count *= in( i[ 2 ], j[ 1 ], k[ 1 ] ); // +1, 0, 0
155  count *= in( i[ 1 ], j[ 2 ], k[ 1 ] ); // 0, +1, 0
156  count *= in( i[ 1 ], j[ 1 ], k[ 2 ] ); // 0, 0, +1
157 
158  count *= i[ 3 ] * j[ 3 ] * k[ 3 ];
159 
160  return( count );
161  }
162  };
163 
164  template < >
165  struct neighbors< 8 >
166  {
167  template < class Array >
168  static inline typename Array::size_type neighbor( Array &in, const typename Array::size_type i[ 4 ], const typename Array::size_type j[ 4 ], const typename Array::size_type k[ 4 ] )
169  {
170  typedef typename Array::size_type size_type;
171 
172  size_type count;
173 
174  count = in( i[ 0 ], j[ 0 ], k[ 1 ] ); // -1, -1, 0
175  count *= in( i[ 1 ], j[ 0 ], k[ 1 ] ); // 0, -1, 0
176  count *= in( i[ 2 ], j[ 0 ], k[ 1 ] ); // +1, -1, 0
177  count *= in( i[ 0 ], j[ 1 ], k[ 1 ] ); // -1, 0, 0
178  count *= in( i[ 2 ], j[ 1 ], k[ 1 ] ); // +1, 0, 0
179  count *= in( i[ 0 ], j[ 2 ], k[ 1 ] ); // -1, +1, 0
180  count *= in( i[ 1 ], j[ 2 ], k[ 1 ] ); // 0, +1, 0
181  count *= in( i[ 2 ], j[ 2 ], k[ 1 ] ); // +1, +1, 0
182 
183  count *= i[ 3 ] * j[ 3 ];
184 
185  return( count );
186  }
187  };
188 
189  template < >
190  struct neighbors< 4 >
191  {
192  template < class Array >
193  static inline typename Array::size_type neighbor( Array &in, const typename Array::size_type i[ 4 ], const typename Array::size_type j[ 4 ], const typename Array::size_type k[ 4 ] )
194  {
195  typedef typename Array::size_type size_type;
196 
197  size_type count;
198 
199  count = in( i[ 1 ], j[ 0 ], k[ 1 ] ); // 0, -1, 0
200  count *= in( i[ 0 ], j[ 1 ], k[ 1 ] ); // -1, 0, 0
201  count *= in( i[ 2 ], j[ 1 ], k[ 1 ] ); // +1, 0, 0
202  count *= in( i[ 1 ], j[ 2 ], k[ 1 ] ); // 0, +1, 0
203 
204  count *= i[ 3 ] * j[ 3 ];
205 
206  return( count );
207  }
208  };
209 
210 
211  template < class Array, class neighbor, class Functor >
212  typename Array::size_type boundary( Array &in, typename Array::value_type border, typename Array::value_type inside, bool boundary_is_border, const neighbor /* dmy */, Functor f )
213  {
214  typedef typename Array::size_type size_type;
215  typedef typename Array::value_type value_type;
216 
217  size_type i, j, k;
218  size_type ii[ 4 ], jj[ 4 ], kk[ 4 ];
219 
220  const size_type width = in.width( );
221  const size_type height = in.height( );
222  const size_type depth = in.depth( );
223 
224  const bool bprogress1 = depth == 1;
225  const bool bprogress2 = depth > 1;
226 
227  f( 0.0 );
228 
229  size_type count = 0;
230  value_type boundary = boundary_is_border ? 0 : 1;
231 
232  for( i = 0 ; i < in.size( ) ; i++ )
233  {
234  in[ i ] = in[ i ] == 0 ? 0 : 1;
235  }
236 
237  for( k = 0 ; k < depth ; k++ )
238  {
239  kk[ 0 ] = k == 0 ? k : k - 1;
240  kk[ 1 ] = k;
241  kk[ 2 ] = k == depth - 1 ? k : k + 1;
242  kk[ 3 ] = 1 < k && k < depth - 1 ? 1 : boundary;
243 
244  for( j = 0 ; j < height ; j++ )
245  {
246  jj[ 0 ] = j == 0 ? j : j - 1;
247  jj[ 1 ] = j;
248  jj[ 2 ] = j == height - 1 ? j : j + 1;
249  jj[ 3 ] = 1 < j && j < height - 1 ? 1 : boundary;
250 
251  for( i = 0 ; i < width ; i++ )
252  {
253  ii[ 0 ] = i == 0 ? i : i - 1;
254  ii[ 1 ] = i;
255  ii[ 2 ] = i == width - 1 ? i : i + 1;
256  ii[ 3 ] = 1 < i && i < width - 1 ? 1 : boundary;
257 
258  if( in( i, j, k ) != 0 )
259  {
260  if( neighbor::neighbor( in, ii, jj, kk ) == 0 )
261  {
262  in( i, j, k ) = 2;
263  count++;
264  }
265  }
266  }
267 
268  if( bprogress1 )
269  {
270  f( static_cast< double >( j + 1 ) / static_cast< double >( height ) * 100.0 );
271  }
272  }
273 
274  if( bprogress2 )
275  {
276  f( static_cast< double >( k + 1 ) / static_cast< double >( depth ) * 100.0 );
277  }
278  }
279 
280  for( i = 0 ; i < in.size( ) ; i++ )
281  {
282  if( in[ i ] > 0 )
283  {
284  in[ i ] = in[ i ] == 2 ? border : inside;
285  }
286  }
287 
288  f( 100.1 );
289 
290  return( count );
291  }
292 }
293 
294 
295 
296 
297 
305 
306 
320 template < class T, class Allocator, class Functor >
321 typename array2< T, Allocator >::size_type boundary4( array2< T, Allocator > &in, typename array2< T, Allocator >::value_type border, typename array2< T, Allocator >::value_type inside, bool boundary_is_border, Functor f )
322 {
323  return( __boundary_controller__::boundary( in, border, inside, boundary_is_border, __boundary_controller__::neighbors< 4 >( ), f ) );
324 }
325 
326 
339 template < class T, class Allocator >
340 inline typename array2< T, Allocator >::size_type boundary4( array2< T, Allocator > &in, typename array2< T, Allocator >::value_type border, typename array2< T, Allocator >::value_type inside = 0, bool boundary_is_border = true )
341 {
342  return( boundary4( in, border, inside, boundary_is_border, __mist_dmy_callback__( ) ) );
343 }
344 
345 
346 
360 template < class T, class Allocator, class Functor >
361 typename array2< T, Allocator >::size_type boundary8( array2< T, Allocator > &in, typename array2< T, Allocator >::value_type border, typename array2< T, Allocator >::value_type inside, bool boundary_is_border, Functor f )
362 {
363  return( __boundary_controller__::boundary( in, border, inside, boundary_is_border, __boundary_controller__::neighbors< 8 >( ), f ) );
364 }
365 
366 
379 template < class T, class Allocator >
380 inline typename array2< T, Allocator >::size_type boundary8( array2< T, Allocator > &in, typename array2< T, Allocator >::value_type border, typename array2< T, Allocator >::value_type inside = 0, bool boundary_is_border = true )
381 {
382  return( boundary8( in, border, inside, boundary_is_border, __mist_dmy_callback__( ) ) );
383 }
384 
385 
399 template < class T, class Allocator, class Functor >
400 typename array3< T, Allocator >::size_type boundary6( array3< T, Allocator > &in, typename array3< T, Allocator >::value_type border, typename array3< T, Allocator >::value_type inside, bool boundary_is_border, Functor f )
401 {
402  return( __boundary_controller__::boundary( in, border, inside, boundary_is_border, __boundary_controller__::neighbors< 6 >( ), f ) );
403 }
404 
405 
418 template < class T, class Allocator >
419 inline typename array3< T, Allocator >::size_type boundary6( array3< T, Allocator > &in, typename array3< T, Allocator >::value_type border, typename array3< T, Allocator >::value_type inside = 0, bool boundary_is_border = true )
420 {
421  return( boundary6( in, border, inside, boundary_is_border, __mist_dmy_callback__( ) ) );
422 }
423 
424 
438 template < class T, class Allocator, class Functor >
439 typename array3< T, Allocator >::size_type boundary18( array3< T, Allocator > &in, typename array3< T, Allocator >::value_type border, typename array3< T, Allocator >::value_type inside, bool boundary_is_border, Functor f )
440 {
441  return( __boundary_controller__::boundary( in, border, inside, boundary_is_border, __boundary_controller__::neighbors< 18 >( ), f ) );
442 }
443 
444 
457 template < class T, class Allocator >
458 inline typename array3< T, Allocator >::size_type boundary18( array3< T, Allocator > &in, typename array3< T, Allocator >::value_type border, typename array3< T, Allocator >::value_type inside = 0, bool boundary_is_border = true )
459 {
460  return( boundary18( in, border, inside, boundary_is_border, __mist_dmy_callback__( ) ) );
461 }
462 
463 
477 template < class T, class Allocator, class Functor >
478 typename array3< T, Allocator >::size_type boundary26( array3< T, Allocator > &in, typename array3< T, Allocator >::value_type border, typename array3< T, Allocator >::value_type inside, bool boundary_is_border, Functor f )
479 {
480  return( __boundary_controller__::boundary( in, border, inside, boundary_is_border, __boundary_controller__::neighbors< 26 >( ), f ) );
481 }
482 
483 
496 template < class T, class Allocator >
497 inline typename array3< T, Allocator >::size_type boundary26( array3< T, Allocator > &in, typename array3< T, Allocator >::value_type border, typename array3< T, Allocator >::value_type inside = 0, bool boundary_is_border = true )
498 {
499  return( boundary26( in, border, inside, boundary_is_border, __mist_dmy_callback__( ) ) );
500 }
501 
502 
503 
505 // 境界画素抽出グループの終わり
506 
507 
508 // mist名前空間の終わり
509 _MIST_END
510 
511 
512 #endif // __INCLUDE_MIST_BOUNDARY__
513 

Generated on Wed Nov 12 2014 19:44:13 for MIST by doxygen 1.8.1.2