morphology.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_MORPHOLOGY__
37 #define __INCLUDE_MIST_MORPHOLOGY__
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 morphology
76 {
78  struct point
79  {
80  typedef ptrdiff_t difference_type;
84  size_t life;
85 
93  point( difference_type xx, difference_type yy, difference_type zz, size_t l ) : x( xx ), y( yy ), z( zz ), life( l )
94  {
95  }
96  };
97 
98 
104  {
105  ptrdiff_t diff;
106  size_t life;
107 
109  pointer_diff( ptrdiff_t d, size_t l ) : diff( d ), life( l )
110  {
111  }
112  };
113 
114 
121  {
122  typedef std::vector< point > list_type;
125  size_t margin_x;
126  size_t margin_y;
127  size_t margin_z;
128  };
129 
130 
142  inline morphology_structure circle( double radius, double resoX, double resoY, bool radiusInPhysicalCoords = false )
143  {
144  typedef array2< bool >::size_type size_type;
145  typedef array2< bool >::difference_type difference_type;
146 
147  double ax, ay;
148  if( radiusInPhysicalCoords )
149  {
150  ax = resoX;
151  ay = resoY;
152  }
153  else
154  {
155  double max_reso = resoX > resoY ? resoX: resoY;
156 
157  ax = resoX / max_reso;
158  ay = resoY / max_reso;
159  }
160 
161  double xx, yy, rr = radius * radius;
162  difference_type rx = static_cast< size_type >( ceil( radius / ax ) );
163  difference_type ry = static_cast< size_type >( ceil( radius / ay ) );
164  difference_type x, y;
165 
166  size_type ox = rx + 1;
167  size_type oy = ry + 1;
168 
169  size_type w = 2 * ox + 1;
170  size_type h = 2 * oy + 1;
171 
173  array2< bool > m( w, h );
174 
175  // 円の構造要素を作成する
176  for( y = -ry ; y <= ry ; y++ )
177  {
178  yy = y * y * ay * ay;
179  for( x = -rx ; x <= rx ; x++ )
180  {
181  xx = x * x * ax * ax;
182  if( xx + yy <= rr )
183  {
184  m( x + ox, y + oy ) = true;
185  }
186  }
187  }
188 
189  // 円の構造要素の各点に生存期間を設定する
190  for( y = -ry ; y <= ry ; y++ )
191  {
192  size_t life = 0;
193  for( x = -rx ; x <= rx ; x++ )
194  {
195  if( m( x + ox, y + oy ) )
196  {
197  s.object.push_back( point( x, y, 0, ++life ) );
198  }
199  else
200  {
201  life = 0;
202  }
203  if( m( x + ox, y + oy ) && !m( x + ox + 1, y + oy ) )
204  {
205  s.update.push_back( point( x, y, 0, life ) );
206  }
207  }
208  }
209 
210  s.margin_x = rx;
211  s.margin_y = ry;
212  s.margin_z = 0;
213 
214  return( s );
215  }
216 
217 
218 
231  inline morphology_structure sphere( double radius, double resoX, double resoY, double resoZ, bool radiusInPhysicalCoords = false )
232  {
233  typedef array3< bool >::size_type size_type;
234  typedef array3< bool >::difference_type difference_type;
235 
236  double ax, ay, az;
237  if( radiusInPhysicalCoords )
238  {
239  ax = resoX;
240  ay = resoY;
241  az = resoZ;
242  }
243  else
244  {
245  double max_reso = resoX > resoY ? resoX: resoY;
246  max_reso = max_reso > resoZ ? max_reso : resoZ;
247 
248  ax = resoX / max_reso;
249  ay = resoY / max_reso;
250  az = resoZ / max_reso;
251  }
252 
253  double xx, yy, zz, rr = radius * radius;
254  difference_type rx = static_cast< size_type >( ceil( radius / ax ) );
255  difference_type ry = static_cast< size_type >( ceil( radius / ay ) );
256  difference_type rz = static_cast< size_type >( ceil( radius / az ) );
257  difference_type x, y, z;
258 
259  size_type ox = rx + 1;
260  size_type oy = ry + 1;
261  size_type oz = rz + 1;
262 
263  size_type w = 2 * ox + 1;
264  size_type h = 2 * oy + 1;
265  size_type d = 2 * oz + 1;
266 
268  array3< bool > m( w, h, d );
269 
270  // 球の構造要素を作成する
271  for( z = -rz ; z <= rz ; z++ )
272  {
273  zz = z * z * az * az;
274  for( y = -ry ; y <= ry ; y++ )
275  {
276  yy = y * y * ay * ay;
277  for( x = -rx ; x <= rx ; x++ )
278  {
279  xx = x * x * ax * ax;
280  if( xx + yy + zz <= rr )
281  {
282  m( x + ox, y + oy, z + oz ) = true;
283  }
284  }
285  }
286  }
287 
288  // 球の構造要素の各点に生存期間を設定する
289  for( z = -rz ; z <= rz ; z++ )
290  {
291  for( y = -ry ; y <= ry ; y++ )
292  {
293  size_t life = 0;
294  for( x = -rx ; x <= rx ; x++ )
295  {
296  if( m( x + ox, y + oy, z + oz ) )
297  {
298  s.object.push_back( point( x, y, z, ++life ) );
299  }
300  else
301  {
302  life = 0;
303  }
304  if( m( x + ox, y + oy, z + oz ) && !m( x + ox + 1, y + oy, z + oz ) )
305  {
306  s.update.push_back( point( x, y, z, life ) );
307  }
308  }
309  }
310  }
311 
312  s.margin_x = rx;
313  s.margin_y = ry;
314  s.margin_z = rz;
315 
316  return( s );
317  }
318 
319 
320 
332  inline morphology_structure square( double radius, double resoX, double resoY, bool radiusInPhysicalCoords = false )
333  {
334  using namespace std;
335  typedef array2< bool >::size_type size_type;
336  typedef array2< bool >::difference_type difference_type;
337 
338  double ax, ay;
339  if( radiusInPhysicalCoords )
340  {
341  ax = resoX;
342  ay = resoY;
343  }
344  else
345  {
346  double max_reso = resoX > resoY ? resoX: resoY;
347 
348  ax = resoX / max_reso;
349  ay = resoY / max_reso;
350  }
351 
352  double xx, yy;
353  difference_type rx = static_cast< size_type >( ceil( radius / ax ) );
354  difference_type ry = static_cast< size_type >( ceil( radius / ay ) );
355  difference_type x, y;
356 
357  size_type ox = rx + 1;
358  size_type oy = ry + 1;
359 
360  size_type w = 2 * ox + 1;
361  size_type h = 2 * oy + 1;
362 
364  array2< bool > m( w, h );
365 
366  // 正方形の構造要素を作成する
367  for( y = -ry ; y <= ry ; y++ )
368  {
369  yy = y * ay;
370  for( x = -rx ; x <= rx ; x++ )
371  {
372  xx = x * ax;
373  if( std::abs( xx ) <= radius && std::abs( yy ) <= radius )
374  {
375  m( x + ox, y + oy ) = true;
376  }
377  }
378  }
379 
380  // 正方形の構造要素の各点に生存期間を設定する
381  for( y = -ry ; y <= ry ; y++ )
382  {
383  size_t life = 0;
384  for( x = -rx ; x <= rx ; x++ )
385  {
386  if( m( x + ox, y + oy ) )
387  {
388  s.object.push_back( point( x, y, 0, ++life ) );
389  }
390  else
391  {
392  life = 0;
393  }
394  if( m( x + ox, y + oy ) && !m( x + ox + 1, y + oy ) )
395  {
396  s.update.push_back( point( x, y, 0, life ) );
397  }
398  }
399  }
400 
401  s.margin_x = rx;
402  s.margin_y = ry;
403  s.margin_z = 0;
404 
405  return( s );
406  }
407 
408 
421  inline morphology_structure cube( double radius, double resoX, double resoY, double resoZ, bool radiusInPhysicalCoords = false )
422  {
423  using namespace std;
424  typedef array3< bool >::size_type size_type;
425  typedef array3< bool >::difference_type difference_type;
426 
427  double ax, ay, az;
428  if( radiusInPhysicalCoords )
429  {
430  ax = resoX;
431  ay = resoY;
432  az = resoZ;
433  }
434  else
435  {
436  double max_reso = resoX > resoY ? resoX: resoY;
437  max_reso = max_reso > resoZ ? max_reso : resoZ;
438 
439  ax = resoX / max_reso;
440  ay = resoY / max_reso;
441  az = resoZ / max_reso;
442  }
443 
444  double xx, yy, zz;
445  difference_type rx = static_cast< size_type >( ceil( radius / ax ) );
446  difference_type ry = static_cast< size_type >( ceil( radius / ay ) );
447  difference_type rz = static_cast< size_type >( ceil( radius / az ) );
448  difference_type x, y, z;
449 
450  size_type ox = rx + 1;
451  size_type oy = ry + 1;
452  size_type oz = rz + 1;
453 
454  size_type w = 2 * ox + 1;
455  size_type h = 2 * oy + 1;
456  size_type d = 2 * oz + 1;
457 
459  array3< bool > m( w, h, d );
460 
461  // 立方体の構造要素を作成する
462  for( z = -rz ; z <= rz ; z++ )
463  {
464  zz = z * az;
465  for( y = -ry ; y <= ry ; y++ )
466  {
467  yy = y * ay;
468  for( x = -rx ; x <= rx ; x++ )
469  {
470  xx = x * ax;
471  if( std::abs( xx ) <= radius && std::abs( yy ) <= radius && std::abs( zz ) <= radius )
472  {
473  m( x + ox, y + oy, z + oz ) = true;
474  }
475  }
476  }
477  }
478 
479  // 立方体の構造要素の各点に生存期間を設定する
480  for( z = -rz ; z <= rz ; z++ )
481  {
482  for( y = -ry ; y <= ry ; y++ )
483  {
484  size_t life = 0;
485  for( x = -rx ; x <= rx ; x++ )
486  {
487  if( m( x + ox, y + oy, z + oz ) )
488  {
489  s.object.push_back( point( x, y, z, ++life ) );
490  }
491  else
492  {
493  life = 0;
494  }
495  if( m( x + ox, y + oy, z + oz ) && !m( x + ox + 1, y + oy, z + oz ) )
496  {
497  s.update.push_back( point( x, y, z, life ) );
498  }
499  }
500  }
501  }
502 
503  s.margin_x = rx;
504  s.margin_y = ry;
505  s.margin_z = rz;
506 
507  return( s );
508  }
509 
510 
511 
523  template < class Array >
524  inline morphology_structure create_morphology_structure( const Array &in, typename Array::size_type cx, typename Array::size_type cy = 0, typename Array::size_type cz = 0 )
525  {
526  using namespace std;
527  typedef typename Array::size_type size_type;
528  typedef typename Array::difference_type difference_type;
529  difference_type x, y, z;
530 
531  difference_type w = in.width( );
532  difference_type h = in.height( );
533  difference_type d = in.depth( );
534 
536  marray< Array > m( in, 1 );
537 
538  // 構造要素の形を作成する
539  for( z = 0 ; z < d ; z++ )
540  {
541  for( y = 0 ; y < h ; y++ )
542  {
543  for( x = 0 ; x < w ; x++ )
544  {
545  m( x, y, z ) = in( x, y, z ) == 0 ? false : true;
546  }
547  }
548  }
549 
550  // 構造要素の各点に生存期間を設定する
551  for( z = 0 ; z < d ; z++ )
552  {
553  for( y = 0 ; y < h ; y++ )
554  {
555  size_t life = 0;
556  for( x = 0 ; x < w ; x++ )
557  {
558  if( m( x, y, z ) )
559  {
560  s.object.push_back( point( x - cx, y - cy, z - cz, ++life ) );
561  }
562  else
563  {
564  life = 0;
565  }
566  if( m( x, y, z ) && !m( x + 1, y, z ) )
567  {
568  s.update.push_back( point( x - cx, y - cy, z - cz, life ) );
569  }
570  }
571  }
572  }
573 
574  s.margin_x = cx > w - cx - 1 ? cx : w - cx;
575  s.margin_y = cy > h - cy - 1 ? cy : h - cy;
576  s.margin_z = cz > d - cz - 1 ? cz : d - cz;
577 
578  return( s );
579  }
580 
581 
591  template < class Array >
592  inline std::vector< pointer_diff > create_pointer_diff_list( const Array &in, const std::vector< point > &list )
593  {
594  typedef typename Array::size_type size_type;
595  typedef typename Array::const_pointer const_pointer;
596  size_type cx = in.width( ) / 2;
597  size_type cy = in.height( ) / 2;
598  size_type cz = in.depth( ) / 2;
599  const_pointer p = &( in( cx, cy, cz ) );
600 
601  std::vector< pointer_diff > out;
602 
603  for( size_type i = 0 ; i < list.size( ) ; i++ )
604  {
605  const point &pt = list[ i ];
606  const_pointer pp = &( in( cx + pt.x, cy + pt.y, cz + pt.z ) );
607  out.push_back( pointer_diff( pp - p, pt.life ) );
608  }
609 
610  return( out );
611  }
612 }
613 
614 
616 // モルフォロジ演算グループの終わり
617 
618 
619 namespace __erosion__
620 {
621  template < class Array1, class Array2, class Functor >
622  void erosion( const Array1 &in, Array2 &out,
623  const std::vector< morphology::pointer_diff > &object, const std::vector< morphology::pointer_diff > &update,
624  typename Array1::size_type thread_idy, typename Array1::size_type thread_numy,
625  typename Array1::size_type thread_idz, typename Array1::size_type thread_numz, Functor f )
626  {
627  typedef typename Array1::size_type size_type;
628  typedef typename Array1::value_type value_type;
629  typedef typename Array1::const_pointer const_pointer;
630  typedef typename Array1::difference_type difference_type;
631  typedef typename Array2::value_type out_value_type;
632  typedef morphology::pointer_diff pointer_diff;
633  typedef std::vector< pointer_diff > list_type;
634 
635  list_type::const_iterator ite;
636 
637  size_type i, j, k;
638  value_type min;
639  size_type life;
640  const_pointer p;
641 
642  size_type w = in.width( );
643  size_type h = in.height( );
644  size_type d = in.depth( );
645 
646  const bool bprogress1 = thread_idy == 0 && d == 1;
647  const bool bprogress2 = thread_idz == 0 && d > 1;
648 
649  for( k = thread_idz ; k < d ; k += thread_numz )
650  {
651  for( j = thread_idy ; j < h ; j += thread_numy )
652  {
653  p = &( in( 0, j, k ) );
654  ite = object.begin( );
655  min = p[ ite->diff ];
656  life = ite->life;
657  ++ite;
658  for( ; ite != object.end( ) ; ++ite )
659  {
660  if( min > p[ ite->diff ] || ( min == p[ ite->diff ] && life < ite->life ) )
661  {
662  min = p[ ite->diff ];
663  life = ite->life;
664  }
665  }
666 
667  out( 0, j, k ) = static_cast< out_value_type >( min );
668  life--;
669 
670  for( i = 1 ; i < w ; i++ )
671  {
672  p = &( in( i, j, k ) );
673 
674  if( life == 0 )
675  {
676  // 前回までの最小値が構造要素から出てしまったので,新たに前探索を行う
677  ite = object.begin( );
678  min = p[ ite->diff ];
679  life = ite->life;
680  ++ite;
681  for( ; ite != object.end( ) ; ++ite )
682  {
683  if( min > p[ ite->diff ] || ( min == p[ ite->diff ] && life < ite->life ) )
684  {
685  min = p[ ite->diff ];
686  life = ite->life;
687  }
688  }
689  }
690  else
691  {
692  // 前回までの最小値が構造要素内に存在するので,更新分のみから探索を行う
693  for( ite = update.begin( ) ; ite != update.end( ) ; ++ite )
694  {
695  if( min > p[ ite->diff ] || ( min == p[ ite->diff ] && life < ite->life ) )
696  {
697  min = p[ ite->diff ];
698  life = ite->life;
699  }
700  }
701  }
702 
703  out( i, j, k ) = static_cast< out_value_type >( min );
704  life--;
705  }
706 
707  if( bprogress1 )
708  {
709  f( static_cast< double >( j + 1 ) / static_cast< double >( h ) * 100.0 );
710  }
711  }
712 
713  if( bprogress2 )
714  {
715  f( static_cast< double >( k + 1 ) / static_cast< double >( d ) * 100.0 );
716  }
717  }
718  }
719 }
720 
721 
722 namespace __dilation__
723 {
724  template < class Array1, class Array2, class Functor >
725  void dilation( const Array1 &in, Array2 &out,
726  const std::vector< morphology::pointer_diff > &object, const std::vector< morphology::pointer_diff > &update,
727  typename Array1::size_type thread_idy, typename Array1::size_type thread_numy,
728  typename Array1::size_type thread_idz, typename Array1::size_type thread_numz, Functor f )
729  {
730  typedef typename Array1::size_type size_type;
731  typedef typename Array1::value_type value_type;
732  typedef typename Array1::const_pointer const_pointer;
733  typedef typename Array1::difference_type difference_type;
734  typedef typename Array2::value_type out_value_type;
735  typedef morphology::pointer_diff pointer_diff;
736  typedef std::vector< pointer_diff > list_type;
737 
738  list_type::const_iterator ite;
739 
740  size_type i, j, k;
741  value_type max;
742  size_type life;
743  const_pointer p;
744 
745  size_type w = in.width( );
746  size_type h = in.height( );
747  size_type d = in.depth( );
748 
749  const bool bprogress1 = thread_idy == 0 && d == 1;
750  const bool bprogress2 = thread_idz == 0 && d > 1;
751 
752  for( k = thread_idz ; k < d ; k += thread_numz )
753  {
754  for( j = thread_idy ; j < h ; j += thread_numy )
755  {
756  p = &( in( 0, j, k ) );
757  ite = object.begin( );
758  max = p[ ite->diff ];
759  life = ite->life;
760  ++ite;
761  for( ; ite != object.end( ) ; ++ite )
762  {
763  if( max < p[ ite->diff ] || ( max == p[ ite->diff ] && life < ite->life ) )
764  {
765  max = p[ ite->diff ];
766  life = ite->life;
767  }
768  }
769 
770  out( 0, j, k ) = static_cast< out_value_type >( max );
771  life--;
772 
773  for( i = 1 ; i < w ; i++ )
774  {
775  p = &( in( i, j, k ) );
776 
777  if( life == 0 )
778  {
779  // 前回までの最小値が構造要素から出てしまったので,新たに前探索を行う
780  ite = object.begin( );
781  max = p[ ite->diff ];
782  life = ite->life;
783  ++ite;
784  for( ; ite != object.end( ) ; ++ite )
785  {
786  if( max < p[ ite->diff ] || ( max == p[ ite->diff ] && life < ite->life ) )
787  {
788  max = p[ ite->diff ];
789  life = ite->life;
790  }
791  }
792  }
793  else
794  {
795  // 前回までの最小値が構造要素内に存在するので,更新分のみから探索を行う
796  for( ite = update.begin( ) ; ite != update.end( ) ; ++ite )
797  {
798  if( max < p[ ite->diff ] || ( max == p[ ite->diff ] && life < ite->life ) )
799  {
800  max = p[ ite->diff ];
801  life = ite->life;
802  }
803  }
804  }
805 
806  out( i, j, k ) = static_cast< out_value_type >( max );
807  life--;
808  }
809 
810  if( bprogress1 )
811  {
812  f( static_cast< double >( j + 1 ) / static_cast< double >( h ) * 100.0 );
813  }
814  }
815 
816  if( bprogress2 )
817  {
818  f( static_cast< double >( k + 1 ) / static_cast< double >( d ) * 100.0 );
819  }
820  }
821  }
822 }
823 
824 
825 // モルフォロジ演算のスレッド実装
826 namespace __morphology_controller__
827 {
828  // Erosion 演算
829  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
830  void erosion( const marray< array< T1, Allocator1 > > &in, array< T2, Allocator2 > &out,
831  const std::vector< morphology::pointer_diff > &object, const std::vector< morphology::pointer_diff > &update,
832  typename array< T1, Allocator1 >::size_type thread_id, typename array< T1, Allocator1 >::size_type thread_num, Functor f )
833  {
834  __erosion__::erosion( in, out, object, update, 0, 1, thread_id, thread_num, f );
835  }
836 
837  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
838  void erosion( const marray< array1< T1, Allocator1 > > &in, array1< T2, Allocator2 > &out,
839  const std::vector< morphology::pointer_diff > &object, const std::vector< morphology::pointer_diff > &update,
840  typename array1< T1, Allocator1 >::size_type thread_id, typename array1< T1, Allocator1 >::size_type thread_num, Functor f )
841  {
842  __erosion__::erosion( in, out, object, update, 0, 1, thread_id, thread_num, f );
843  }
844 
845  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
846  void erosion( const marray< array2< T1, Allocator1 > > &in, array2< T2, Allocator2 > &out,
847  const std::vector< morphology::pointer_diff > &object, const std::vector< morphology::pointer_diff > &update,
848  typename array2< T1, Allocator1 >::size_type thread_id, typename array2< T1, Allocator1 >::size_type thread_num, Functor f )
849  {
850  __erosion__::erosion( in, out, object, update, thread_id, thread_num, 0, 1, f );
851  }
852 
853  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
854  void erosion( const marray< array3< T1, Allocator1 > > &in, array3< T2, Allocator2 > &out,
855  const std::vector< morphology::pointer_diff > &object, const std::vector< morphology::pointer_diff > &update,
856  typename array3< T1, Allocator1 >::size_type thread_id, typename array3< T1, Allocator1 >::size_type thread_num, Functor f )
857  {
858  __erosion__::erosion( in, out, object, update, 0, 1, thread_id, thread_num, f );
859  }
860 
861 
862  // Dilation 演算
863  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
864  void dilation( const marray< array< T1, Allocator1 > > &in, array< T2, Allocator2 > &out,
865  const std::vector< morphology::pointer_diff > &object, const std::vector< morphology::pointer_diff > &update,
866  typename array< T1, Allocator1 >::size_type thread_id, typename array< T1, Allocator1 >::size_type thread_num, Functor f )
867  {
868  __dilation__::dilation( in, out, object, update, 0, 1, thread_id, thread_num, f );
869  }
870 
871  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
872  void dilation( const marray< array1< T1, Allocator1 > > &in, array1< T2, Allocator2 > &out,
873  const std::vector< morphology::pointer_diff > &object, const std::vector< morphology::pointer_diff > &update,
874  typename array1< T1, Allocator1 >::size_type thread_id, typename array1< T1, Allocator1 >::size_type thread_num, Functor f )
875  {
876  __dilation__::dilation( in, out, object, update, 0, 1, thread_id, thread_num, f );
877  }
878 
879  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
880  void dilation( const marray< array2< T1, Allocator1 > > &in, array2< T2, Allocator2 > &out,
881  const std::vector< morphology::pointer_diff > &object, const std::vector< morphology::pointer_diff > &update,
882  typename array2< T1, Allocator1 >::size_type thread_id, typename array2< T1, Allocator1 >::size_type thread_num, Functor f )
883  {
884  __dilation__::dilation( in, out, object, update, thread_id, thread_num, 0, 1, f );
885  }
886 
887  template < class T1, class Allocator1, class T2, class Allocator2, class Functor >
888  void dilation( const marray< array3< T1, Allocator1 > > &in, array3< T2, Allocator2 > &out,
889  const std::vector< morphology::pointer_diff > &object, const std::vector< morphology::pointer_diff > &update,
890  typename array3< T1, Allocator1 >::size_type thread_id, typename array3< T1, Allocator1 >::size_type thread_num, Functor f )
891  {
892  __dilation__::dilation( in, out, object, update, 0, 1, thread_id, thread_num, f );
893  }
894 
895 
896  template < class T1, class T2, class Functor >
897  class morphology_thread : public mist::thread< morphology_thread< T1, T2, Functor > >
898  {
899  public:
901  typedef typename base::thread_exit_type thread_exit_type;
902  typedef typename T1::size_type size_type;
903  typedef typename T1::value_type value_type;
904  typedef morphology::pointer_diff pointer_diff;
905  typedef std::vector< pointer_diff > list_type;
906 
907  private:
908  size_t thread_id_;
909  size_t thread_num_;
910 
911  // 入出力用の画像へのポインタ
912  const T1 *in_;
913  T2 *out_;
914  list_type *object_;
915  list_type *update_;
916  bool is_erosion_;
917 
918  Functor f_;
919 
920  public:
921  void setup_parameters( const T1 &in, T2 &out, list_type &object, list_type &update, bool is_erosion, size_type thread_id, size_type thread_num, Functor f )
922  {
923  in_ = &in;
924  out_ = &out;
925  object_ = &object;
926  update_ = &update;
927  is_erosion_ = is_erosion;
928  thread_id_ = thread_id;
929  thread_num_ = thread_num;
930  f_ = f;
931  }
932 
933  const morphology_thread& operator =( const morphology_thread &p )
934  {
935  if( &p != this )
936  {
937  base::operator =( p );
938  thread_id_ = p.thread_id_;
939  thread_num_ = p.thread_num_;
940  in_ = p.in_;
941  out_ = p.out_;
942  is_erosion_ = p.is_erosion_;
943  object_ = p.object_;
944  update_ = p.update_;
945  f_ = p.f_;
946  }
947  return( *this );
948  }
949 
950  morphology_thread( size_type id = 0, size_type num = 1 ) : thread_id_( id ), thread_num_( num ),
951  in_( NULL ), out_( NULL ), object_( NULL ), update_( NULL ), is_erosion_( true )
952  {
953  }
954  morphology_thread( const morphology_thread &p ) : base( p ), thread_id_( p.thread_id_ ), thread_num_( p.thread_num_ ),
955  in_( p.in_ ), out_( p.out_ ), object_( p.object_ ), update_( p.update_ ), is_erosion_( p.is_erosion_ )
956  {
957  }
958 
959  protected:
960  // 継承した先で必ず実装されるスレッド関数
961  virtual thread_exit_type thread_function( )
962  {
963  if( is_erosion_ )
964  {
965  erosion( *in_, *out_, *object_, *update_, thread_id_, thread_num_, f_ );
966  }
967  else
968  {
969  dilation( *in_, *out_, *object_, *update_, thread_id_, thread_num_, f_ );
970  }
971  return( true );
972  }
973  };
974 }
975 
976 
979 
980 
994 template < class Array, class Functor >
995 bool erosion( Array &in, const morphology::morphology_structure &s, Functor f, typename Array::size_type thread_num )
996 {
997  if( in.empty( ) )
998  {
999  return( false );
1000  }
1001 
1002  typedef typename Array::value_type value_type;
1003  typedef typename Array::size_type size_type;
1004  typedef __morphology_controller__::morphology_thread< marray< Array >, Array, Functor > morphology_thread;
1005  typedef morphology::pointer_diff pointer_diff;
1006  typedef std::vector< pointer_diff > list_type;
1007 
1008  if( thread_num == 0 )
1009  {
1010  thread_num = static_cast< size_type >( get_cpu_num( ) );
1011  }
1012 
1013  value_type max = type_limits< value_type >::maximum( );
1014 
1015  marray< Array > out( in, s.margin_x, s.margin_y, s.margin_z, max );
1016 
1017  list_type object = morphology::create_pointer_diff_list( out, s.object );
1018  list_type update = morphology::create_pointer_diff_list( out, s.update );
1019 
1020  morphology_thread *thread = new morphology_thread[ thread_num ];
1021 
1022  size_type i;
1023  for( i = 0 ; i < thread_num ; i++ )
1024  {
1025  thread[ i ].setup_parameters( out, in, object, update, true, i, thread_num, f );
1026  }
1027 
1028  f( 0.0 );
1029 
1030  // スレッドを実行して,終了まで待機する
1031  do_threads_( thread, thread_num );
1032 
1033  f( 100.1 );
1034 
1035  delete [] thread;
1036 
1037  return( true );
1038 }
1039 
1040 
1053 template < class Array >
1054 bool erosion( Array &in, const morphology::morphology_structure &s, typename Array::size_type thread_num = 0 )
1055 {
1056  return( erosion( in, s, __mist_dmy_callback__( ), thread_num ) );
1057 }
1058 
1059 
1073 template < class Array, class Functor >
1074 bool dilation( Array &in, const morphology::morphology_structure &s, Functor f, typename Array::size_type thread_num )
1075 {
1076  if( in.empty( ) )
1077  {
1078  return( false );
1079  }
1080 
1081  typedef typename Array::value_type value_type;
1082  typedef typename Array::size_type size_type;
1083  typedef __morphology_controller__::morphology_thread< marray< Array >, Array, Functor > morphology_thread;
1084  typedef morphology::pointer_diff pointer_diff;
1085  typedef std::vector< pointer_diff > list_type;
1086 
1087  if( thread_num == 0 )
1088  {
1089  thread_num = static_cast< size_type >( get_cpu_num( ) );
1090  }
1091 
1092  value_type min = type_limits< value_type >::minimum( );
1093 
1094  marray< Array > out( in, s.margin_x, s.margin_y, s.margin_z, min );
1095 
1096  list_type object = morphology::create_pointer_diff_list( out, s.object );
1097  list_type update = morphology::create_pointer_diff_list( out, s.update );
1098 
1099  morphology_thread *thread = new morphology_thread[ thread_num ];
1100 
1101  size_type i;
1102  for( i = 0 ; i < thread_num ; i++ )
1103  {
1104  thread[ i ].setup_parameters( out, in, object, update, false, i, thread_num, f );
1105  }
1106 
1107  f( 0.0 );
1108 
1109  // スレッドを実行して,終了まで待機する
1110  do_threads_( thread, thread_num );
1111 
1112  f( 100.1 );
1113 
1114  delete [] thread;
1115 
1116  return( true );
1117 }
1118 
1119 
1132 template < class Array >
1133 bool dilation( Array &in, const morphology::morphology_structure &s, typename Array::size_type thread_num = 0 )
1134 {
1135  return( dilation( in, s, __mist_dmy_callback__( ), thread_num ) );
1136 }
1137 
1138 
1152 template < class Array, class Functor >
1153 bool opening( Array &in, const morphology::morphology_structure &s, Functor f, typename Array::size_type thread_num )
1154 {
1155  if( in.empty( ) )
1156  {
1157  return( false );
1158  }
1159 
1160  typedef typename Array::value_type value_type;
1161  typedef typename Array::size_type size_type;
1162  typedef __mist_convert_callback__< Functor > CallBack;
1163  typedef __morphology_controller__::morphology_thread< marray< Array >, Array, CallBack > morphology_thread;
1164  typedef morphology::pointer_diff pointer_diff;
1165  typedef std::vector< pointer_diff > list_type;
1166 
1167  if( thread_num == 0 )
1168  {
1169  thread_num = static_cast< size_type >( get_cpu_num( ) );
1170  }
1171 
1172  value_type max = type_limits< value_type >::maximum( );
1173  value_type min = type_limits< value_type >::minimum( );
1174 
1175  marray< Array > out( in, s.margin_x, s.margin_y, s.margin_z, max );
1176 
1177  list_type object = morphology::create_pointer_diff_list( out, s.object );
1178  list_type update = morphology::create_pointer_diff_list( out, s.update );
1179 
1180  morphology_thread *thread = new morphology_thread[ thread_num ];
1181 
1182  f( 0.0 );
1183 
1184  size_type i;
1185  {
1186  // Erosion 演算
1187  for( i = 0 ; i < thread_num ; i++ )
1188  {
1189  thread[ i ].setup_parameters( out, in, object, update, true, i, thread_num, CallBack( f, 0, 50 ) );
1190  }
1191 
1192  // スレッドを実行して,終了まで待機する
1193  do_threads_( thread, thread_num );
1194  }
1195 
1196  out = in;
1197  out.fill_margin( min );
1198 
1199  {
1200  // Dilation 演算
1201  for( i = 0 ; i < thread_num ; i++ )
1202  {
1203  thread[ i ].setup_parameters( out, in, object, update, false, i, thread_num, CallBack( f, 50, 100 ) );
1204  }
1205 
1206  // スレッドを実行して,終了まで待機する
1207  do_threads_( thread, thread_num );
1208  }
1209 
1210  f( 100.1 );
1211 
1212  delete [] thread;
1213 
1214  return( true );
1215 }
1216 
1217 
1230 template < class Array >
1231 bool opening( Array &in, const morphology::morphology_structure &s, typename Array::size_type thread_num = 0 )
1232 {
1233  return( opening( in, s, __mist_dmy_callback__( ), thread_num ) );
1234 }
1235 
1236 
1250 template < class Array, class Functor >
1251 bool closing( Array &in, const morphology::morphology_structure &s, Functor f, typename Array::size_type thread_num )
1252 {
1253  if( in.empty( ) )
1254  {
1255  return( false );
1256  }
1257 
1258  typedef typename Array::value_type value_type;
1259  typedef typename Array::size_type size_type;
1260  typedef __mist_convert_callback__< Functor > CallBack;
1261  typedef __morphology_controller__::morphology_thread< marray< Array >, Array, CallBack > morphology_thread;
1262  typedef morphology::pointer_diff pointer_diff;
1263  typedef std::vector< pointer_diff > list_type;
1264 
1265  if( thread_num == 0 )
1266  {
1267  thread_num = static_cast< size_type >( get_cpu_num( ) );
1268  }
1269 
1270  value_type max = type_limits< value_type >::maximum( );
1271  value_type min = type_limits< value_type >::minimum( );
1272 
1273  marray< Array > out( in, s.margin_x, s.margin_y, s.margin_z, min );
1274 
1275  list_type object = morphology::create_pointer_diff_list( out, s.object );
1276  list_type update = morphology::create_pointer_diff_list( out, s.update );
1277 
1278  morphology_thread *thread = new morphology_thread[ thread_num ];
1279 
1280  f( 0.0 );
1281 
1282  size_type i;
1283  {
1284  // Dilation 演算
1285  for( i = 0 ; i < thread_num ; i++ )
1286  {
1287  thread[ i ].setup_parameters( out, in, object, update, false, i, thread_num, CallBack( f, 0, 50 ) );
1288  }
1289 
1290  // スレッドを実行して,終了まで待機する
1291  do_threads_( thread, thread_num );
1292  }
1293 
1294  out = in;
1295  out.fill_margin( max );
1296 
1297  {
1298  // Erosion 演算
1299  for( i = 0 ; i < thread_num ; i++ )
1300  {
1301  thread[ i ].setup_parameters( out, in, object, update, true, i, thread_num, CallBack( f, 50, 100 ) );
1302  }
1303 
1304  // スレッドを実行して,終了まで待機する
1305  do_threads_( thread, thread_num );
1306  }
1307 
1308  f( 100.1 );
1309 
1310  delete [] thread;
1311 
1312  return( true );
1313 }
1314 
1315 
1328 template < class Array >
1329 bool closing( Array &in, const morphology::morphology_structure &s, typename Array::size_type thread_num = 0 )
1330 {
1331  return( closing( in, s, __mist_dmy_callback__( ), thread_num ) );
1332 }
1333 
1334 
1335 
1349 template < class Array, class Functor >
1350 inline bool erosion( Array &in, double radius, Functor f, typename Array::size_type thread_num )
1351 {
1352  if( in.depth( ) == 1 )
1353  {
1354  return( erosion( in, morphology::circle( radius, in.reso1( ), in.reso2( ) ), f, thread_num ) );
1355  }
1356  else
1357  {
1358  return( erosion( in, morphology::sphere( radius, in.reso1( ), in.reso2( ), in.reso3( ) ), f, thread_num ) );
1359  }
1360 }
1361 
1362 
1376 template < class Array, class Functor >
1377 inline bool dilation( Array &in, double radius, Functor f, typename Array::size_type thread_num )
1378 {
1379  if( in.depth( ) == 1 )
1380  {
1381  return( dilation( in, morphology::circle( radius, in.reso1( ), in.reso2( ) ), f, thread_num ) );
1382  }
1383  else
1384  {
1385  return( dilation( in, morphology::sphere( radius, in.reso1( ), in.reso2( ), in.reso3( ) ), f, thread_num ) );
1386  }
1387 }
1388 
1389 
1403 template < class Array, class Functor >
1404 inline bool opening( Array &in, double radius, Functor f, typename Array::size_type thread_num )
1405 {
1406  if( in.depth( ) == 1 )
1407  {
1408  return( opening( in, morphology::circle( radius, in.reso1( ), in.reso2( ) ), f, thread_num ) );
1409  }
1410  else
1411  {
1412  return( opening( in, morphology::sphere( radius, in.reso1( ), in.reso2( ), in.reso3( ) ), f, thread_num ) );
1413  }
1414 }
1415 
1416 
1430 template < class Array, class Functor >
1431 inline bool closing( Array &in, double radius, Functor f, typename Array::size_type thread_num )
1432 {
1433  if( in.depth( ) == 1 )
1434  {
1435  return( closing( in, morphology::circle( radius, in.reso1( ), in.reso2( ) ), f, thread_num ) );
1436  }
1437  else
1438  {
1439  return( closing( in, morphology::sphere( radius, in.reso1( ), in.reso2( ), in.reso3( ) ), f, thread_num ) );
1440  }
1441 }
1442 
1443 
1444 
1457 template < class Array >
1458 inline bool erosion( Array &in, double radius, typename Array::size_type thread_num = 0 )
1459 {
1460  return( erosion( in, radius, __mist_dmy_callback__( ), thread_num ) );
1461 }
1462 
1463 
1476 template < class Array >
1477 inline bool dilation( Array &in, double radius, typename Array::size_type thread_num = 0 )
1478 {
1479  return( dilation( in, radius, __mist_dmy_callback__( ), thread_num ) );
1480 }
1481 
1482 
1495 template < class Array >
1496 inline bool opening( Array &in, double radius, typename Array::size_type thread_num = 0 )
1497 {
1498  return( opening( in, radius, __mist_dmy_callback__( ), thread_num ) );
1499 }
1500 
1501 
1514 template < class Array >
1515 inline bool closing( Array &in, double radius, typename Array::size_type thread_num = 0 )
1516 {
1517  return( closing( in, radius, __mist_dmy_callback__( ), thread_num ) );
1518 }
1519 
1520 
1522 // モルフォロジ演算グループの終わり
1523 
1524 
1525 // mist名前空間の終わり
1526 _MIST_END
1527 
1528 
1529 #endif // __INCLUDE_MIST_MORPHOLOGY__
1530 

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