- メインページ
- モジュール
- ネームスペース
- データ構造
- ファイル

- ファイル一覧
- グローバル

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名前空間の始まり
44 _MIST_BEGIN
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