mode.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 
35 
36 #ifndef __INCLUDE_MIST_MODE__
37 #define __INCLUDE_MIST_MODE__
38 
39 
40 #ifndef __INCLUDE_MIST_H__
41 #include "../mist.h"
42 #endif
43 
44 #ifndef __INCLUDE_MIST_LIMITS__
45 #include "../limits.h"
46 #endif
47 
48 
49 #ifndef __INCLUDE_MIST_THREAD__
50 #include "../thread.h"
51 #endif
52 
53 #include <vector>
54 #include <cmath>
55 
56 
57 // mist名前空間の始まり
59 
60 
61 
69 
70 
75 namespace mode_filter
76 {
78  struct point
79  {
80  typedef ptrdiff_t difference_type;
84 
91  point( difference_type xx, difference_type yy, difference_type zz ) : x( xx ), y( yy ), z( zz )
92  {
93  }
94  };
95 
96 
103  {
104  typedef std::vector< point > list_type;
108  size_t margin_x;
109  size_t margin_y;
110  size_t margin_z;
111  };
112 
113 
124  inline mode_structure circle( double radius, double resoX, double resoY )
125  {
126  typedef array2< bool >::size_type size_type;
127  typedef array2< bool >::difference_type difference_type;
128 
129  double max_reso = resoX > resoY ? resoX: resoY;
130 
131  double ax = resoX / max_reso;
132  double ay = resoY / max_reso;
133  double xx, yy, rr = radius * radius;
134  difference_type rx = static_cast< size_type >( ceil( radius / ax ) );
135  difference_type ry = static_cast< size_type >( ceil( radius / ay ) );
136  difference_type x, y;
137 
138  size_type ox = rx + 1;
139  size_type oy = ry + 1;
140 
141  size_type w = 2 * ox + 1;
142  size_type h = 2 * oy + 1;
143 
144  mode_structure s;
145  array2< bool > m( w, h );
146 
147  // 円の構造要素を作成する
148  for( y = -ry ; y <= ry ; y++ )
149  {
150  yy = y * y * ay * ay;
151  for( x = -rx ; x <= rx ; x++ )
152  {
153  xx = x * x * ax * ax;
154  if( xx + yy <= rr )
155  {
156  m( x + ox, y + oy ) = true;
157  }
158  }
159  }
160 
161  // 円の構造要素の各点を設定する
162  for( y = -ry ; y <= ry ; y++ )
163  {
164  for( x = -rx ; x <= rx ; x++ )
165  {
166  if( m( x + ox, y + oy ) )
167  {
168  s.object.push_back( point( x, y, 0 ) );
169  if( !m( x + ox + 1, y + oy ) )
170  {
171  s.update_in.push_back( point( x, y, 0 ) );
172  }
173  if( !m( x + ox - 1, y + oy ) )
174  {
175  s.update_out.push_back( point( x - 1, y, 0 ) );
176  }
177  }
178  }
179  }
180 
181  s.margin_x = rx;
182  s.margin_y = ry;
183  s.margin_z = 0;
184 
185  return( s );
186  }
187 
188 
189 
201  inline mode_structure sphere( double radius, double resoX, double resoY, double resoZ )
202  {
203  typedef array3< bool >::size_type size_type;
204  typedef array3< bool >::difference_type difference_type;
205 
206  double max_reso = resoX > resoY ? resoX: resoY;
207  max_reso = max_reso > resoZ ? max_reso : resoZ;
208 
209  double ax = resoX / max_reso;
210  double ay = resoY / max_reso;
211  double az = resoZ / max_reso;
212  double xx, yy, zz, rr = radius * radius;
213  difference_type rx = static_cast< size_type >( ceil( radius / ax ) );
214  difference_type ry = static_cast< size_type >( ceil( radius / ay ) );
215  difference_type rz = static_cast< size_type >( ceil( radius / az ) );
216  difference_type x, y, z;
217 
218  size_type ox = rx + 1;
219  size_type oy = ry + 1;
220  size_type oz = rz + 1;
221 
222  size_type w = 2 * ox + 1;
223  size_type h = 2 * oy + 1;
224  size_type d = 2 * oz + 1;
225 
226  mode_structure s;
227  array3< bool > m( w, h, d );
228 
229  // 球の構造要素を作成する
230  for( z = -rz ; z <= rz ; z++ )
231  {
232  zz = z * z * az * az;
233  for( y = -ry ; y <= ry ; y++ )
234  {
235  yy = y * y * ay * ay;
236  for( x = -rx ; x <= rx ; x++ )
237  {
238  xx = x * x * ax * ax;
239  if( xx + yy + zz <= rr )
240  {
241  m( x + ox, y + oy, z + oz ) = true;
242  }
243  }
244  }
245  }
246 
247  // 球の構造要素の各点を設定する
248  for( z = -rz ; z <= rz ; z++ )
249  {
250  for( y = -ry ; y <= ry ; y++ )
251  {
252  for( x = -rx ; x <= rx ; x++ )
253  {
254  if( m( x + ox, y + oy, z + oz ) )
255  {
256  s.object.push_back( point( x, y, z ) );
257  if( !m( x + ox + 1, y + oy, z + oz ) )
258  {
259  s.update_in.push_back( point( x, y, z ) );
260  }
261  if( !m( x + ox - 1, y + oy, z + oz ) )
262  {
263  s.update_out.push_back( point( x - 1, y, z ) );
264  }
265  }
266  }
267  }
268  }
269 
270  s.margin_x = rx;
271  s.margin_y = ry;
272  s.margin_z = rz;
273 
274  return( s );
275  }
276 
277 
278 
289  inline mode_structure square( double radius, double resoX, double resoY )
290  {
291  using namespace std;
292  typedef array2< bool >::size_type size_type;
293  typedef array2< bool >::difference_type difference_type;
294 
295  double max_reso = resoX > resoY ? resoX: resoY;
296 
297  double ax = resoX / max_reso;
298  double ay = resoY / max_reso;
299  double xx, yy;
300  difference_type rx = static_cast< size_type >( ceil( radius / ax ) );
301  difference_type ry = static_cast< size_type >( ceil( radius / ay ) );
302  difference_type x, y;
303 
304  size_type ox = rx + 1;
305  size_type oy = ry + 1;
306 
307  size_type w = 2 * ox + 1;
308  size_type h = 2 * oy + 1;
309 
310  mode_structure s;
311  array2< bool > m( w, h );
312 
313  // 正方形の構造要素を作成する
314  for( y = -ry ; y <= ry ; y++ )
315  {
316  yy = y * ay;
317  for( x = -rx ; x <= rx ; x++ )
318  {
319  xx = x * ax;
320  if( std::abs( xx ) <= radius && std::abs( yy ) <= radius )
321  {
322  m( x + ox, y + oy ) = true;
323  }
324  }
325  }
326 
327  // 正方形の構造要素の各点を設定する
328  for( y = -ry ; y <= ry ; y++ )
329  {
330  for( x = -rx ; x <= rx ; x++ )
331  {
332  if( m( x + ox, y + oy ) )
333  {
334  s.object.push_back( point( x, y, 0 ) );
335  if( !m( x + ox + 1, y + oy ) )
336  {
337  s.update_in.push_back( point( x, y, 0 ) );
338  }
339  if( !m( x + ox - 1, y + oy ) )
340  {
341  s.update_out.push_back( point( x - 1, y, 0 ) );
342  }
343  }
344  }
345  }
346 
347  s.margin_x = rx;
348  s.margin_y = ry;
349  s.margin_z = 0;
350 
351  return( s );
352  }
353 
354 
366  inline mode_structure cube( double radius, double resoX, double resoY, double resoZ )
367  {
368  using namespace std;
369  typedef array3< bool >::size_type size_type;
370  typedef array3< bool >::difference_type difference_type;
371 
372  double max_reso = resoX > resoY ? resoX: resoY;
373  max_reso = max_reso > resoZ ? max_reso : resoZ;
374 
375  double ax = resoX / max_reso;
376  double ay = resoY / max_reso;
377  double az = resoZ / max_reso;
378  double xx, yy, zz;
379  difference_type rx = static_cast< size_type >( ceil( radius / ax ) );
380  difference_type ry = static_cast< size_type >( ceil( radius / ay ) );
381  difference_type rz = static_cast< size_type >( ceil( radius / az ) );
382  difference_type x, y, z;
383 
384  size_type ox = rx + 1;
385  size_type oy = ry + 1;
386  size_type oz = rz + 1;
387 
388  size_type w = 2 * ox + 1;
389  size_type h = 2 * oy + 1;
390  size_type d = 2 * oz + 1;
391 
392  mode_structure s;
393  array3< bool > m( w, h, d );
394 
395  // 立方体の構造要素を作成する
396  for( z = -rz ; z <= rz ; z++ )
397  {
398  zz = z * az;
399  for( y = -ry ; y <= ry ; y++ )
400  {
401  yy = y * ay;
402  for( x = -rx ; x <= rx ; x++ )
403  {
404  xx = x * ax;
405  if( std::abs( xx ) <= radius && std::abs( yy ) <= radius && std::abs( zz ) <= radius )
406  {
407  m( x + ox, y + oy, z + oz ) = true;
408  }
409  }
410  }
411  }
412 
413  // 立方体の構造要素の各点を設定する
414  for( z = -rz ; z <= rz ; z++ )
415  {
416  for( y = -ry ; y <= ry ; y++ )
417  {
418  for( x = -rx ; x <= rx ; x++ )
419  {
420  if( m( x + ox, y + oy, z + oz ) )
421  {
422  s.object.push_back( point( x, y, z ) );
423  if( !m( x + ox + 1, y + oy, z + oz ) )
424  {
425  s.update_in.push_back( point( x, y, z ) );
426  }
427  if( !m( x + ox - 1, y + oy, z + oz ) )
428  {
429  s.update_out.push_back( point( x - 1, y, z ) );
430  }
431  }
432  }
433  }
434  }
435 
436  s.margin_x = rx;
437  s.margin_y = ry;
438  s.margin_z = rz;
439 
440  return( s );
441  }
442 
443 
444 
456  template < class Array >
457  inline mode_structure create_mode_structure( const Array &in, typename Array::size_type cx, typename Array::size_type cy = 0, typename Array::size_type cz = 0 )
458  {
459  using namespace std;
460  typedef typename Array::size_type size_type;
461  typedef typename Array::difference_type difference_type;
462  difference_type x, y, z;
463 
464  difference_type w = in.width( );
465  difference_type h = in.height( );
466  difference_type d = in.depth( );
467 
468  mode_structure s;
469  marray< Array > m( in, 1 );
470 
471  // 構造要素の形を作成する
472  for( z = 0 ; z < d ; z++ )
473  {
474  for( y = 0 ; y < h ; y++ )
475  {
476  for( x = 0 ; x < w ; x++ )
477  {
478  m( x, y, z ) = in( x, y, z ) == 0 ? false : true;
479  }
480  }
481  }
482 
483  // 構造要素の各点を設定する
484  for( z = 0 ; z < d ; z++ )
485  {
486  for( y = 0 ; y < h ; y++ )
487  {
488  size_t life = 0;
489  for( x = 0 ; x < w ; x++ )
490  {
491  if( m( x, y, z ) )
492  {
493  s.object.push_back( point( x - cx, y - cy, z - cz ) );
494  if( !m( x + 1, y, z ) )
495  {
496  s.update_in.push_back( point( x - cx, y - cy, z - cz ) );
497  }
498  if( !m( x - 1, y, z ) )
499  {
500  s.update_out.push_back( point( x - cx - 1, y - cy, z - cz ) );
501  }
502  }
503  }
504  }
505  }
506 
507  s.margin_x = cx > w - cx - 1 ? cx : w - cx;
508  s.margin_y = cy > h - cy - 1 ? cy : h - cy;
509  s.margin_z = cz > d - cz - 1 ? cz : d - cz;
510 
511  return( s );
512  }
513 
514 
524  template < class Array >
525  inline std::vector< ptrdiff_t > create_pointer_diff_list( const Array &in, const std::vector< point > &list )
526  {
527  typedef typename Array::size_type size_type;
528  typedef typename Array::const_pointer const_pointer;
529  size_type cx = in.width( ) / 2;
530  size_type cy = in.height( ) / 2;
531  size_type cz = in.depth( ) / 2;
532  const_pointer p = &( in( cx, cy, cz ) );
533 
534  std::vector< ptrdiff_t > out;
535 
536  for( size_type i = 0 ; i < list.size( ) ; i++ )
537  {
538  const point &pt = list[ i ];
539  const_pointer pp = &in( cx + pt.x, cy + pt.y, cz + pt.z );
540  out.push_back( pp - p );
541  }
542 
543  return( out );
544  }
545 }
546 
547 
549 // 最頻値フィルタグループの終わり
550 
551 
552 namespace __mode__
553 {
554  template < class Array1, class Array2, class Functor >
555  void mode( const Array1 &in, Array2 &out,
556  const std::vector< ptrdiff_t > &object, const std::vector< ptrdiff_t > &update_in, const std::vector< ptrdiff_t > &update_out,
557  typename Array1::size_type thread_idy, typename Array1::size_type thread_numy,
558  typename Array1::size_type thread_idz, typename Array1::size_type thread_numz, Functor f )
559  {
560  typedef typename Array1::size_type size_type;
561  typedef typename Array1::value_type value_type;
562  typedef typename Array1::const_pointer const_pointer;
563  typedef typename Array1::difference_type difference_type;
564  typedef typename Array2::value_type out_value_type;
565  typedef typename Array2::value_type out_value_type;
566  typedef std::vector< ptrdiff_t > list_type;
567  typedef list_type::const_iterator const_iterator;
568 
569  size_type w = in.width( );
570  size_type h = in.height( );
571  size_type d = in.depth( );
572 
573  const bool bprogress1 = thread_idy == 0 && d == 1;
574  const bool bprogress2 = thread_idz == 0 && d > 1;
575 
576  for( size_type k = thread_idz ; k < d ; k += thread_numz )
577  {
578  for( size_type j = thread_idy ; j < h ; j += thread_numy )
579  {
580  const_pointer p = &in( 0, j, k );
581  difference_type count[ 2 ] = { 0, 0 };
582  for( const_iterator ite = object.begin( ) ; ite != object.end( ) ; ++ite )
583  {
584  count[ p[ *ite ] > 0 ]++;
585  }
586 
587  out( 0, j, k ) = static_cast< out_value_type >( count[ 0 ] > count[ 1 ] ? 0 : 1 );
588 
589  for( size_type i = 1 ; i < w ; i++ )
590  {
591  p = &in( i, j, k );
592 
593  // 構造要素から抜けた分だけ減算する
594  for( const_iterator ite = update_out.begin( ) ; ite != update_out.end( ) ; ++ite )
595  {
596  count[ p[ *ite ] > 0 ]--;
597  }
598 
599  // 構造要素に新しく入った分を加える
600  for( const_iterator ite = update_in.begin( ) ; ite != update_in.end( ) ; ++ite )
601  {
602  count[ p[ *ite ] > 0 ]++;
603  }
604 
605  out( i, j, k ) = static_cast< out_value_type >( count[ 0 ] > count[ 1 ] ? 0 : 1 );
606  }
607 
608  if( bprogress1 )
609  {
610  f( static_cast< double >( j + 1 ) / static_cast< double >( h ) * 100.0 );
611  }
612  }
613 
614  if( bprogress2 )
615  {
616  f( static_cast< double >( k + 1 ) / static_cast< double >( d ) * 100.0 );
617  }
618  }
619  }
620 }
621 
622 
623 
624 
625 // 最頻値フィルタのスレッド実装
626 namespace __mode_controller__
627 {
628  // 各次元をラッピングするための関数
629  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
630  void mode( const marray< array< T1, Allocator1 > > &in, array< T2, Allocator2 > &out,
631  const std::vector< ptrdiff_t > &object, const std::vector< ptrdiff_t > &update_in, const std::vector< ptrdiff_t > &update_out,
632  typename array< T1, Allocator1 >::size_type thread_id, typename array< T1, Allocator1 >::size_type thread_num, Functor f )
633  {
634  __mode__::mode( in, out, object, update_in, update_out, 0, 1, thread_id, thread_num, f );
635  }
636 
637  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
638  void mode( const marray< array1< T1, Allocator1 > > &in, array1< T2, Allocator2 > &out,
639  const std::vector< ptrdiff_t > &object, const std::vector< ptrdiff_t > &update_in, const std::vector< ptrdiff_t > &update_out,
640  typename array1< T1, Allocator1 >::size_type thread_id, typename array1< T1, Allocator1 >::size_type thread_num, Functor f )
641  {
642  __mode__::mode( in, out, object, update_in, update_out, 0, 1, thread_id, thread_num, f );
643  }
644 
645  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
646  void mode( const marray< array2< T1, Allocator1 > > &in, array2< T2, Allocator2 > &out,
647  const std::vector< ptrdiff_t > &object, const std::vector< ptrdiff_t > &update_in, const std::vector< ptrdiff_t > &update_out,
648  typename array2< T1, Allocator1 >::size_type thread_id, typename array2< T1, Allocator1 >::size_type thread_num, Functor f )
649  {
650  __mode__::mode( in, out, object, update_in, update_out, thread_id, thread_num, 0, 1, f );
651  }
652 
653  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
654  void mode( const marray< array3< T1, Allocator1 > > &in, array3< T2, Allocator2 > &out,
655  const std::vector< ptrdiff_t > &object, const std::vector< ptrdiff_t > &update_in, const std::vector< ptrdiff_t > &update_out,
656  typename array3< T1, Allocator1 >::size_type thread_id, typename array3< T1, Allocator1 >::size_type thread_num, Functor f )
657  {
658  __mode__::mode( in, out, object, update_in, update_out, 0, 1, thread_id, thread_num, f );
659  }
660 
661 
662  template < class T1, class T2, class Functor >
663  class mode_thread : public mist::thread< mode_thread< T1, T2, Functor > >
664  {
665  public:
667  typedef typename base::thread_exit_type thread_exit_type;
668  typedef typename T1::size_type size_type;
669  typedef typename T1::value_type value_type;
670  typedef typename T1::difference_type difference_type;
671  typedef std::vector< difference_type > list_type;
672 
673  private:
674  size_t thread_id_;
675  size_t thread_num_;
676 
677  // 入出力用の画像へのポインタ
678  const T1 *in_;
679  T2 *out_;
680  list_type *object_;
681  list_type *update_in_;
682  list_type *update_out_;
683 
684  Functor f_;
685 
686  public:
687  void setup_parameters( const T1 &in, T2 &out, list_type &object, list_type &update_in, list_type &update_out, size_type thread_id, size_type thread_num, Functor f )
688  {
689  in_ = &in;
690  out_ = &out;
691  object_ = &object;
692  update_in_ = &update_in;
693  update_out_ = &update_out;
694  thread_id_ = thread_id;
695  thread_num_ = thread_num;
696  f_ = f;
697  }
698 
699  const mode_thread& operator =( const mode_thread &p )
700  {
701  if( &p != this )
702  {
703  base::operator =( p );
704  thread_id_ = p.thread_id_;
705  thread_num_ = p.thread_num_;
706  in_ = p.in_;
707  out_ = p.out_;
708  object_ = p.object_;
709  update_in_ = p.update_in_;
710  update_out_ = p.update_out_;
711  f_ = p.f_;
712  }
713  return( *this );
714  }
715 
716  mode_thread( size_type id = 0, size_type num = 1 ) : thread_id_( id ), thread_num_( num ),
717  in_( NULL ), out_( NULL ), object_( NULL ), update_in_( NULL ), update_out_( NULL )
718  {
719  }
720  mode_thread( const mode_thread &p ) : base( p ), thread_id_( p.thread_id_ ), thread_num_( p.thread_num_ ),
721  in_( p.in_ ), out_( p.out_ ), object_( p.object_ ), update_in_( p.update_in_ ), update_out_( p.update_out_ )
722  {
723  }
724 
725  protected:
726  // 継承した先で必ず実装されるスレッド関数
727  virtual thread_exit_type thread_function( )
728  {
729  mode( *in_, *out_, *object_, *update_in_, *update_out_, thread_id_, thread_num_, f_ );
730  return( true );
731  }
732  };
733 }
734 
735 
738 
739 
753 template < class T, class Allocator, class Functor >
754 bool mode( array2< T, Allocator > &in, const mode_filter::mode_structure &s, Functor f, typename array2< T, Allocator >::size_type thread_num )
755 {
756  if( in.empty( ) )
757  {
758  return( false );
759  }
760 
761  typedef typename array2< T, Allocator >::value_type value_type;
762  typedef typename array2< T, Allocator >::size_type size_type;
763  typedef typename array2< T, Allocator >::difference_type difference_type;
764  typedef __mode_controller__::mode_thread< marray< array2< T, Allocator > >, array2< T, Allocator >, Functor > mode_thread;
765  typedef std::vector< difference_type > list_type;
766 
767  if( thread_num == 0 )
768  {
769  thread_num = static_cast< size_type >( get_cpu_num( ) );
770  }
771 
772  marray< array2< T, Allocator > > out( in, s.margin_x, s.margin_y, 0 );
773 
774  list_type object = mode_filter::create_pointer_diff_list( out, s.object );
775  list_type update_in = mode_filter::create_pointer_diff_list( out, s.update_in );
776  list_type update_out = mode_filter::create_pointer_diff_list( out, s.update_out );
777 
778  mode_thread *thread = new mode_thread[ thread_num ];
779 
780  for( size_type i = 0 ; i < thread_num ; i++ )
781  {
782  thread[ i ].setup_parameters( out, in, object, update_in, update_out, i, thread_num, f );
783  }
784 
785  f( 0.0 );
786 
787  // スレッドを実行して,終了まで待機する
788  do_threads_( thread, thread_num );
789 
790  f( 100.1 );
791 
792  delete [] thread;
793 
794  return( true );
795 }
796 
797 
810 template < class T, class Allocator >
812 {
813  return( mode( in, s, __mist_dmy_callback__( ), thread_num ) );
814 }
815 
816 
817 
831 template < class T, class Allocator, class Functor >
832 inline bool mode( array2< T, Allocator > &in, double radius, Functor f, typename array2< T, Allocator >::size_type thread_num )
833 {
834  return( mode( in, mode_filter::circle( radius, in.reso1( ), in.reso2( ) ), f, thread_num ) );
835 }
836 
837 
850 template < class T, class Allocator >
851 inline bool mode( array2< T, Allocator > &in, double radius, typename array2< T, Allocator >::size_type thread_num = 0 )
852 {
853  return( mode( in, mode_filter::circle( radius, in.reso1( ), in.reso2( ) ), __mist_dmy_callback__( ), thread_num ) );
854 }
855 
856 
857 
858 
859 
860 
861 
875 template < class T, class Allocator, class Functor >
876 bool mode( array3< T, Allocator > &in, const mode_filter::mode_structure &s, Functor f, typename array3< T, Allocator >::size_type thread_num )
877 {
878  if( in.empty( ) )
879  {
880  return( false );
881  }
882 
883  typedef typename array3< T, Allocator >::value_type value_type;
884  typedef typename array3< T, Allocator >::size_type size_type;
885  typedef typename array3< T, Allocator >::difference_type difference_type;
886  typedef __mode_controller__::mode_thread< marray< array3< T, Allocator > >, array3< T, Allocator >, Functor > mode_thread;
887  typedef std::vector< difference_type > list_type;
888 
889  if( thread_num == 0 )
890  {
891  thread_num = static_cast< size_type >( get_cpu_num( ) );
892  }
893 
895 
896  list_type object = mode_filter::create_pointer_diff_list( out, s.object );
897  list_type update_in = mode_filter::create_pointer_diff_list( out, s.update_in );
898  list_type update_out = mode_filter::create_pointer_diff_list( out, s.update_out );
899 
900  mode_thread *thread = new mode_thread[ thread_num ];
901 
902  for( size_type i = 0 ; i < thread_num ; i++ )
903  {
904  thread[ i ].setup_parameters( out, in, object, update_in, update_out, i, thread_num, f );
905  }
906 
907  f( 0.0 );
908 
909  // スレッドを実行して,終了まで待機する
910  do_threads_( thread, thread_num );
911 
912  f( 100.1 );
913 
914  delete [] thread;
915 
916  return( true );
917 }
918 
919 
932 template < class T, class Allocator >
934 {
935  return( mode( in, s, __mist_dmy_callback__( ), thread_num ) );
936 }
937 
938 
939 
940 
954 template < class T, class Allocator, class Functor >
955 inline bool mode( array3< T, Allocator > &in, double radius, Functor f, typename array3< T, Allocator >::size_type thread_num )
956 {
957  return( mode( in, mode_filter::sphere( radius, in.reso1( ), in.reso2( ), in.reso3( ) ), f, thread_num ) );
958 }
959 
960 
961 
962 
975 template < class T, class Allocator >
976 inline bool mode( array3< T, Allocator > &in, double radius, typename array3< T, Allocator >::size_type thread_num = 0 )
977 {
978  return( mode( in, mode_filter::sphere( radius, in.reso1( ), in.reso2( ), in.reso3( ) ), __mist_dmy_callback__( ), thread_num ) );
979 }
980 
981 
982 
984 // 最頻値フィルタグループの終わり
985 
986 
987 // mist名前空間の終わり
988 _MIST_END
989 
990 
991 #endif // __INCLUDE_MIST_MODE__
992 

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