40 #ifndef __INCLUDE_MIST_THINNING__
41 #define __INCLUDE_MIST_THINNING__
44 #ifndef __INCLUDE_MIST_H__
48 #ifndef __INCLUDE_MIST_LIMITS__
49 #include "../limits.h"
52 #ifndef __INCLUDE_MIST_MATRIX__
53 #include "../matrix.h"
56 #ifndef __INCLUDE_MIST_DISTANCE_TRANSFORM__
67 namespace __thinning_controller__
69 template <
class T,
class Allocator >
70 inline void val9(
const array2< T, Allocator > &in,
typename array2< T, Allocator >::value_type p[ 9 ],
71 typename array2< T, Allocator >::size_type i,
typename array2< T, Allocator >::size_type j )
74 p[ 1 ] = in( i + 1, j );
75 p[ 2 ] = in( i + 1, j - 1 );
76 p[ 3 ] = in( i , j - 1 );
77 p[ 4 ] = in( i - 1, j - 1 );
78 p[ 5 ] = in( i - 1, j );
79 p[ 6 ] = in( i - 1, j + 1 );
80 p[ 7 ] = in( i , j + 1 );
81 p[ 8 ] = in( i + 1, j + 1 );
84 template <
class T >
inline T pixel( T p )
86 return ( ( p > 0 ) ? 1 : 0 );
89 template <
class T >
inline T pixel( T p[ 9 ],
int index )
93 return ( pixel( p[ index + 8 ] ) );
97 return ( pixel( p[ index - 8 ] ) );
101 return ( pixel( p[ index ] ) );
105 template <
class T >
inline T pixel_( T p[ 9 ],
int index )
107 return ( 1 - pixel( p, index ) );
110 template <
class T >
inline int Nc4( T p[ 9 ] )
114 for(
int i = 1 ; i < 9 ; i += 2 )
116 ret += pixel( p, i ) - pixel( p, i ) * pixel( p, i + 1 ) * pixel( p, i + 2 );
122 template <
class T >
inline int Nc8( T p[ 9 ] )
126 for(
int i = 1 ; i < 9 ; i += 2 )
128 ret += pixel_( p, i ) - pixel_( p, i ) * pixel_( p, i + 1 ) * pixel_( p, i + 2 );
136 template <
class T,
class Allocator >
137 void thinning( array2< T, Allocator > &ia )
139 typedef typename array2< T, Allocator >::size_type size_type;
140 typedef typename array2< T, Allocator >::value_type value_type;
143 size_type w = ia.width( );
144 size_type h = ia.height( );
146 char p[ 9 ], q[ 9 ], value;
147 array2< char > ic( w, h );
148 array2< char > id( w, h );
150 for( i = 0 ; i < ia.size( ) ; i++ )
152 id[ i ] = ia[ i ] == 0 ? 0 : 1;
162 for( j = 1 ; j < h - 1 ; j++ )
164 for( i = 1 ; i < w - 1 ; i++ )
169 if( pixel( p[ 0 ] ) != 1 )
175 if( p[ 1 ] == 1 && p[ 3 ] == 1 && p[ 5 ] == 1 && p[ 7 ] == 1 )
181 value = pixel( p[ 1 ] ) + pixel( p[ 2 ] ) + pixel( p[ 3 ] ) + pixel( p[ 4 ] ) + pixel( p[ 5 ] ) + pixel( p[ 6 ] ) + pixel( p[ 7 ] ) + pixel( p[ 8 ] );
189 value = pixel( q[ 1 ] ) + pixel( q[ 2 ] ) + pixel( q[ 3 ] ) + pixel( q[ 4 ] ) + pixel( q[ 5 ] ) + pixel( q[ 6 ] ) + pixel( q[ 7 ] ) + pixel( q[ 8 ] );
205 if( q[ 3 ] == -1 || q[ 5 ] == -1 )
220 for( i = 0 ; i <
id.size( ) ; i++ )
222 id[ i ] =
id[ i ] == -1 ? 0 :
id[ i ];
226 for( i = 0 ; i < ia.size( ) ; i++ )
228 ia[ i ] =
id[ i ] > 0 ? 1 : 0;
235 namespace __euclidean_utility__
237 template <
class T,
class Allocator >
238 inline void val9_1(
const array2< T, Allocator > &in,
typename array2< T, Allocator >::value_type p[ 9 ],
239 typename array2< T, Allocator >::size_type i,
typename array2< T, Allocator >::size_type j )
241 p[ 0 ] = in( i , j );
242 p[ 1 ] = in( i + 1, j );
243 p[ 2 ] = in( i + 1, j - 1 );
244 p[ 3 ] = in( i , j - 1 );
245 p[ 4 ] = in( i - 1, j - 1 );
246 p[ 5 ] = in( i - 1, j );
247 p[ 6 ] = in( i - 1, j + 1 );
248 p[ 7 ] = in( i , j + 1 );
249 p[ 8 ] = in( i + 1, j + 1 );
252 template <
class T,
class Allocator >
253 inline void val9_2(
const array2< T, Allocator > &in,
typename array2< T, Allocator >::value_type p[ 9 ],
254 typename array2< T, Allocator >::size_type i,
typename array2< T, Allocator >::size_type j )
256 p[ 0 ] = in( i , j );
257 p[ 1 ] = in( i - 1, j );
258 p[ 2 ] = in( i - 1, j + 1 );
259 p[ 3 ] = in( i , j + 1 );
260 p[ 4 ] = in( i + 1, j + 1 );
261 p[ 5 ] = in( i + 1, j );
262 p[ 6 ] = in( i + 1, j - 1 );
263 p[ 7 ] = in( i , j - 1 );
264 p[ 8 ] = in( i - 1, j - 1 );
267 template <
class T,
class Allocator >
268 inline void val9_3(
const array2< T, Allocator > &in,
typename array2< T, Allocator >::value_type p[ 9 ],
269 typename array2< T, Allocator >::size_type i,
typename array2< T, Allocator >::size_type j )
271 p[ 0 ] = in( i , j );
272 p[ 1 ] = in( i + 1, j );
273 p[ 2 ] = in( i + 1, j + 1 );
274 p[ 3 ] = in( i , j + 1 );
275 p[ 4 ] = in( i - 1, j + 1 );
276 p[ 5 ] = in( i - 1, j );
277 p[ 6 ] = in( i - 1, j - 1 );
278 p[ 7 ] = in( i , j - 1 );
279 p[ 8 ] = in( i + 1, j - 1 );
282 template <
class T >
inline T max_pixel( T p[ 9 ] )
286 for(
int i = 1 ; i < 9 ; i++ )
288 if( std::abs( p[ i ] ) > max )
290 max = std::abs( p[ i ] );
297 template <
class T >
inline T plus_pixel_num( T p[ 9 ] )
301 for(
int i = 1 ; i < 9 ; i++ )
312 template <
class T >
inline T pixel( T p )
314 return ( ( p > 0 ) ? 1 : 0 );
317 template <
class T >
inline T pixel( T p[ 9 ],
int index )
321 return ( pixel( p[ index + 8 ] ) );
323 else if( index >= 9 )
325 return ( pixel( p[ index - 8 ] ) );
329 return ( pixel( p[ index ] ) );
333 template <
class T >
inline T pixel_( T p[ 9 ],
int index )
335 return ( 1 - pixel( p, index ) );
338 template <
class T >
inline int Nc4( T p[ 9 ] )
342 for(
int i = 1 ; i < 9 ; i += 2 )
344 ret += pixel( p, i ) - pixel( p, i ) * pixel( p, i + 1 ) * pixel( p, i + 2 );
350 template <
class T >
inline T Nc8( T p[ 9 ] )
354 for(
int i = 1 ; i < 9 ; i += 2 )
356 ret += pixel_( p, i ) - pixel_( p, i ) * pixel_( p, i + 1 ) * pixel_( p, i + 2 );
367 template <
class T,
class Allocator >
368 void thinning( array2< T, Allocator > &ia )
370 typedef typename array2< T, Allocator >::size_type size_type;
371 typedef typename array2< T, Allocator >::value_type value_type;
373 size_type w = ia.width( );
374 size_type h = ia.height( );
376 double p[ 9 ], q[ 9 ];
377 array2< double > ic( w, h, ia.reso1( ), ia.reso2( ) );
378 array2< double > id( w, h, ia.reso1( ), ia.reso2( ) );
380 for( i = 0 ; i < ia.size( ) ; i++ )
382 id[ i ] = ia[ i ] == 0 ? 0 : 1;
390 for( j = 1 ; j < h - 1 ; j++ )
392 for( i = 1 ; i < w - 1 ; i++ )
394 val9_1( ic, p, i, j );
395 val9_1(
id, q, i, j );
402 if( p[ 3 ] > 0 && p[ 5 ] > 0 )
412 if( max_pixel( p ) <= std::abs( q[ 0 ] ) )
417 if( ( q[ 0 ] > q[ 1 ] && q[ 1 ] > 0 ) && ( ( p[ 2 ] > 0 ) || ( p[ 3 ] > 0 ) ) && ( ( q[ 7 ] > 0 ) || ( q[ 8 ] > 0 ) ) )
422 if( ( q[ 0 ] > q[ 7 ] && q[ 7 ] > 0 ) && ( ( p[ 5 ] > 0 ) || ( q[ 6 ] > 0 ) ) && ( ( q[ 8 ] > 0 ) || ( q[ 1 ] > 0 ) ) )
427 ic( i, j ) = - id( i, j );
433 for( j = h - 2 ; j > 0 ; j-- )
435 for( i = w - 2 ; i > 0 ; i-- )
437 val9_2(
id, p, i, j );
438 val9_2( ic, q, i, j );
445 if( p[ 3 ] > 0 && p[ 5 ] > 0 )
450 val9_1(
id, p, i, j );
457 val9_2(
id, p, i, j );
459 if( max_pixel( p ) <= std::abs( q[ 0 ] ) )
464 if( ( q[ 0 ] > q[ 1 ] && q[ 1 ] > 0 ) && ( ( p[ 2 ] > 0 ) || ( p[ 3 ] > 0 ) ) && ( ( q[ 7 ] > 0 ) || ( q[ 8 ] > 0 ) ) )
469 if( ( q[ 0 ] > q[ 7 ] && q[ 7 ] > 0 ) && ( ( p[ 5 ] > 0 ) || ( q[ 6 ] >= q[ 0 ] ) ) && ( ( q[ 8 ] > 0 ) || ( q[ 1 ] > 0 ) ) )
474 id( i, j ) = - ic( i, j );
480 for( j = h - 2 ; j > 0 ; j-- )
482 for( i = 1 ; i < w - 1 ; i++ )
484 val9_3( ic, p, i, j );
485 val9_3(
id, q, i, j );
492 if( p[ 3 ] > 0 && p[ 5 ] > 0 )
497 val9_1( ic, p, i, j );
504 val9_3( ic, p, i, j );
506 if( max_pixel( p ) <= std::abs( q[ 0 ] ) )
511 ic( i, j ) = - id( i, j );
517 for( j = 1 ; j < h - 1 ; j++ )
519 for( i = 1 ; i < w - 1 ; i++ )
521 val9_1(
id, p, i, j );
522 val9_1( ic, q, i, j );
530 if( ( p[ 1 ] > 0 ) && ( p[ 3 ] > 0 ) && ( p[ 5 ] > 0 ) && ( p[ 7 ] > 0 ) )
540 if( plus_pixel_num( p ) < 2 )
545 if( plus_pixel_num( p ) == 2 && ( q[ 4 ] > 0 && p[ 4 ] == 0 ) )
559 for( i = 0 ; i < ia.size( ) ; i++ )
561 ia[ i ] =
id[ i ] != 0 ? 1 : 0;
569 template <
size_t Nc >
572 typedef size_t size_type;
573 typedef ptrdiff_t difference_type;
576 static T P1( T *p[ 4 ], difference_type i, difference_type j )
580 return( p[ i ][ j - 8 ] );
584 return( p[ i ][ j ] );
589 static T P2( T *p[ 4 ], difference_type i, difference_type j )
593 return( p[ i ][ j - 8 ] );
597 return( p[ i ][ j + 8 ] );
601 return( p[ i ][ j ] );
607 static difference_type Nc6( T *p[ 4 ] )
609 static size_type S0[] = { 1, 3 };
610 static size_type S1[] = { 1, 3, 5, 7 };
612 difference_type ret = 0;
614 for( size_type h = 0 ; h < 2 ; h++ )
616 difference_type tmp = 0;
617 for( size_type k = 0 ; k < 4 ; k++ )
619 tmp += P1( p, S0[ h ], S1[ k ] ) * P1( p, 2, S1[ k ] );
621 ret += P1( p, S0[ h ], 0 ) * ( 1 - tmp );
624 for( size_type k = 0 ; k < 4 ; k++ )
626 difference_type tmp = 0;
627 for( size_type h = 0 ; h < 2 ; h++ )
629 tmp += P1( p, S0[ h ], 0 ) * P1( p, S0[ h ], S1[ k ] ) * P1( p, S0[ h ], S1[ k ] + 1 ) * P1( p, S0[ h ], S1[ k ] + 2 );
631 ret += P1( p, 2, S1[ k ] ) * ( 1 - P1( p, 2, S1[ k ] + 1 ) * P1( p, 2, S1[ k ] + 2 ) * ( 1 - tmp ) );
639 static difference_type Sx( T *p[ 4 ] )
641 static size_type S0[] = { 1, 3 };
642 static size_type S1[] = { 1, 3, 5, 7 };
644 difference_type sx = 0;
646 for( size_type k = 0 ; k < 4 ; k++ )
648 for( size_type h = 0 ; h < 2 ; h++ )
650 sx += ( 1 - P1( p, S0[ h ], S1[ k ] + 1 ) ) * P1( p, S0[ h ], S1[ k ] ) * P1( p, S0[ h ], S1[ k ] + 2 ) * P1( p, S0[ h ], 0 ) * P1( p, 2, S1[ k ] ) * P1( p, 2, S1[ k ] + 1 ) * P1( p, 2, S1[ k ] + 2 );
657 static bool is_deletable(
const int v[ 27 ] )
660 const int *p[ 4 ] = { NULL, v + 0, v + 9, v + 18 };
669 difference_type num = p[ 1 ][ 0 ] + p[ 2 ][ 1 ] + p[ 2 ][ 3 ] + p[ 2 ][ 5 ] + p[ 2 ][ 7 ] + p[ 3 ][ 0 ];
696 if( p[ 2 ][ 0 ] == 0 )
701 static size_type S1[] = { 1, 3, 5, 7 };
702 difference_type hole = 0;
703 if( p[ 1 ][ 0 ] != 0 )
705 for( size_type h = 0 ; h < 4 ; h++ )
707 hole += p[ 1 ][ S1[ h ] ] * p[ 2 ][ S1[ h ] ];
716 if( p[ 3 ][ 0 ] != 0 )
718 for( size_type h = 0 ; h < 4 ; h++ )
720 hole += p[ 3 ][ S1[ h ] ] * p[ 2 ][ S1[ h ] ];
728 for( size_type h = 0 ; h < 4 ; h++ )
731 if( p[ 2 ][ S1[ h ] ] != 0 )
733 hole = p[ 1 ][ 0 ] * p[ 1 ][ S1[ h ] ] + p[ 3 ][ 0 ] * p[ 3 ][ S1[ h ] ] + P2( p, 2, S1[ h ] - 1 ) * P2( p, 2, S1[ h ] - 2 ) + P2( p, 2, S1[ h ] + 1 ) * P2( p, 2, S1[ h ] + 2 );
746 typedef matrix< difference_type > matrix_type;
749 matrix_type M( 6, 6 );
751 M( 0, 0 ) = 0 ; M( 0, 1 ) = p[ 1 ][ 1 ]; M( 0, 2 ) = p[ 1 ][ 3 ]; M( 0, 3 ) = p[ 1 ][ 7 ]; M( 0, 4 ) = p[ 1 ][ 5 ]; M( 0, 5 ) = 0;
752 M( 1, 0 ) = p[ 1 ][ 1 ]; M( 1, 1 ) = 0 ; M( 1, 2 ) = p[ 2 ][ 2 ]; M( 1, 3 ) = p[ 2 ][ 8 ]; M( 1, 4 ) = 0 ; M( 1, 5 ) = p[ 3 ][ 1 ];
753 M( 2, 0 ) = p[ 1 ][ 3 ]; M( 2, 1 ) = p[ 2 ][ 2 ]; M( 2, 2 ) = 0 ; M( 2, 3 ) = 0 ; M( 2, 4 ) = p[ 2 ][ 4 ]; M( 2, 5 ) = p[ 3 ][ 3 ];
754 M( 3, 0 ) = p[ 1 ][ 7 ]; M( 3, 1 ) = p[ 2 ][ 8 ]; M( 3, 2 ) = 0 ; M( 3, 3 ) = 0 ; M( 3, 4 ) = p[ 2 ][ 6 ]; M( 3, 5 ) = p[ 3 ][ 7 ];
755 M( 4, 0 ) = p[ 1 ][ 5 ]; M( 4, 1 ) = 0 ; M( 4, 2 ) = p[ 2 ][ 4 ]; M( 4, 3 ) = p[ 2 ][ 6 ]; M( 4, 4 ) = 0 ; M( 4, 5 ) = p[ 3 ][ 5 ];
756 M( 5, 0 ) = 0 ; M( 5, 1 ) = p[ 3 ][ 1 ]; M( 5, 2 ) = p[ 3 ][ 3 ]; M( 5, 3 ) = p[ 3 ][ 7 ]; M( 5, 4 ) = p[ 3 ][ 5 ]; M( 5, 5 ) = 0;
758 matrix_type I = matrix_type::identity( 6, 6 );
759 matrix_type N = M * matrix_type( I + M * matrix_type( I + M * matrix_type( I + M * ( I + M ) ) ));
761 for( size_type r = 0 ; r < N.size( ) ; r++ )
772 std::cout <<
"Error" << std::endl;
779 static bool is_3d_simplex(
const int v[ 27 ] )
782 int p[ 3 ][ 3 ][ 3 ];
784 p[ 0 ][ 0 ][ 0 ] = v[ 4 ];
785 p[ 1 ][ 0 ][ 0 ] = v[ 5 ];
786 p[ 2 ][ 0 ][ 0 ] = v[ 6 ];
787 p[ 0 ][ 1 ][ 0 ] = v[ 3 ];
788 p[ 1 ][ 1 ][ 0 ] = v[ 0 ];
789 p[ 2 ][ 1 ][ 0 ] = v[ 7 ];
790 p[ 0 ][ 2 ][ 0 ] = v[ 2 ];
791 p[ 1 ][ 2 ][ 0 ] = v[ 1 ];
792 p[ 2 ][ 2 ][ 0 ] = v[ 8 ];
793 p[ 0 ][ 0 ][ 1 ] = v[ 13 ];
794 p[ 1 ][ 0 ][ 1 ] = v[ 14 ];
795 p[ 2 ][ 0 ][ 1 ] = v[ 15 ];
796 p[ 0 ][ 1 ][ 1 ] = v[ 12 ];
797 p[ 1 ][ 1 ][ 1 ] = v[ 9 ];
798 p[ 2 ][ 1 ][ 1 ] = v[ 16 ];
799 p[ 0 ][ 2 ][ 1 ] = v[ 11 ];
800 p[ 1 ][ 2 ][ 1 ] = v[ 10 ];
801 p[ 2 ][ 2 ][ 1 ] = v[ 17 ];
802 p[ 0 ][ 0 ][ 2 ] = v[ 22 ];
803 p[ 1 ][ 0 ][ 2 ] = v[ 23 ];
804 p[ 2 ][ 0 ][ 2 ] = v[ 24 ];
805 p[ 0 ][ 1 ][ 2 ] = v[ 21 ];
806 p[ 1 ][ 1 ][ 2 ] = v[ 18 ];
807 p[ 2 ][ 1 ][ 2 ] = v[ 25 ];
808 p[ 0 ][ 2 ][ 2 ] = v[ 20 ];
809 p[ 1 ][ 2 ][ 2 ] = v[ 19 ];
810 p[ 2 ][ 2 ][ 2 ] = v[ 26 ];
812 if( p[ 1 ][ 1 ][ 1 ] == 0 )
return(
false );
814 for( size_type k = 1 ; k < 3 ; k++ )
816 for( size_type j = 1 ; j < 3 ; j++ )
818 for( size_type i = 1 ; i < 3 ; i++ )
820 if( p[ i - 1 ][ j ][ k ] * p[ i ][ j - 1 ][ k ] * p[ i ][ j ][ k - 1 ] *
821 p[ i - 1 ][ j - 1 ][ k ] * p[ i ][ j - 1 ][ k - 1 ] * p[ i - 1 ][ j ][ k - 1 ] *
822 p[ i ][ j ][ k ] * p[ i - 1 ][ j - 1 ][ k - 1 ] != 0 )
835 struct neighbor< 26 >
837 typedef size_t size_type;
838 typedef ptrdiff_t difference_type;
841 static T P1( T *p[ 4 ], difference_type i, difference_type j )
845 return( p[ i ][ j - 8 ] );
849 return( p[ i ][ j ] );
854 static T P2( T *p[ 4 ], difference_type i, difference_type j )
858 return( p[ i ][ j - 8 ] );
862 return( p[ i ][ j + 8 ] );
866 return( p[ i ][ j ] );
871 static T P1_( T *p[ 4 ], difference_type i, difference_type j )
875 return( 1 - p[ i ][ j - 8 ] );
879 return( 1 - p[ i ][ j ] );
884 static T P2_( T *p[ 4 ], difference_type i, difference_type j )
888 return( 1 - p[ i ][ j - 8 ] );
892 return( 1 - p[ i ][ j + 8 ] );
896 return( 1 - p[ i ][ j ] );
903 static difference_type Nc26( T *p[ 4 ] )
905 static size_type S0[] = { 1, 3 };
906 static size_type S1[] = { 1, 3, 5, 7 };
908 difference_type ret = 0;
910 for( size_type h = 0 ; h < 2 ; h++ )
912 difference_type tmp = 0;
913 for( size_type k = 0 ; k < 4 ; k++ )
915 tmp += P1_( p, S0[ h ], S1[ k ] ) * P1_( p, 2, S1[ k ] );
917 ret += P1_( p, S0[ h ], 0 ) * ( 1 - tmp );
920 for( size_type k = 0 ; k < 4 ; k++ )
922 difference_type tmp = 0;
923 for( size_type h = 0 ; h < 2 ; h++ )
925 tmp += P1_( p, S0[ h ], 0 ) * P1_( p, S0[ h ], S1[ k ] ) * P1_( p, S0[ h ], S1[ k ] + 1 ) * P1_( p, S0[ h ], S1[ k ] + 2 );
927 ret += P1_( p, 2, S1[ k ] ) * ( 1 - P1_( p, 2, S1[ k ] + 1 ) * P1_( p, 2, S1[ k ] + 2 ) * ( 1 - tmp ) );
937 static difference_type Sx( T *p[ 4 ] )
939 static size_type S0[] = { 1, 3 };
940 static size_type S1[] = { 1, 3, 5, 7 };
942 difference_type sx = 0;
944 for( size_type k = 0 ; k < 4 ; k++ )
946 for( size_type h = 0 ; h < 2 ; h++ )
948 sx += ( 1 - P1( p, S0[ h ], S1[ k ] + 1 ) ) * P1( p, S0[ h ], S1[ k ] ) * P1( p, S0[ h ], S1[ k ] + 2 ) * P1( p, S0[ h ], 0 ) * P1( p, 2, S1[ k ] ) * P1( p, 2, S1[ k ] + 1 ) * P1( p, 2, S1[ k ] + 2 );
956 static bool is_deletable(
const int v[ 27 ] )
960 const int *p[ 4 ] = { NULL, v + 0, v + 9, v + 18 };
961 memcpy( pp, v,
sizeof(
int ) * 27 );
970 for(
size_t i = 0 ; i < 9 ; i++ )
972 pp[ i ] = v[ i ] == 0 ? 1 : 0;
975 for(
size_t i = 10 ; i < 27 ; i++ )
977 pp[ i ] = v[ i ] == 0 ? 1 : 0;
985 difference_type num = p[ 1 ][ 0 ] + p[ 2 ][ 1 ] + p[ 2 ][ 3 ] + p[ 2 ][ 5 ] + p[ 2 ][ 7 ] + p[ 3 ][ 0 ];
1012 if( p[ 2 ][ 0 ] == 0 )
1017 static size_type S1[] = { 1, 3, 5, 7 };
1018 difference_type hole = 0;
1019 if( p[ 1 ][ 0 ] != 0 )
1021 for( size_type h = 0 ; h < 4 ; h++ )
1023 hole += p[ 1 ][ S1[ h ] ] * p[ 2 ][ S1[ h ] ];
1032 if( p[ 3 ][ 0 ] != 0 )
1034 for( size_type h = 0 ; h < 4 ; h++ )
1036 hole += p[ 3 ][ S1[ h ] ] * p[ 2 ][ S1[ h ] ];
1044 for( size_type h = 0 ; h < 4 ; h++ )
1047 if( p[ 2 ][ S1[ h ] ] != 0 )
1049 hole = p[ 1 ][ 0 ] * p[ 1 ][ S1[ h ] ] + p[ 3 ][ 0 ] * p[ 3 ][ S1[ h ] ] + P2( p, 2, S1[ h ] - 1 ) * P2( p, 2, S1[ h ] - 2 ) + P2( p, 2, S1[ h ] + 1 ) * P2( p, 2, S1[ h ] + 2 );
1062 typedef matrix< int > matrix_type;
1065 matrix_type M( 6, 6 );
1067 M( 0, 0 ) = 0 ; M( 0, 1 ) = p[ 1 ][ 1 ]; M( 0, 2 ) = p[ 1 ][ 3 ]; M( 0, 3 ) = p[ 1 ][ 7 ]; M( 0, 4 ) = p[ 1 ][ 5 ]; M( 0, 5 ) = 0;
1068 M( 1, 0 ) = p[ 1 ][ 1 ]; M( 1, 1 ) = 0 ; M( 1, 2 ) = p[ 2 ][ 2 ]; M( 1, 3 ) = p[ 2 ][ 8 ]; M( 1, 4 ) = 0 ; M( 1, 5 ) = p[ 3 ][ 1 ];
1069 M( 2, 0 ) = p[ 1 ][ 3 ]; M( 2, 1 ) = p[ 2 ][ 2 ]; M( 2, 2 ) = 0 ; M( 2, 3 ) = 0 ; M( 2, 4 ) = p[ 2 ][ 4 ]; M( 2, 5 ) = p[ 3 ][ 3 ];
1070 M( 3, 0 ) = p[ 1 ][ 7 ]; M( 3, 1 ) = p[ 2 ][ 8 ]; M( 3, 2 ) = 0 ; M( 3, 3 ) = 0 ; M( 3, 4 ) = p[ 2 ][ 6 ]; M( 3, 5 ) = p[ 3 ][ 7 ];
1071 M( 4, 0 ) = p[ 1 ][ 5 ]; M( 4, 1 ) = 0 ; M( 4, 2 ) = p[ 2 ][ 4 ]; M( 4, 3 ) = p[ 2 ][ 6 ]; M( 4, 4 ) = 0 ; M( 4, 5 ) = p[ 3 ][ 5 ];
1072 M( 5, 0 ) = 0 ; M( 5, 1 ) = p[ 3 ][ 1 ]; M( 5, 2 ) = p[ 3 ][ 3 ]; M( 5, 3 ) = p[ 3 ][ 7 ]; M( 5, 4 ) = p[ 3 ][ 5 ]; M( 5, 5 ) = 0;
1074 matrix_type I = matrix_type::identity( 6, 6 );
1075 matrix_type N = M * matrix_type( I + M * matrix_type( I + M * matrix_type( I + M * ( I + M ) ) ));
1077 for( size_type r = 0 ; r < N.size( ) ; r++ )
1088 std::cout <<
"Error" << std::endl;
1095 static bool is_3d_simplex(
const int v[ 27 ] )
1098 int p[ 3 ][ 3 ][ 3 ];
1100 p[ 0 ][ 0 ][ 0 ] = v[ 4 ];
1101 p[ 1 ][ 0 ][ 0 ] = v[ 5 ];
1102 p[ 2 ][ 0 ][ 0 ] = v[ 6 ];
1103 p[ 0 ][ 1 ][ 0 ] = v[ 3 ];
1104 p[ 1 ][ 1 ][ 0 ] = v[ 0 ];
1105 p[ 2 ][ 1 ][ 0 ] = v[ 7 ];
1106 p[ 0 ][ 2 ][ 0 ] = v[ 2 ];
1107 p[ 1 ][ 2 ][ 0 ] = v[ 1 ];
1108 p[ 2 ][ 2 ][ 0 ] = v[ 8 ];
1109 p[ 0 ][ 0 ][ 1 ] = v[ 13 ];
1110 p[ 1 ][ 0 ][ 1 ] = v[ 14 ];
1111 p[ 2 ][ 0 ][ 1 ] = v[ 15 ];
1112 p[ 0 ][ 1 ][ 1 ] = v[ 12 ];
1113 p[ 1 ][ 1 ][ 1 ] = v[ 9 ];
1114 p[ 2 ][ 1 ][ 1 ] = v[ 16 ];
1115 p[ 0 ][ 2 ][ 1 ] = v[ 11 ];
1116 p[ 1 ][ 2 ][ 1 ] = v[ 10 ];
1117 p[ 2 ][ 2 ][ 1 ] = v[ 17 ];
1118 p[ 0 ][ 0 ][ 2 ] = v[ 22 ];
1119 p[ 1 ][ 0 ][ 2 ] = v[ 23 ];
1120 p[ 2 ][ 0 ][ 2 ] = v[ 24 ];
1121 p[ 0 ][ 1 ][ 2 ] = v[ 21 ];
1122 p[ 1 ][ 1 ][ 2 ] = v[ 18 ];
1123 p[ 2 ][ 1 ][ 2 ] = v[ 25 ];
1124 p[ 0 ][ 2 ][ 2 ] = v[ 20 ];
1125 p[ 1 ][ 2 ][ 2 ] = v[ 19 ];
1126 p[ 2 ][ 2 ][ 2 ] = v[ 26 ];
1128 if( p[ 1 ][ 1 ][ 1 ] == 0 )
return(
false );
1130 for( size_type k = 0 ; k < 3 ; k += 2 )
1132 for( size_type j = 0 ; j < 3 ; j += 2 )
1134 for( size_type i = 0 ; i < 3 ; i += 2 )
1138 if( p[ i ][ j ][ 1 ] != 0 ) num++;
1139 if( p[ i ][ j ][ k ] != 0 ) num++;
1140 if( p[ i ][ 1 ][ 1 ] != 0 ) num++;
1141 if( p[ i ][ 1 ][ k ] != 0 ) num++;
1142 if( p[ 1 ][ j ][ 1 ] != 0 ) num++;
1143 if( p[ 1 ][ j ][ k ] != 0 ) num++;
1144 if( p[ 1 ][ 1 ][ k ] != 0 ) num++;
1146 if( num > 3 )
return(
true );
1147 if( num < 3 )
continue;
1149 if( p[ 1 ][ 1 ][ k ] * ( p[ 1 ][ 1 ][ k ] * p[ i ][ 1 ][ k ] +
1150 p[ 1 ][ j ][ 1 ] * p[ 1 ][ j ][ k ] +
1151 p[ i ][ j ][ 1 ] * p[ i ][ j ][ k ] ) != 0 )
1155 if( p[ i ][ 1 ][ 1 ] * ( p[ 1 ][ j ][ 1 ] * p[ i ][ j ][ 1 ] +
1156 p[ 1 ][ j ][ k ] * p[ i ][ j ][ k ] ) != 0 )
1160 if( p[ 1 ][ j ][ 1 ] * ( p[ i ][ 1 ][ k ] * p[ i ][ j ][ k ] ) != 0 )
1175 template <
class Tin,
class Tout,
class Difference >
1176 void create_neighbor_list(
const Tin *pin, Tout *pout, Difference p[ 27 ] )
1178 for(
size_t i = 0 ; i < 27 ; i++ )
1180 pout[ i ] = pin[ p[ i ] ] > 0 ? 1 : 0;
1184 template <
class T,
class Allocator,
class Neighbor >
1185 void shrink_skelton( array3< T, Allocator > &in, Neighbor __dmy__ )
1187 typedef typename array3< T, Allocator >::size_type size_type;
1188 typedef typename array3< T, Allocator >::difference_type difference_type;
1189 typedef typename array3< T, Allocator >::const_pointer const_pointer;
1190 typedef typename array3< T, Allocator >::value_type value_type;
1191 typedef Neighbor neighbor_type;
1193 difference_type diff[ 27 ];
1197 difference_type ox = in.width( ) / 2;
1198 difference_type oy = in.height( ) / 2;
1199 difference_type oz = in.depth( ) / 2;
1201 const_pointer p0 = &in( ox, oy, oz );
1203 diff[ 0 ] = &in( ox , oy , oz - 1 ) - p0;
1204 diff[ 1 ] = &in( ox , oy + 1, oz - 1 ) - p0;
1205 diff[ 2 ] = &in( ox - 1, oy + 1, oz - 1 ) - p0;
1206 diff[ 3 ] = &in( ox - 1, oy , oz - 1 ) - p0;
1207 diff[ 4 ] = &in( ox - 1, oy - 1, oz - 1 ) - p0;
1208 diff[ 5 ] = &in( ox , oy - 1, oz - 1 ) - p0;
1209 diff[ 6 ] = &in( ox + 1, oy - 1, oz - 1 ) - p0;
1210 diff[ 7 ] = &in( ox + 1, oy , oz - 1 ) - p0;
1211 diff[ 8 ] = &in( ox + 1, oy + 1, oz - 1 ) - p0;
1213 diff[ 9 ] = &in( ox , oy , oz ) - p0;
1214 diff[ 10 ] = &in( ox , oy + 1, oz ) - p0;
1215 diff[ 11 ] = &in( ox - 1, oy + 1, oz ) - p0;
1216 diff[ 12 ] = &in( ox - 1, oy , oz ) - p0;
1217 diff[ 13 ] = &in( ox - 1, oy - 1, oz ) - p0;
1218 diff[ 14 ] = &in( ox , oy - 1, oz ) - p0;
1219 diff[ 15 ] = &in( ox + 1, oy - 1, oz ) - p0;
1220 diff[ 16 ] = &in( ox + 1, oy , oz ) - p0;
1221 diff[ 17 ] = &in( ox + 1, oy + 1, oz ) - p0;
1223 diff[ 18 ] = &in( ox , oy , oz + 1 ) - p0;
1224 diff[ 19 ] = &in( ox , oy + 1, oz + 1 ) - p0;
1225 diff[ 20 ] = &in( ox - 1, oy + 1, oz + 1 ) - p0;
1226 diff[ 21 ] = &in( ox - 1, oy , oz + 1 ) - p0;
1227 diff[ 22 ] = &in( ox - 1, oy - 1, oz + 1 ) - p0;
1228 diff[ 23 ] = &in( ox , oy - 1, oz + 1 ) - p0;
1229 diff[ 24 ] = &in( ox + 1, oy - 1, oz + 1 ) - p0;
1230 diff[ 25 ] = &in( ox + 1, oy , oz + 1 ) - p0;
1231 diff[ 26 ] = &in( ox + 1, oy + 1, oz + 1 ) - p0;
1235 for( size_type j = 0 ; j < in.height( ) ; j++ )
1237 for( size_type i = 0 ; i < in.width( ) ; i++ )
1240 in( i, j, in.depth( ) - 1 ) = 0;
1244 for( size_type k = 0 ; k < in.depth( ) ; k++ )
1246 for( size_type j = 0 ; j < in.height( ) ; j++ )
1249 in( in.width( ) - 1, j, k ) = 0;
1253 for( size_type k = 0 ; k < in.depth( ) ; k++ )
1255 for( size_type i = 0 ; i < in.width( ) ; i++ )
1258 in( i, in.height( ) - 1, k ) = 0;
1266 for( size_type k = 1 ; k < in.depth( ) - 1 ; k++ )
1268 for( size_type j = 1 ; j < in.height( ) - 1 ; j++ )
1270 for( size_type i = 1 ; i < in.width( ) - 1 ; i++ )
1272 value_type &v = in( i, j, k );
1275 create_neighbor_list( &v, val, diff );
1277 if( neighbor_type::is_deletable( val ) )
1296 typedef ptrdiff_t difference_type;
1298 difference_type diff;
1302 border( difference_type d, T val ) : diff( d ), value( val ), distance( val ) {}
1305 template <
class T >
1306 inline std::ostream &operator <<( std::ostream &out, const border< T > &b )
1313 out << b.value <<
", ";
1319 template <
class T,
class Allocator,
class Neighbor >
1320 void thinning( array3< T, Allocator > &in, Neighbor __dmy__ )
1322 typedef typename array3< T, Allocator >::size_type size_type;
1323 typedef typename array3< T, Allocator >::difference_type difference_type;
1324 typedef typename array3< T, Allocator >::const_pointer const_pointer;
1325 typedef typename array3< T, Allocator >::pointer pointer;
1326 typedef T value_type;
1327 typedef Neighbor neighbor_type;
1328 typedef border< T > border_type;
1329 typedef std::vector< border_type > border_list_type;
1335 for( size_type j = 0 ; j < in.height( ) ; j++ )
1337 for( size_type i = 0 ; i < in.width( ) ; i++ )
1340 in( i, j, in.depth( ) - 1 ) = 0;
1344 for( size_type k = 0 ; k < in.depth( ) ; k++ )
1346 for( size_type j = 0 ; j < in.height( ) ; j++ )
1349 in( in.width( ) - 1, j, k ) = 0;
1353 for( size_type k = 0 ; k < in.depth( ) ; k++ )
1355 for( size_type i = 0 ; i < in.width( ) ; i++ )
1358 in( i, in.height( ) - 1, k ) = 0;
1362 value_type min = type_limits< value_type >::maximum( ), max = type_limits< value_type >::minimum( );
1363 for( size_type i = 0 ; i < in.size( ) ; i++ )
1365 value_type &v = in[ i ];
1369 if( v > max ) max = v;
1370 if( v < min ) min = v;
1374 border_list_type blist, slist[ 9 ];
1375 difference_type diff[ 27 ], nc6[ 6 ];
1379 difference_type ox = in.width( ) / 2;
1380 difference_type oy = in.height( ) / 2;
1381 difference_type oz = in.depth( ) / 2;
1383 const_pointer p0 = &in( ox, oy, oz );
1386 diff[ 0 ] = &in( ox , oy , oz - 1 ) - p0;
1387 diff[ 1 ] = &in( ox , oy + 1, oz - 1 ) - p0;
1388 diff[ 2 ] = &in( ox - 1, oy + 1, oz - 1 ) - p0;
1389 diff[ 3 ] = &in( ox - 1, oy , oz - 1 ) - p0;
1390 diff[ 4 ] = &in( ox - 1, oy - 1, oz - 1 ) - p0;
1391 diff[ 5 ] = &in( ox , oy - 1, oz - 1 ) - p0;
1392 diff[ 6 ] = &in( ox + 1, oy - 1, oz - 1 ) - p0;
1393 diff[ 7 ] = &in( ox + 1, oy , oz - 1 ) - p0;
1394 diff[ 8 ] = &in( ox + 1, oy + 1, oz - 1 ) - p0;
1396 diff[ 9 ] = &in( ox , oy , oz ) - p0;
1397 diff[ 10 ] = &in( ox , oy + 1, oz ) - p0;
1398 diff[ 11 ] = &in( ox - 1, oy + 1, oz ) - p0;
1399 diff[ 12 ] = &in( ox - 1, oy , oz ) - p0;
1400 diff[ 13 ] = &in( ox - 1, oy - 1, oz ) - p0;
1401 diff[ 14 ] = &in( ox , oy - 1, oz ) - p0;
1402 diff[ 15 ] = &in( ox + 1, oy - 1, oz ) - p0;
1403 diff[ 16 ] = &in( ox + 1, oy , oz ) - p0;
1404 diff[ 17 ] = &in( ox + 1, oy + 1, oz ) - p0;
1406 diff[ 18 ] = &in( ox , oy , oz + 1 ) - p0;
1407 diff[ 19 ] = &in( ox , oy + 1, oz + 1 ) - p0;
1408 diff[ 20 ] = &in( ox - 1, oy + 1, oz + 1 ) - p0;
1409 diff[ 21 ] = &in( ox - 1, oy , oz + 1 ) - p0;
1410 diff[ 22 ] = &in( ox - 1, oy - 1, oz + 1 ) - p0;
1411 diff[ 23 ] = &in( ox , oy - 1, oz + 1 ) - p0;
1412 diff[ 24 ] = &in( ox + 1, oy - 1, oz + 1 ) - p0;
1413 diff[ 25 ] = &in( ox + 1, oy , oz + 1 ) - p0;
1414 diff[ 26 ] = &in( ox + 1, oy + 1, oz + 1 ) - p0;
1416 nc6[ 0 ] = diff[ 12 ];
1417 nc6[ 1 ] = diff[ 16 ];
1418 nc6[ 2 ] = diff[ 14 ];
1419 nc6[ 3 ] = diff[ 10 ];
1420 nc6[ 4 ] = diff[ 0 ];
1421 nc6[ 5 ] = diff[ 18 ];
1425 const_pointer p0 = &in[ 0 ];
1428 for( size_type i = 0 ; i < in.size( ) ; i++ )
1430 value_type &v = in[ i ];
1433 const_pointer p = &v;
1434 if( p[ nc6[ 0 ] ] == 0 || p[ nc6[ 1 ] ] == 0 ||
1435 p[ nc6[ 2 ] ] == 0 || p[ nc6[ 3 ] ] == 0 ||
1436 p[ nc6[ 4 ] ] == 0 || p[ nc6[ 5 ] ] == 0 )
1438 blist.push_back( border_type( p - p0, v ) );
1446 blist.reserve( blist.size( ) * 2 + 1 );
1447 slist[ 0 ].reserve( blist.size( ) );
1448 slist[ 1 ].reserve( blist.size( ) );
1449 slist[ 2 ].reserve( blist.size( ) );
1450 slist[ 3 ].reserve( blist.size( ) );
1451 slist[ 4 ].reserve( blist.size( ) );
1452 slist[ 5 ].reserve( blist.size( ) );
1453 slist[ 6 ].reserve( blist.size( ) );
1454 slist[ 7 ].reserve( blist.size( ) );
1455 slist[ 8 ].reserve( blist.size( ) );
1457 size_type count = 0, loop = 0;
1461 size_type __length__ = 0;
1464 for( size_type l = 0 ; l < blist.size( ) ; l++ )
1466 border_type &b = blist[ l ];
1467 pointer p = &in[ b.diff ];
1469 if( b.value <= min )
1471 create_neighbor_list( p, val, diff );
1474 if( !neighbor_type::is_deletable( val ) )
1481 size_type num = val[ 0 ];
1515 difference_type val = num / 3 + 7;
1516 b.value =
static_cast< value_type
>( val );
1518 if( 7 <= val && val <= 15 )
1520 slist[ val - 7 ].push_back( b );
1527 blist[ __length__++ ] = b;
1530 blist.erase( blist.begin( ) + __length__, blist.end( ) );
1533 for( size_type ll = 0 ; ll < 9 ; ll++ )
1535 border_list_type &list = slist[ ll ];
1537 for( size_type l = 0 ; l < list.size( ) ; l++ )
1539 border_type &b = list[ l ];
1540 pointer p = &in[ b.diff ];
1542 create_neighbor_list( p, val, diff );
1545 if( !neighbor_type::is_deletable( val ) )
1548 blist.push_back( b );
1552 size_type num = 0, i;
1555 for( i = 0 ; i < 9 && num < 2 ; i++ )
1562 for( i = 10 ; i < 27 && num < 2 ; i++ )
1576 if( p[ nc6[ 0 ] ] > 20 )
1578 blist.push_back( border_type( b.diff + nc6[ 0 ], p[ nc6[ 0 ] ] ) );
1581 if( p[ nc6[ 1 ] ] > 20 )
1583 blist.push_back( border_type( b.diff + nc6[ 1 ], p[ nc6[ 1 ] ] ) );
1586 if( p[ nc6[ 2 ] ] > 20 )
1588 blist.push_back( border_type( b.diff + nc6[ 2 ], p[ nc6[ 2 ] ] ) );
1591 if( p[ nc6[ 3 ] ] > 20 )
1593 blist.push_back( border_type( b.diff + nc6[ 3 ], p[ nc6[ 3 ] ] ) );
1596 if( p[ nc6[ 4 ] ] > 20 )
1598 blist.push_back( border_type( b.diff + nc6[ 4 ], p[ nc6[ 4 ] ] ) );
1601 if( p[ nc6[ 5 ] ] > 20 )
1603 blist.push_back( border_type( b.diff + nc6[ 5 ], p[ nc6[ 5 ] ] ) );
1614 for( size_type l = 0 ; l < blist.size( ) ; l++ )
1616 border_type &b = blist[ l ];
1617 pointer p = &in[ b.diff ];
1621 create_neighbor_list( p, val, diff );
1623 if( neighbor_type::is_deletable( val ) )
1625 b.value = b.distance;
1633 for( size_type l = 0 ; l < blist.size( ) ; l++ )
1635 border_type &b = blist[ l ];
1636 if( b.value < min && b.value > 20 )
1647 std::cout << loop++ <<
" \r";
1649 }
while( min < max || count != blist.size( ) );
1651 std::cout << std::endl;
1654 for( size_type i = 0 ; i < in.size( ) ; i++ )
1664 template <
class T,
class Allocator,
class Neighbor >
1665 void surface_thinning( array3< T, Allocator > &in, Neighbor __dmy__ )
1667 typedef typename array3< T, Allocator >::size_type size_type;
1668 typedef typename array3< T, Allocator >::difference_type difference_type;
1669 typedef typename array3< T, Allocator >::const_pointer const_pointer;
1670 typedef typename array3< T, Allocator >::pointer pointer;
1671 typedef T value_type;
1672 typedef Neighbor neighbor_type;
1673 typedef border< T > border_type;
1674 typedef std::vector< border_type > border_list_type;
1677 for( size_type j = 0 ; j < in.height( ) ; j++ )
1679 for( size_type i = 0 ; i < in.width( ) ; i++ )
1682 in( i, j, in.depth( ) - 1 ) = 0;
1686 for( size_type k = 0 ; k < in.depth( ) ; k++ )
1688 for( size_type j = 0 ; j < in.height( ) ; j++ )
1691 in( in.width( ) - 1, j, k ) = 0;
1695 for( size_type k = 0 ; k < in.depth( ) ; k++ )
1697 for( size_type i = 0 ; i < in.width( ) ; i++ )
1700 in( i, in.height( ) - 1, k ) = 0;
1707 value_type min = type_limits< value_type >::maximum( ), max = type_limits< value_type >::minimum( );
1708 for( size_type i = 0 ; i < in.size( ) ; i++ )
1710 value_type &v = in[ i ];
1714 if( v > max ) max = v;
1715 if( v < min ) min = v;
1719 border_list_type blist, slist[ 9 ];
1720 difference_type diff[ 27 ], nc6[ 6 ];
1724 difference_type ox = in.width( ) / 2;
1725 difference_type oy = in.height( ) / 2;
1726 difference_type oz = in.depth( ) / 2;
1728 const_pointer p0 = &in( ox, oy, oz );
1731 diff[ 0 ] = &in( ox , oy , oz - 1 ) - p0;
1732 diff[ 1 ] = &in( ox , oy + 1, oz - 1 ) - p0;
1733 diff[ 2 ] = &in( ox - 1, oy + 1, oz - 1 ) - p0;
1734 diff[ 3 ] = &in( ox - 1, oy , oz - 1 ) - p0;
1735 diff[ 4 ] = &in( ox - 1, oy - 1, oz - 1 ) - p0;
1736 diff[ 5 ] = &in( ox , oy - 1, oz - 1 ) - p0;
1737 diff[ 6 ] = &in( ox + 1, oy - 1, oz - 1 ) - p0;
1738 diff[ 7 ] = &in( ox + 1, oy , oz - 1 ) - p0;
1739 diff[ 8 ] = &in( ox + 1, oy + 1, oz - 1 ) - p0;
1741 diff[ 9 ] = &in( ox , oy , oz ) - p0;
1742 diff[ 10 ] = &in( ox , oy + 1, oz ) - p0;
1743 diff[ 11 ] = &in( ox - 1, oy + 1, oz ) - p0;
1744 diff[ 12 ] = &in( ox - 1, oy , oz ) - p0;
1745 diff[ 13 ] = &in( ox - 1, oy - 1, oz ) - p0;
1746 diff[ 14 ] = &in( ox , oy - 1, oz ) - p0;
1747 diff[ 15 ] = &in( ox + 1, oy - 1, oz ) - p0;
1748 diff[ 16 ] = &in( ox + 1, oy , oz ) - p0;
1749 diff[ 17 ] = &in( ox + 1, oy + 1, oz ) - p0;
1751 diff[ 18 ] = &in( ox , oy , oz + 1 ) - p0;
1752 diff[ 19 ] = &in( ox , oy + 1, oz + 1 ) - p0;
1753 diff[ 20 ] = &in( ox - 1, oy + 1, oz + 1 ) - p0;
1754 diff[ 21 ] = &in( ox - 1, oy , oz + 1 ) - p0;
1755 diff[ 22 ] = &in( ox - 1, oy - 1, oz + 1 ) - p0;
1756 diff[ 23 ] = &in( ox , oy - 1, oz + 1 ) - p0;
1757 diff[ 24 ] = &in( ox + 1, oy - 1, oz + 1 ) - p0;
1758 diff[ 25 ] = &in( ox + 1, oy , oz + 1 ) - p0;
1759 diff[ 26 ] = &in( ox + 1, oy + 1, oz + 1 ) - p0;
1761 nc6[ 0 ] = diff[ 12 ];
1762 nc6[ 1 ] = diff[ 16 ];
1763 nc6[ 2 ] = diff[ 14 ];
1764 nc6[ 3 ] = diff[ 10 ];
1765 nc6[ 4 ] = diff[ 0 ];
1766 nc6[ 5 ] = diff[ 18 ];
1770 const_pointer p0 = &in[ 0 ];
1773 for( size_type i = 0 ; i < in.size( ) ; i++ )
1775 value_type &v = in[ i ];
1778 const_pointer p = &v;
1779 if( p[ nc6[ 0 ] ] == 0 || p[ nc6[ 1 ] ] == 0 ||
1780 p[ nc6[ 2 ] ] == 0 || p[ nc6[ 3 ] ] == 0 ||
1781 p[ nc6[ 4 ] ] == 0 || p[ nc6[ 5 ] ] == 0 )
1783 blist.push_back( border_type( p - p0, v ) );
1791 blist.reserve( blist.size( ) * 2 + 1 );
1792 slist[ 0 ].reserve( blist.size( ) );
1793 slist[ 1 ].reserve( blist.size( ) );
1794 slist[ 2 ].reserve( blist.size( ) );
1795 slist[ 3 ].reserve( blist.size( ) );
1796 slist[ 4 ].reserve( blist.size( ) );
1797 slist[ 5 ].reserve( blist.size( ) );
1798 slist[ 6 ].reserve( blist.size( ) );
1799 slist[ 7 ].reserve( blist.size( ) );
1800 slist[ 8 ].reserve( blist.size( ) );
1802 size_type count = 0, loop = 0;
1806 size_type __length__ = 0;
1809 for( size_type l = 0 ; l < blist.size( ) ; l++ )
1811 border_type &b = blist[ l ];
1812 pointer p = &in[ b.diff ];
1814 if( b.value <= min )
1816 create_neighbor_list( p, val, diff );
1819 if( !neighbor_type::is_deletable( val ) )
1826 if( !neighbor_type::is_3d_simplex( val ) )
1833 size_type num = val[ 0 ];
1860 difference_type val = num / 3 + 7;
1861 b.value =
static_cast< value_type
>( val );
1863 if( 7 <= val && val <= 15 )
1865 slist[ val - 7 ].push_back( b );
1872 blist[ __length__++ ] = b;
1875 blist.erase( blist.begin( ) + __length__, blist.end( ) );
1878 for( size_type ll = 0 ; ll < 9 ; ll++ )
1880 border_list_type &list = slist[ ll ];
1882 for( size_type l = 0 ; l < list.size( ) ; l++ )
1884 border_type &b = list[ l ];
1885 pointer p = &in[ b.diff ];
1887 create_neighbor_list( p, val, diff );
1890 if( !neighbor_type::is_deletable( val ) )
1897 if( !neighbor_type::is_3d_simplex( val ) )
1906 if( p[ nc6[ 0 ] ] > 20 )
1908 blist.push_back( border_type( b.diff + nc6[ 0 ], p[ nc6[ 0 ] ] ) );
1911 if( p[ nc6[ 1 ] ] > 20 )
1913 blist.push_back( border_type( b.diff + nc6[ 1 ], p[ nc6[ 1 ] ] ) );
1916 if( p[ nc6[ 2 ] ] > 20 )
1918 blist.push_back( border_type( b.diff + nc6[ 2 ], p[ nc6[ 2 ] ] ) );
1921 if( p[ nc6[ 3 ] ] > 20 )
1923 blist.push_back( border_type( b.diff + nc6[ 3 ], p[ nc6[ 3 ] ] ) );
1926 if( p[ nc6[ 4 ] ] > 20 )
1928 blist.push_back( border_type( b.diff + nc6[ 4 ], p[ nc6[ 4 ] ] ) );
1931 if( p[ nc6[ 5 ] ] > 20 )
1933 blist.push_back( border_type( b.diff + nc6[ 5 ], p[ nc6[ 5 ] ] ) );
1947 for( size_type l = 0 ; l < blist.size( ) ; l++ )
1949 border_type &b = blist[ l ];
1950 if( b.value < min && b.value > 20 )
1956 std::cout << loop++ <<
" \r";
1958 }
while( min < max || blist.size( ) > 0 );
1960 std::cout << std::endl;
1963 for( size_type i = 0 ; i < in.size( ) ; i++ )
2002 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
2012 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2014 out[ i ] = in[ i ] > 0 ? 1 : 0;
2017 __thinning_controller__::thinning( out );
2052 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
2065 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2067 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2069 __euclidean_utility__::thinning( out );
2073 double r1 = in.
reso1( );
2074 double r2 = in.
reso2( );
2079 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2081 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2083 __euclidean_utility__::thinning( out );
2101 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
2113 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2115 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2117 __euclidean_utility__::shrink_skelton( out, __euclidean_utility__::neighbor< 6 >( ) );
2131 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
2143 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2145 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2147 __euclidean_utility__::shrink_skelton( out, __euclidean_utility__::neighbor< 26 >( ) );
2171 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
2185 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2187 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2189 __euclidean_utility__::thinning( out, __euclidean_utility__::neighbor< 6 >( ) );
2193 double r1 = in.
reso1( );
2194 double r2 = in.
reso2( );
2195 double r3 = in.
reso3( );
2201 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2203 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2205 __euclidean_utility__::thinning( out, __euclidean_utility__::neighbor< 6 >( ) );
2234 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
2248 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2250 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2252 __euclidean_utility__::thinning( out, __euclidean_utility__::neighbor< 26 >( ) );
2256 double r1 = in.
reso1( );
2257 double r2 = in.
reso2( );
2258 double r3 = in.
reso3( );
2264 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2266 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2268 __euclidean_utility__::thinning( out, __euclidean_utility__::neighbor< 26 >( ) );
2292 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
2306 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2308 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2310 __euclidean_utility__::surface_thinning( out, __euclidean_utility__::neighbor< 6 >( ) );
2314 double r1 = in.
reso1( );
2315 double r2 = in.
reso2( );
2316 double r3 = in.
reso3( );
2322 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2324 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2326 __euclidean_utility__::surface_thinning( out, __euclidean_utility__::neighbor< 6 >( ) );
2351 template <
class T1,
class T2,
class Allocator1,
class Allocator2 >
2365 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2367 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2369 __euclidean_utility__::surface_thinning( out, __euclidean_utility__::neighbor< 26 >( ) );
2373 double r1 = in.
reso1( );
2374 double r2 = in.
reso2( );
2375 double r3 = in.
reso3( );
2381 for( size_type i = 0 ; i < in.
size( ) ; i++ )
2383 out[ i ] =
static_cast< value_type
>( in[ i ] > 0 ? 1 : 0 );
2385 __euclidean_utility__::surface_thinning( out, __euclidean_utility__::neighbor< 26 >( ) );
2403 #endif // __INCLUDE_MIST_THINNING__