34 #ifndef __INCLUDE_MIST_MEDIAN_FILTER__
35 #define __INCLUDE_MIST_MEDIAN_FILTER__
38 #ifndef __INCLUDE_MIST_H__
42 #ifndef __INCLUDE_MIST_TYPE_TRAIT_H__
43 #include "../config/type_trait.h"
47 #ifndef __INCLUDE_MIST_COLOR_H__
48 #include "../config/color.h"
52 #ifndef __INCLUDE_MIST_THREAD__
53 #include "../thread.h"
63 namespace __median_filter_with_histogram__
69 template <
class Array1,
class Array2,
class Functor >
70 void median_filter(
const Array1 &in, Array2 &out,
71 typename Array1::size_type fw,
typename Array1::size_type fh,
typename Array1::size_type fd,
72 typename Array1::value_type min,
typename Array1::value_type max,
73 typename Array1::size_type thread_idy,
typename Array1::size_type thread_numy,
74 typename Array1::size_type thread_idz,
typename Array1::size_type thread_numz, Functor f )
76 typedef typename Array1::size_type size_type;
77 typedef typename Array1::difference_type difference_type;
78 typedef typename Array1::value_type value_type;
79 typedef typename Array2::value_type out_value_type;
80 typedef difference_type hist_value;
82 size_type range =
static_cast< size_type
>( max - min + 1 );
83 size_type a = 0, i, j, k, x, y, z, ri, leftnum;
84 difference_type pth, th, lt_med;
87 size_type w = in.width( );
88 size_type h = in.height( );
89 size_type d = in.depth( );
91 const bool bprogress1 = thread_idy == 0 && d == 1;
92 const bool bprogress2 = thread_idz == 0 && d > 1;
94 size_type bw = fw / 2;
95 size_type bh = fh / 2;
96 size_type bd = fd / 2;
98 difference_type *leftmost =
new difference_type[ fh * fd ];
99 difference_type *sort =
new difference_type[ fw * fh * fd + 1 ];
100 hist_value *hist =
new hist_value[ range ];
102 for( k = thread_idz ; k < d ; k += thread_numz )
104 for( j = thread_idy ; j < h ; j += thread_numy )
108 memset( hist, 0,
sizeof( hist_value ) * range );
111 for( z = k < bd ? 0 : k - bd ; z <= k + bd && z < d ; z++ )
113 for( y = j < bh ? 0 : j - bh ; y <= j + bh && y < h ; y++ )
115 leftmost[ leftnum++ ] = in( 0, y, z ) - min;
116 for( x = 0 ; x <= bw ; x++ )
118 sort[ pth++ ] = in( x, y, z ) - min;
119 hist[ in( x, y, z ) - min ]++;
125 std::sort( sort, sort + pth );
131 if( sort[ 0 ] == sort[ th ] )
138 while( med <= sort[ --a ] ){}
139 lt_med =
static_cast< signed int >( a + 1 );
142 out( i, j, k ) =
static_cast< out_value_type
>( med + min );
144 for( i = 1 ; i < w ; i++ )
150 for( a = 0 ; a < leftnum ; a++ )
152 hist[ leftmost[ a ] ]--;
154 if( leftmost[ a ] < med )
162 for( z = k < bd ? 0 : k - bd ; z <= k + bd && z < d ; z++ )
164 for( y = j < bh ? 0 : j - bh ; y <= j + bh && y < h ; y++ )
168 hist[ in( ri, y, z ) - min ]++;
170 if( in( ri, y, z ) - min < med )
178 leftmost[ leftnum++ ] = in( i - bw, y, z ) - min;
187 while( lt_med + hist[ med ] <= th )
189 lt_med += hist[ med ];
198 lt_med -= hist[ med ];
202 out( i, j, k ) =
static_cast< out_value_type
>( med + min );
207 f( static_cast< double >( j + 1 ) / static_cast< double >( h ) * 100.0 );
213 f( static_cast< double >( k + 1 ) / static_cast< double >( d ) * 100.0 );
224 namespace __median_filter_divide_conquer__
231 inline T nth_value(
const T *a,
size_t num,
size_t c, T *work1, T *work2, T *work3 )
233 typedef T value_type;
236 size_t wi1, wi2, wi3;
238 value_type *w1 = work1;
239 value_type *w2 = work2;
240 value_type *src, *www;
245 for( i = 0 ; i < num ; i++ )
249 w1[ wi1++ ] = a[ i ];
251 else if( a[ i ] > s )
253 w2[ wi2++ ] = a[ i ];
267 else if( wi1 + wi3 <= c )
284 for( i = 0 ; i < num ; i++ )
288 w1[ wi1++ ] = src[ i ];
290 else if( src[ i ] > s )
292 w2[ wi2++ ] = src[ i ];
307 else if( wi1 + wi3 <= c )
329 template <
class Array1,
class Array2,
class Functor >
330 void median_filter(
const Array1 &in, Array2 &out,
331 typename Array1::size_type fw,
typename Array1::size_type fh,
typename Array1::size_type fd,
332 typename Array1::size_type thread_idy,
typename Array1::size_type thread_numy,
333 typename Array1::size_type thread_idz,
typename Array1::size_type thread_numz, Functor f )
335 typedef typename Array1::size_type size_type;
336 typedef typename Array1::value_type value_type;
337 typedef typename Array2::value_type out_value_type;
339 size_type i, j, k, x, y, z, ri;
340 size_type pth, c, th, windex;
342 size_type w = in.width( );
343 size_type h = in.height( );
344 size_type d = in.depth( );
346 const bool bprogress1 = thread_idy == 0 && d == 1;
347 const bool bprogress2 = thread_idz == 0 && d > 1;
349 size_type bw = fw / 2;
350 size_type bh = fh / 2;
351 size_type bd = fd / 2;
355 size_type size = fw * fh * fd;
357 value_type *work =
new value_type[ size + 1 ];
358 value_type *work1 =
new value_type[ size + 1 ];
359 value_type *work2 =
new value_type[ size + 1 ];
360 value_type *work3 =
new value_type[ size + 1 ];
361 value_type **sort =
new value_type*[ fw ];
363 for( k = thread_idz ; k < d ; k += thread_numz )
369 else if( k + bd >= d )
371 bbd = d - k + bd + 1;
378 for( j = thread_idy ; j < h ; j += thread_numy )
384 else if( j + bh >= h )
386 bbh = h - j + bh + 1;
393 for( i = 0 ; i < fw ; i++ )
395 sort[ i ] = work + i * bbh * bbd;
402 for( x = 0 ; x <= bw ; x++ )
404 windex = windex % fw;
406 for( z = k < bd ? 0 : k - bd ; z <= k + bd && z < d ; z++ )
408 for( y = j < bh ? 0 : j - bh ; y <= j + bh && y < h ; y++ )
410 sort[ windex ][ c++ ] = in( x, y, z );
416 pth = ( bw + 1 ) * bbh * bbd;
417 th = ( pth - 1 ) / 2;
418 out( i, j, k ) =
static_cast< out_value_type
>( nth_value( work, pth, th, work1, work2, work3 ) );
420 for( i = 1 ; i < bw ; i++ )
423 pth = ( i + bw + 1 ) * bbh * bbd;
424 windex = windex % fw;
427 for( z = k < bd ? 0 : k - bd ; z <= k + bd && z < d ; z++ )
429 for( y = j < bh ? 0 : j - bh ; y <= j + bh && y < h ; y++ )
431 sort[ windex ][ c++ ] = in( i, y, z );
435 th = ( pth - 1 ) / 2;
437 out( i, j, k ) =
static_cast< out_value_type
>( nth_value( work, pth, th, work1, work2, work3 ) );
442 pth = fw * bbh * bbd;
443 th = ( pth - 1 ) / 2;
444 for( ; i + bw < w ; i++ )
447 windex = windex % fw;
450 for( z = k < bd ? 0 : k - bd ; z <= k + bd && z < d ; z++ )
452 for( y = j < bh ? 0 : j - bh ; y <= j + bh && y < h ; y++ )
454 sort[ windex ][ c++ ] = in( ri, y, z );
458 out( i, j, k ) =
static_cast< out_value_type
>( nth_value( work, pth, th, work1, work2, work3 ) );
465 windex = windex % fw;
468 for( z = k < bd ? 0 : k - bd ; z <= k + bd && z < d ; z++ )
470 for( y = j < bh ? 0 : j - bh ; y <= j + bh && y < h ; y++ )
472 sort[ windex ][ c++ ] = 0;
476 out( i, j, k ) =
static_cast< out_value_type
>( nth_value( work, pth, th, work1, work2, work3 ) );
483 f( static_cast< double >( j + 1 ) / static_cast< double >( h ) * 100.0 );
489 f( static_cast< double >( k + 1 ) / static_cast< double >( d ) * 100.0 );
504 namespace __median_filter_specialized_version__
507 inline void sort3x3(
const T &v0,
const T &v1,
const T &v2, T v[ 3 ] )
560 inline void sort2x2(
const T &v0,
const T &v1, T v[ 3 ] )
575 inline void sort3x3(
const T &v0,
const T &v1,
const T &v2, T w0[ 3 ], T w1[ 3 ], T w2[ 3 ], T *v[ 3 ] )
628 inline void sort2x2(
const T &v0,
const T &v1, T w0[ 3 ], T w1[ 3 ], T *v[ 3 ] )
643 inline const T &minimum(
const T &v0,
const T &v1 )
645 return( v0 < v1 ? v0 : v1 );
649 inline const T &minimum(
const T &v0,
const T &v1,
const T &v2 )
651 return( v0 < v1 ? ( v0 < v2 ? v0 : v2 ) : ( v1 < v2 ? v1 : v2 ) );
655 inline const T &maximum(
const T &v0,
const T &v1,
const T &v2 )
657 return( v0 > v1 ? ( v0 > v2 ? v0 : v2 ) : ( v1 > v2 ? v1 : v2 ) );
661 inline const T &maximum(
const T &v0,
const T &v1 )
663 return( v0 > v1 ? v0 : v1 );
667 inline const T &median(
const T &v0,
const T &v1,
const T &v2 )
720 template <
class T1,
class T2,
class Allocator1,
class Allocator2,
class Functor >
721 void median_filter3x3(
const array2< T1, Allocator1 > &in, array2< T2, Allocator2 > &out,
722 typename array2< T1, Allocator1 >::size_type thread_id,
typename array2< T1, Allocator1 >::size_type thread_num, Functor f )
724 typedef typename array2< T1, Allocator1 >::size_type size_type;
725 typedef typename array2< T1, Allocator1 >::value_type value_type;
726 typedef typename array2< T1, Allocator1 >::difference_type difference_type;
727 typedef typename array2< T2, Allocator2 >::value_type out_value_type;
730 size_type w = in.width( );
731 size_type h = in.height( );
733 value_type work0[ 3 ];
734 value_type work1[ 3 ];
735 value_type work2[ 3 ];
736 value_type *work[ 3 ] = { work0, work1, work2 };
737 value_type *sort[ 3 ];
741 for( j = thread_id ; j < 1 ; j += thread_num )
743 sort2x2( in( 0, 0 ), in( 0, 1 ), work0 );
744 sort2x2( in( 1, 0 ), in( 1, 1 ), work1 );
746 sort2x2( work0[ 1 ], work1[ 1 ], work0, work1, sort );
747 out( 0, 0 ) =
static_cast< out_value_type
>( minimum( sort[ 0 ][ 1 ], sort[ 1 ][ 0 ] ) );
749 for( i = 1 ; i < w - 1 ; i++ )
752 sort2x2( in( i + 1, 0 ), in( i + 1, 0 + 1 ), work[ wi ] );
753 sort3x3( work0[ 1 ], work1[ 1 ], work2[ 1 ], work0, work1, work2, sort );
755 value_type &x = sort[ 1 ][ 1 ];
756 value_type &y = sort[ 0 ][ 1 ];
757 value_type &z = sort[ 2 ][ 0 ];
761 value_type &w = sort[ 1 ][ 0 ];
762 out( i, 0 ) =
static_cast< out_value_type
>( minimum( y, z, w ) );
766 out( i, 0 ) =
static_cast< out_value_type
>( x );
770 sort2x2( work[ ( w - 2 ) % 3 ][ 1 ], work[ ( w - 1 ) % 3 ][ 1 ], work[ ( w - 2 ) % 3 ], work[ ( w - 1 ) % 3 ], sort );
771 out( w - 1, 0 ) =
static_cast< out_value_type
>( minimum( sort[ 0 ][ 1 ], sort[ 1 ][ 0 ] ) );
775 f( static_cast< double >( j + 1 ) / static_cast< double >( h ) * 100.0 );
780 for( ; j < h - 1 ; j += thread_num )
782 sort3x3( in( 0, j - 1 ), in( 0, j ), in( 0, j + 1 ), work0 );
783 sort3x3( in( 1, j - 1 ), in( 1, j ), in( 1, j + 1 ), work1 );
785 sort2x2( work0[ 1 ], work1[ 1 ], work0, work1, sort );
786 out( 0, j ) =
static_cast< out_value_type
>( median( sort[ 0 ][ 2 ], sort[ 1 ][ 0 ], sort[ 1 ][ 1 ] ) );
788 for( i = 1 ; i < w - 1 ; i++ )
791 sort3x3( in( i + 1, j - 1 ), in( i + 1, j ), in( i + 1, j + 1 ), work[ wi ] );
792 sort3x3( work0[ 1 ], work1[ 1 ], work2[ 1 ], work0, work1, work2, sort );
794 value_type &x = sort[ 1 ][ 1 ];
795 value_type &y = sort[ 0 ][ 2 ];
796 value_type &z = sort[ 2 ][ 0 ];
800 value_type &w = sort[ 1 ][ 0 ];
801 out( i, j ) =
static_cast< out_value_type
>( minimum( y, z, w ) );
803 else if( x > y && x > z )
805 value_type &w = sort[ 1 ][ 2 ];
806 out( i, j ) =
static_cast< out_value_type
>( maximum( y, z, w ) );
810 out( i, j ) =
static_cast< out_value_type
>( x );
814 sort2x2( work[ ( w - 2 ) % 3 ][ 1 ], work[ ( w - 1 ) % 3 ][ 1 ], work[ ( w - 2 ) % 3 ], work[ ( w - 1 ) % 3 ], sort );
815 out( w - 1, j ) =
static_cast< out_value_type
>( median( sort[ 0 ][ 2 ], sort[ 1 ][ 0 ], sort[ 1 ][ 1 ] ) );
819 f( static_cast< double >( j + 1 ) / static_cast< double >( h ) * 100.0 );
825 for( ; j < h ; j += thread_num )
827 sort2x2( in( 0, h - 2 ), in( 0, h - 1 ), work0 );
828 sort2x2( in( 1, h - 2 ), in( 1, h - 1 ), work1 );
830 sort2x2( work0[ 1 ], work1[ 1 ], work0, work1, sort );
831 out( 0, h - 1 ) =
static_cast< out_value_type
>( minimum( sort[ 0 ][ 1 ], sort[ 1 ][ 0 ] ) );
833 for( i = 1 ; i < w - 1 ; i++ )
836 sort2x2( in( i + 1, h - 2 ), in( i + 1, h - 1 ), work[ wi ] );
837 sort3x3( work0[ 1 ], work1[ 1 ], work2[ 1 ], work0, work1, work2, sort );
839 value_type &x = sort[ 1 ][ 1 ];
840 value_type &y = sort[ 0 ][ 1 ];
841 value_type &z = sort[ 2 ][ 0 ];
845 value_type &w = sort[ 1 ][ 0 ];
846 out( i, h - 1 ) =
static_cast< out_value_type
>( minimum( y, z, w ) );
850 out( i, h - 1 ) =
static_cast< out_value_type
>( x );
854 sort2x2( work[ ( w - 2 ) % 3 ][ 1 ], work[ ( w - 1 ) % 3 ][ 1 ], work[ ( w - 2 ) % 3 ], work[ ( w - 1 ) % 3 ], sort );
855 out( w - 1, h - 1 ) =
static_cast< out_value_type
>( minimum( sort[ 0 ][ 1 ], sort[ 1 ][ 0 ] ) );
859 f( static_cast< double >( j + 1 ) / static_cast< double >( h ) * 100.0 );
867 namespace __median_filter_controller__
869 template <
class T,
class Allocator >
870 void get_min_max(
const array< T, Allocator > &in,
typename array< T, Allocator >::value_type &min,
typename array< T, Allocator >::value_type &max )
873 for(
typename array< T, Allocator >::size_type i = 0 ; i < in.size( ) ; i++ )
879 else if( max < in[ i ] )
887 struct __median_filter__
889 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
890 static void median_filter(
const array< T1, Allocator1 > &in, array< T2, Allocator2 > &out,
891 typename array< T1, Allocator1 >::size_type fw,
typename array< T1, Allocator1 >::size_type fh,
typename array< T1, Allocator1 >::size_type fd,
892 typename array< T1, Allocator1 >::size_type thread_id,
typename array< T1, Allocator1 >::size_type thread_num, Functor f )
894 typedef typename array< T1, Allocator1 >::value_type value_type;
895 value_type min = in[ 0 ];
896 value_type max = in[ 0 ];
897 get_min_max( in, min, max );
898 __median_filter_with_histogram__::median_filter( in, out, fw, fh, fd, min, max, 0, 1, thread_id, thread_num, f );
901 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
902 static void median_filter(
const array2< T1, Allocator1 > &in, array2< T2, Allocator2 > &out,
903 typename array2< T1, Allocator1 >::size_type fw,
typename array2< T1, Allocator1 >::size_type fh,
typename array2< T1, Allocator1 >::size_type fd,
904 typename array2< T1, Allocator1 >::size_type thread_id,
typename array2< T1, Allocator1 >::size_type thread_num, Functor f )
906 typedef typename array2< T1, Allocator1 >::value_type value_type;
908 if( fw == 3 && fh == 3 )
910 __median_filter_specialized_version__::median_filter3x3( in, out, thread_id, thread_num, f );
914 value_type min = in[ 0 ];
915 value_type max = in[ 0 ];
916 get_min_max( in, min, max );
917 __median_filter_with_histogram__::median_filter( in, out, fw, fh, fd, min, max, thread_id, thread_num, 0, 1, f );
921 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
922 static void median_filter(
const array3< T1, Allocator1 > &in, array3< T2, Allocator2 > &out,
923 typename array3< T1, Allocator1 >::size_type fw,
typename array3< T1, Allocator1 >::size_type fh,
typename array3< T1, Allocator1 >::size_type fd,
924 typename array3< T1, Allocator1 >::size_type thread_id,
typename array3< T1, Allocator1 >::size_type thread_num, Functor f )
926 typedef typename array3< T1, Allocator1 >::value_type value_type;
927 value_type min = in[ 0 ];
928 value_type max = in[ 0 ];
929 get_min_max( in, min, max );
930 __median_filter_with_histogram__::median_filter( in, out, fw, fh, fd, min, max, 0, 1, thread_id, thread_num, f );
937 struct __median_filter__< false >
939 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
940 static void median_filter(
const array< T1, Allocator1 > &in, array< T2, Allocator2 > &out,
941 typename array< T1, Allocator1 >::size_type fw,
typename array< T1, Allocator1 >::size_type fh,
typename array< T1, Allocator1 >::size_type fd,
942 typename array< T1, Allocator1 >::size_type thread_id,
typename array< T1, Allocator1 >::size_type thread_num, Functor f )
944 __median_filter_divide_conquer__::median_filter( in, out, fw, fh, fd, 0, 1, thread_id, thread_num, f );
947 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
948 static void median_filter(
const array2< T1, Allocator1 > &in, array2< T2, Allocator2 > &out,
949 typename array2< T1, Allocator1 >::size_type fw,
typename array2< T1, Allocator1 >::size_type fh,
typename array2< T1, Allocator1 >::size_type fd,
950 typename array2< T1, Allocator1 >::size_type thread_id,
typename array2< T1, Allocator1 >::size_type thread_num, Functor f )
952 if( fw == 3 && fh == 3 )
954 __median_filter_specialized_version__::median_filter3x3( in, out, thread_id, thread_num, f );
958 __median_filter_divide_conquer__::median_filter( in, out, fw, fh, fd, thread_id, thread_num, 0, 1, f );
962 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
963 static void median_filter(
const array3< T1, Allocator1 > &in, array3< T2, Allocator2 > &out,
964 typename array3< T1, Allocator1 >::size_type fw,
typename array3< T1, Allocator1 >::size_type fh,
typename array3< T1, Allocator1 >::size_type fd,
965 typename array3< T1, Allocator1 >::size_type thread_id,
typename array3< T1, Allocator1 >::size_type thread_num, Functor f )
967 __median_filter_divide_conquer__::median_filter( in, out, fw, fh, fd, 0, 1, thread_id, thread_num, f );
972 template <
class T1,
class T2,
class Functor >
973 class median_thread :
public mist::thread< median_thread< T1, T2, Functor > >
977 typedef typename base::thread_exit_type thread_exit_type;
978 typedef typename T1::size_type size_type;
979 typedef typename T1::value_type value_type;
995 void setup_parameters(
const T1 &in, T2 &out,
size_t fw, size_type fh, size_type fd, size_type thread_id, size_type thread_num, Functor f )
1002 thread_id_ = thread_id;
1003 thread_num_ = thread_num;
1007 const median_thread& operator =(
const median_thread &p )
1011 base::operator =( p );
1012 thread_id_ = p.thread_id_;
1013 thread_num_ = p.thread_num_;
1024 median_thread( size_type
id = 0, size_type num = 1 ) : thread_id_( id ), thread_num_( num ),
1025 in_( NULL ), out_( NULL ), fw_( 3 ), fh_( 3 ), fd_( 3 )
1028 median_thread(
const median_thread &p ) : base( p ), thread_id_( p.thread_id_ ), thread_num_( p.thread_num_ ),
1029 in_( p.in_ ), out_( p.out_ ), fw_( p.fw_ ), fh_( p.fh_ ), fd_( p.fd_ )
1035 virtual thread_exit_type thread_function( )
1037 __median_filter__< type_and< is_integer< value_type >::value, !is_color< value_type >::value >::value >::median_filter( *in_, *out_, fw_, fh_, fd_, thread_id_, thread_num_, f_ );
1069 template <
class T1,
class Allocator1,
class T2,
class Allocator2 >
1080 fw =
static_cast< size_type
>( fw / 2 ) * 2 + 1;
1082 __median_filter_controller__::__median_filter__< is_integer< T1 >::value >::median_filter( in, out, fw, 1, 1, 0, 1,
__mist_dmy_callback__( ) );
1106 template <
class T1,
class Allocator1,
class T2,
class Allocator2 >
1118 fw =
static_cast< size_type
>( fw / 2 ) * 2 + 1;
1120 __median_filter_controller__::__median_filter__< is_integer< T1 >::value >::median_filter( in, out, fw, 1, 1, 0, 1,
__mist_dmy_callback__( ) );
1145 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
1156 typedef __median_filter_controller__::median_thread< array2< T1, Allocator1 >,
array2< T2, Allocator2 >, Functor > median_thread;
1158 if( thread_num == 0 )
1160 thread_num =
static_cast< size_type
>(
get_cpu_num( ) );
1167 median_thread *
thread =
new median_thread[ thread_num ];
1169 fw =
static_cast< size_type
>( fw / 2 ) * 2 + 1;
1170 fh =
static_cast< size_type
>( fh / 2 ) * 2 + 1;
1173 for( i = 0 ; i < thread_num ; i++ )
1175 thread[ i ].setup_parameters( in, out, fw, fh, 1, i, thread_num, f );
1209 template <
class T1,
class Allocator1,
class T2,
class Allocator2 >
1234 template <
class T1,
class Allocator1,
class T2,
class Allocator2 >
1263 template <
class T1,
class Allocator1,
class T2,
class Allocator2,
class Functor >
1274 typedef __median_filter_controller__::median_thread< array3< T1, Allocator1 >,
array3< T2, Allocator2 >, Functor > median_thread;
1276 if( thread_num == 0 )
1278 thread_num =
static_cast< size_type
>(
get_cpu_num( ) );
1286 median_thread *
thread =
new median_thread[ thread_num ];
1288 fw =
static_cast< size_type
>( fw / 2 ) * 2 + 1;
1289 fh =
static_cast< size_type
>( fh / 2 ) * 2 + 1;
1290 fd =
static_cast< size_type
>( fd / 2 ) * 2 + 1;
1293 for( i = 0 ; i < thread_num ; i++ )
1295 thread[ i ].setup_parameters( in, out, fw, fh, fd, i, thread_num, f );
1330 template <
class T1,
class Allocator1,
class T2,
class Allocator2 >
1355 template <
class T1,
class Allocator1,
class T2,
class Allocator2 >
1372 #endif // __INCLUDE_MIST_MEDIAN_FILTER__