34 #ifndef __INCLUDE_MIST_REGIONGROWING__
35 #define __INCLUDE_MIST_REGIONGROWING__
38 #ifndef __INCLUDE_MIST_H__
42 #ifndef __INCLUDE_MIST_LIMITS__
43 #include "../limits.h"
46 #ifndef __INCLUDE_MIST_VECTOR__
47 #include "../vector.h"
88 namespace region_growing_utility
182 return( i * i * resoX_ * resoX_ + j * j * resoY_ * resoY_ <= radius_ * radius_ );
190 circle(
double radius,
double resoX = 1.0,
double resoY = 1.0,
bool radiusInPhysicalCoords =
false ) : radius_( radius )
192 if( radiusInPhysicalCoords )
199 double max_reso = resoX > resoY ? resoX: resoY;
201 resoX_ = resoX / max_reso;
202 resoY_ = resoY / max_reso;
204 width_ =
static_cast< size_type >( std::ceil( radius_ / resoX_ ) ) * 2 + 1;
205 height_ =
static_cast< size_type >( std::ceil( radius_ / resoY_ ) ) * 2 + 1;
234 return( i * i * resoX_ * resoX_ + j * j * resoY_ * resoY_+ k * k * resoZ_ * resoZ_ <= radius_ * radius_ );
241 sphere(
double radius,
double resoX = 1.0,
double resoY = 1.0,
double resoZ = 1.0,
bool radiusInPhysicalCoords =
false ) : radius_( radius )
243 if (radiusInPhysicalCoords)
251 double max_reso = resoX > resoY ? resoX: resoY;
252 max_reso = max_reso > resoZ ? max_reso : resoZ;
254 resoX_ = resoX / max_reso;
255 resoY_ = resoY / max_reso;
256 resoZ_ = resoZ / max_reso;
258 width_ =
static_cast< size_type >( std::ceil( radius_ / resoX_ ) ) * 2 + 1;
259 height_ =
static_cast< size_type >( std::ceil( radius_ / resoY_ ) ) * 2 + 1;
260 depth_ =
static_cast< size_type >( std::ceil( radius_ / resoZ_ ) ) * 2 + 1;
273 typedef size_t size_type;
274 typedef ptrdiff_t difference_type;
275 typedef T value_type;
282 template <
class VerifyList >
283 bool operator()(
const VerifyList &elements, size_type num )
const
285 typedef typename VerifyList::value_type verify_value_type;
287 for( size_type i = 0 ; i < num ; i++ )
289 const verify_value_type &v = elements[ i ];
315 typedef size_t size_type;
316 typedef ptrdiff_t difference_type;
317 typedef T value_type;
324 template <
class VerifyList >
325 bool operator()(
const VerifyList &elements, size_type num )
const
327 typedef typename VerifyList::value_type verify_value_type;
329 for( size_type i = 0 ; i < num ; i++ )
331 const verify_value_type &v = elements[ i ];
357 typedef size_t size_type;
358 typedef ptrdiff_t difference_type;
359 typedef T value_type;
366 template <
class VerifyList >
367 bool operator()(
const VerifyList &elements, size_type num )
const
369 typedef typename VerifyList::value_type verify_value_type;
371 for( size_type i = 0 ; i < num ; i++ )
373 const verify_value_type &v = elements[ i ];
374 if( v < th_ || th_ < v )
399 typedef size_t size_type;
400 typedef ptrdiff_t difference_type;
401 typedef T value_type;
409 template <
class VerifyList >
410 bool operator()(
const VerifyList &elements, size_type num )
const
412 typedef typename VerifyList::value_type verify_value_type;
414 for( size_type i = 0 ; i < num ; i++ )
416 const verify_value_type &v = elements[ i ];
417 if( v < min_ || max_ < v )
430 range( value_type min, value_type max ) : min_( min ), max_( max ){ }
436 namespace __region_growing_utility__
440 typedef ptrdiff_t difference_type;
445 pointer_diff2( ptrdiff_t d1 = 0, ptrdiff_t d2 = 0 ) : diff1( d1 ), diff2( d2 ){ }
448 typedef vector3< ptrdiff_t > point_type;
449 typedef std::vector< point_type > point_list_type;
450 typedef std::vector< pointer_diff2 > ptrdiff_list_type;
455 typedef size_t size_type;
456 typedef ptrdiff_t difference_type;
458 bool empty( )
const {
return(
true ); }
459 bool operator ()( difference_type , difference_type , difference_type )
const {
return(
false ); }
463 template <
class Array1,
class Array2,
class Component >
464 ptrdiff_list_type create_component_list(
const Array1 &in1,
const Array2 &in2,
const Component &components )
466 typedef typename Array1::const_pointer const_pointer1;
467 typedef typename Array2::const_pointer const_pointer2;
468 typedef typename ptrdiff_list_type::size_type size_type;
469 typedef typename ptrdiff_list_type::difference_type difference_type;
470 typedef typename ptrdiff_list_type::value_type value_type;
472 ptrdiff_list_type list;
474 difference_type w = components.width( );
475 difference_type h = components.height( );
476 difference_type d = components.depth( );
477 difference_type cx = w / 2;
478 difference_type cy = h / 2;
479 difference_type cz = d / 2;
480 difference_type ox1 = in1.width( ) / 2;
481 difference_type oy1 = in1.height( ) / 2;
482 difference_type oz1 = in1.depth( ) / 2;
483 difference_type ox2 = in2.width( ) / 2;
484 difference_type oy2 = in2.height( ) / 2;
485 difference_type oz2 = in2.depth( ) / 2;
487 const_pointer1 p1 = &in1( ox1, oy1, oz1 );
488 const_pointer2 p2 = &in2( ox2, oy2, oz2 );
490 for( difference_type k = 0 ; k < d ; k++ )
492 for( difference_type j = 0 ; j < h ; j++ )
494 for( difference_type i = 0 ; i < w ; i++ )
496 if( components( i - cx, j - cy, k - cz ) )
498 ptrdiff_t d1 = &in1( ox1 + i - cx, oy1 + j - cy, oz1 + k - cz ) - p1;
499 ptrdiff_t d2 = &in2( ox2 + i - cx, oy2 + j - cy, oz2 + k - cz ) - p2;
500 list.push_back( pointer_diff2( d1, d2 ) );
510 template <
class Array1,
class Array2,
class Component >
511 ptrdiff_list_type create_update_list(
const Array1 &in1,
const Array2 &in2,
const Component &components )
513 typedef typename Array1::const_pointer const_pointer1;
514 typedef typename Array2::const_pointer const_pointer2;
515 typedef typename ptrdiff_list_type::size_type size_type;
516 typedef typename ptrdiff_list_type::difference_type difference_type;
517 typedef typename ptrdiff_list_type::value_type value_type;
519 ptrdiff_list_type list;
521 difference_type ox1 = in1.width( ) / 2;
522 difference_type oy1 = in1.height( ) / 2;
523 difference_type oz1 = in1.depth( ) / 2;
524 difference_type ox2 = in2.width( ) / 2;
525 difference_type oy2 = in2.height( ) / 2;
526 difference_type oz2 = in2.depth( ) / 2;
528 const_pointer1 p1 = &in1( ox1, oy1, oz1 );
529 const_pointer2 p2 = &in2( ox2, oy2, oz2 );
531 switch( components.expand_mode( ) )
534 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1, oz1 ) - p1, &in2( ox2 - 1, oy2, oz2 ) - p2 ) );
535 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1, oz1 ) - p1, &in2( ox2 + 1, oy2, oz2 ) - p2 ) );
536 list.push_back( pointer_diff2( &in1( ox1, oy1 - 1, oz1 ) - p1, &in2( ox2, oy2 - 1, oz2 ) - p2 ) );
537 list.push_back( pointer_diff2( &in1( ox1, oy1 + 1, oz1 ) - p1, &in2( ox2, oy2 + 1, oz2 ) - p2 ) );
541 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 - 1, oz1 ) - p1, &in2( ox2 - 1, oy2 - 1, oz2 ) - p2 ) );
542 list.push_back( pointer_diff2( &in1( ox1 , oy1 - 1, oz1 ) - p1, &in2( ox2 , oy2 - 1, oz2 ) - p2 ) );
543 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 - 1, oz1 ) - p1, &in2( ox2 + 1, oy2 - 1, oz2 ) - p2 ) );
544 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 , oz1 ) - p1, &in2( ox2 - 1, oy2 , oz2 ) - p2 ) );
545 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 , oz1 ) - p1, &in2( ox2 + 1, oy2 , oz2 ) - p2 ) );
546 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 + 1, oz1 ) - p1, &in2( ox2 - 1, oy2 + 1, oz2 ) - p2 ) );
547 list.push_back( pointer_diff2( &in1( ox1 , oy1 + 1, oz1 ) - p1, &in2( ox2 , oy2 + 1, oz2 ) - p2 ) );
548 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 + 1, oz1 ) - p1, &in2( ox2 + 1, oy2 + 1, oz2 ) - p2 ) );
552 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1, oz1 ) - p1, &in2( ox2 - 1, oy2, oz2 ) - p2 ) );
553 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1, oz1 ) - p1, &in2( ox2 + 1, oy2, oz2 ) - p2 ) );
554 list.push_back( pointer_diff2( &in1( ox1, oy1 - 1, oz1 ) - p1, &in2( ox2, oy2 - 1, oz2 ) - p2 ) );
555 list.push_back( pointer_diff2( &in1( ox1, oy1 + 1, oz1 ) - p1, &in2( ox2, oy2 + 1, oz2 ) - p2 ) );
556 list.push_back( pointer_diff2( &in1( ox1, oy1, oz1 - 1 ) - p1, &in2( ox2, oy2, oz2 - 1 ) - p2 ) );
557 list.push_back( pointer_diff2( &in1( ox1, oy1, oz1 + 1 ) - p1, &in2( ox2, oy2, oz2 + 1 ) - p2 ) );
561 list.push_back( pointer_diff2( &in1( ox1 , oy1 - 1, oz1 - 1 ) - p1, &in2( ox2 , oy2 - 1, oz2 - 1 ) - p2 ) );
562 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 , oz1 - 1 ) - p1, &in2( ox2 - 1, oy2 , oz2 - 1 ) - p2 ) );
563 list.push_back( pointer_diff2( &in1( ox1 , oy1 , oz1 - 1 ) - p1, &in2( ox2 , oy2 , oz2 - 1 ) - p2 ) );
564 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 , oz1 - 1 ) - p1, &in2( ox2 + 1, oy2 , oz2 - 1 ) - p2 ) );
565 list.push_back( pointer_diff2( &in1( ox1 , oy1 + 1, oz1 - 1 ) - p1, &in2( ox2 , oy2 + 1, oz2 - 1 ) - p2 ) );
566 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 - 1, oz1 ) - p1, &in2( ox2 - 1, oy2 - 1, oz2 ) - p2 ) );
567 list.push_back( pointer_diff2( &in1( ox1 , oy1 - 1, oz1 ) - p1, &in2( ox2 , oy2 - 1, oz2 ) - p2 ) );
568 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 - 1, oz1 ) - p1, &in2( ox2 + 1, oy2 - 1, oz2 ) - p2 ) );
569 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 , oz1 ) - p1, &in2( ox2 - 1, oy2 , oz2 ) - p2 ) );
570 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 , oz1 ) - p1, &in2( ox2 + 1, oy2 , oz2 ) - p2 ) );
571 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 + 1, oz1 ) - p1, &in2( ox2 - 1, oy2 + 1, oz2 ) - p2 ) );
572 list.push_back( pointer_diff2( &in1( ox1 , oy1 + 1, oz1 ) - p1, &in2( ox2 , oy2 + 1, oz2 ) - p2 ) );
573 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 + 1, oz1 ) - p1, &in2( ox2 + 1, oy2 + 1, oz2 ) - p2 ) );
574 list.push_back( pointer_diff2( &in1( ox1 , oy1 - 1, oz1 + 1 ) - p1, &in2( ox2 , oy2 - 1, oz2 + 1 ) - p2 ) );
575 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 , oz1 + 1 ) - p1, &in2( ox2 - 1, oy2 , oz2 + 1 ) - p2 ) );
576 list.push_back( pointer_diff2( &in1( ox1 , oy1 , oz1 + 1 ) - p1, &in2( ox2 , oy2 , oz2 + 1 ) - p2 ) );
577 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 , oz1 + 1 ) - p1, &in2( ox2 + 1, oy2 , oz2 + 1 ) - p2 ) );
578 list.push_back( pointer_diff2( &in1( ox1 , oy1 + 1, oz1 + 1 ) - p1, &in2( ox2 , oy2 + 1, oz2 + 1 ) - p2 ) );
582 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 - 1, oz1 - 1 ) - p1, &in2( ox2 - 1, oy2 - 1, oz2 - 1 ) - p2 ) );
583 list.push_back( pointer_diff2( &in1( ox1 , oy1 - 1, oz1 - 1 ) - p1, &in2( ox2 , oy2 - 1, oz2 - 1 ) - p2 ) );
584 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 - 1, oz1 - 1 ) - p1, &in2( ox2 + 1, oy2 - 1, oz2 - 1 ) - p2 ) );
585 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 , oz1 - 1 ) - p1, &in2( ox2 - 1, oy2 , oz2 - 1 ) - p2 ) );
586 list.push_back( pointer_diff2( &in1( ox1 , oy1 , oz1 - 1 ) - p1, &in2( ox2 , oy2 , oz2 - 1 ) - p2 ) );
587 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 , oz1 - 1 ) - p1, &in2( ox2 + 1, oy2 , oz2 - 1 ) - p2 ) );
588 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 + 1, oz1 - 1 ) - p1, &in2( ox2 - 1, oy2 + 1, oz2 - 1 ) - p2 ) );
589 list.push_back( pointer_diff2( &in1( ox1 , oy1 + 1, oz1 - 1 ) - p1, &in2( ox2 , oy2 + 1, oz2 - 1 ) - p2 ) );
590 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 + 1, oz1 - 1 ) - p1, &in2( ox2 + 1, oy2 + 1, oz2 - 1 ) - p2 ) );
591 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 - 1, oz1 ) - p1, &in2( ox2 - 1, oy2 - 1, oz2 ) - p2 ) );
592 list.push_back( pointer_diff2( &in1( ox1 , oy1 - 1, oz1 ) - p1, &in2( ox2 , oy2 - 1, oz2 ) - p2 ) );
593 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 - 1, oz1 ) - p1, &in2( ox2 + 1, oy2 - 1, oz2 ) - p2 ) );
594 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 , oz1 ) - p1, &in2( ox2 - 1, oy2 , oz2 ) - p2 ) );
595 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 , oz1 ) - p1, &in2( ox2 + 1, oy2 , oz2 ) - p2 ) );
596 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 + 1, oz1 ) - p1, &in2( ox2 - 1, oy2 + 1, oz2 ) - p2 ) );
597 list.push_back( pointer_diff2( &in1( ox1 , oy1 + 1, oz1 ) - p1, &in2( ox2 , oy2 + 1, oz2 ) - p2 ) );
598 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 + 1, oz1 ) - p1, &in2( ox2 + 1, oy2 + 1, oz2 ) - p2 ) );
599 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 - 1, oz1 + 1 ) - p1, &in2( ox2 - 1, oy2 - 1, oz2 + 1 ) - p2 ) );
600 list.push_back( pointer_diff2( &in1( ox1 , oy1 - 1, oz1 + 1 ) - p1, &in2( ox2 , oy2 - 1, oz2 + 1 ) - p2 ) );
601 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 - 1, oz1 + 1 ) - p1, &in2( ox2 + 1, oy2 - 1, oz2 + 1 ) - p2 ) );
602 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 , oz1 + 1 ) - p1, &in2( ox2 - 1, oy2 , oz2 + 1 ) - p2 ) );
603 list.push_back( pointer_diff2( &in1( ox1 , oy1 , oz1 + 1 ) - p1, &in2( ox2 , oy2 , oz2 + 1 ) - p2 ) );
604 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 , oz1 + 1 ) - p1, &in2( ox2 + 1, oy2 , oz2 + 1 ) - p2 ) );
605 list.push_back( pointer_diff2( &in1( ox1 - 1, oy1 + 1, oz1 + 1 ) - p1, &in2( ox2 - 1, oy2 + 1, oz2 + 1 ) - p2 ) );
606 list.push_back( pointer_diff2( &in1( ox1 , oy1 + 1, oz1 + 1 ) - p1, &in2( ox2 , oy2 + 1, oz2 + 1 ) - p2 ) );
607 list.push_back( pointer_diff2( &in1( ox1 + 1, oy1 + 1, oz1 + 1 ) - p1, &in2( ox2 + 1, oy2 + 1, oz2 + 1 ) - p2 ) );
612 list = create_component_list( in1, in2, components );
620 template <
class T,
class Allocator,
class Array,
class Po
intType >
621 bool check_component_list(
const array2< T, Allocator > &in1,
const Array &in2,
const PointType &pt, pointer_diff2 &ptr )
623 typedef typename array2< T, Allocator >::const_pointer const_pointer1;
624 typedef typename Array::const_pointer const_pointer2;
625 typedef typename ptrdiff_list_type::difference_type difference_type;
627 difference_type x =
static_cast< difference_type
>( pt.x );
628 difference_type y =
static_cast< difference_type
>( pt.y );
629 difference_type w = in1.width( );
630 difference_type h = in1.height( );
632 if( x < 0 || x >= w || y < 0 || y >= h )
636 else if( in2( x, y ) != 0 )
642 ptr.diff1 = &in1( x, y) - &in1[ 0 ];
643 ptr.diff2 = &in2( x, y ) - &in2[ 0 ];
649 template <
class T,
class Allocator,
class Array,
class Po
intType >
650 bool check_component_list(
const array3< T, Allocator > &in1,
const Array &in2,
const PointType &pt, pointer_diff2 &ptr )
652 typedef typename array3< T, Allocator >::const_pointer const_pointer1;
653 typedef typename Array::const_pointer const_pointer2;
654 typedef typename ptrdiff_list_type::difference_type difference_type;
656 difference_type x =
static_cast< difference_type
>( pt.x );
657 difference_type y =
static_cast< difference_type
>( pt.y );
658 difference_type z =
static_cast< difference_type
>( pt.z );
659 difference_type w = in1.width( );
660 difference_type h = in1.height( );
661 difference_type d = in1.depth( );
663 if( x < 0 || x >= w || y < 0 || y >= h || z < 0 || z >= d )
667 else if( in2( x, y, z ) != 0 )
673 ptr.diff1 = &in1( x, y, z ) - &in1[ 0 ];
674 ptr.diff2 = &in2( x, y, z ) - &in2[ 0 ];
680 template <
class Po
intType >
681 struct point_list_converter
683 typedef std::vector< PointType > point_list_type;
685 static point_list_type create_point_list(
const PointType &pt )
687 point_list_type list( 1 );
694 template <
class Po
intType >
695 struct point_list_converter< std::vector< PointType > >
697 typedef std::vector< PointType > point_list_type;
699 static point_list_type create_point_list(
const point_list_type &list )
705 template <
class Po
intType >
706 struct point_list_converter< std::deque< PointType > >
708 typedef std::deque< PointType > point_list_type;
710 static point_list_type create_point_list(
const point_list_type &list )
718 inline const T maximum(
const T &v0,
const typename type_trait< T >::value_type &v1 )
720 return( v0 > v1 ? v0 : v1 );
724 inline const T maximum(
const T &v0,
const typename type_trait< T >::value_type &v1,
const typename type_trait< T >::value_type &v2 )
726 return( v0 > v1 ? ( v0 > v2 ? v0 : v2 ) : ( v1 > v2 ? v1 : v2 ) );
730 inline const T maximum(
const T &v0,
const typename type_trait< T >::value_type &v1,
const typename type_trait< T >::value_type &v2,
const typename type_trait< T >::value_type &v3 )
732 return( maximum( maximum( v0, v1 ), maximum( v2, v3 ) ) );
752 template <
class Array1,
class Array2,
class MaskType,
class Po
intList,
class Component,
class Condition >
753 typename Array1::difference_type
region_growing(
const Array1 &in, Array2 &out,
const MaskType &mask,
const PointList &start_points,
typename Array2::value_type output_value,
754 const Component &components,
const Condition &condition,
typename Array1::size_type max_paint )
761 typedef typename Array1::template rebind< unsigned char >::other mask_type;
762 typedef __region_growing_utility__::pointer_diff2 pointer_diff_type;
764 typedef typename Array1::size_type size_type;
765 typedef typename Array1::value_type value_type;
766 typedef typename Array1::difference_type difference_type;
767 typedef typename Array2::value_type out_value_type;
769 typedef typename Array1::const_pointer const_pointer;
770 typedef typename mask_type::pointer work_pointer;
771 typedef typename Array2::pointer output_pointer;
773 size_type rx = components.width( ) / 2;
774 size_type ry = components.height( ) / 2;
775 size_type rz = components.depth( ) / 2;
781 __region_growing_utility__::ptrdiff_list_type clist = __region_growing_utility__::create_component_list( in, work, components );
782 __region_growing_utility__::ptrdiff_list_type ulist = __region_growing_utility__::create_update_list( in, work, components );
784 std::deque< pointer_diff_type > que;
785 std::vector< value_type > element( clist.size( ) );
786 __region_growing_utility__::ptrdiff_list_type elist( clist.size( ) );
795 for( size_type k = 0 ; k < in.depth( ) ; k++ )
797 for( size_type j = 0 ; j < in.height( ) ; j++ )
799 for( size_type i = 0 ; i < in.width( ) ; i++ )
801 if( mask( i, j, k ) )
803 work( i, j, k ) = 255;
810 typedef __region_growing_utility__::point_list_converter< PointList > start_point_list_converter;
811 typedef typename start_point_list_converter::point_list_type start_point_list_type;
812 start_point_list_type sps = start_point_list_converter::create_point_list( start_points );
815 for(
typename start_point_list_type::const_iterator ite = sps.begin( ) ; ite != sps.end( ) ; ++ite )
817 __region_growing_utility__::pointer_diff2 ptr;
818 if( __region_growing_utility__::check_component_list( in, work, *ite, ptr ) )
820 que.push_back( ptr );
825 if( in.size( ) != out.size( ) )
827 out.resize( in.width( ), in.height( ), in.depth( ) );
828 out.reso1( in.reso1( ) );
829 out.reso2( in.reso2( ) );
830 out.reso3( in.reso3( ) );
834 size_type num_painted = 0;
839 if( condition.require_all_elements( ) )
842 while( !que.empty( ) )
844 if( num_painted >= max_paint )
846 return( num_painted );
850 pointer_diff_type cur = que.front( );
853 const_pointer pi = &in[ 0 ] + cur.diff1;
854 work_pointer pw = &work[ 0 ] + cur.diff2;
855 output_pointer po = &out[ 0 ] + cur.diff1;
863 for( size_type i = 0 ; i < clist.size( ) ; i++ )
865 const pointer_diff_type &d = clist[ i ];
866 if( ( pw[ d.diff2 ] & 0x0f ) == 0 )
868 element[ num ] = pi[ d.diff1 ];
875 if( num != 0 && condition( element, num ) )
878 for( size_type i = 0 ; i < num ; i++ )
880 const pointer_diff_type &d = elist[ i ];
881 num_painted += po[ d.diff1 ] != output_value ? 1 : 0;
882 po[ d.diff1 ] = output_value;
886 for( size_type i = 0 ; i < ulist.size( ) ; i++ )
888 const pointer_diff_type &d = ulist[ i ];
889 if( ( pw[ d.diff2 ] & 0xf0 ) == 0 )
891 pw[ d.diff2 ] |= 0xf0;
892 que.push_back( pointer_diff_type( cur.diff1 + d.diff1, cur.diff2 + d.diff2 ) );
901 while( !que.empty( ) )
903 if( num_painted >= max_paint )
905 return( num_painted );
909 pointer_diff_type cur = que.front( );
912 const_pointer pi = &in[ 0 ] + cur.diff1;
913 work_pointer pw = &work[ 0 ] + cur.diff2;
914 output_pointer po = &out[ 0 ] + cur.diff1;
924 for( size_type i = 0 ; i < clist.size( ) ; i++ )
926 const pointer_diff_type &d = clist[ i ];
927 if( ( pw[ d.diff2 ] & 0x0f ) == 0 )
929 element[ num ] = pi[ d.diff1 ];
936 if( condition( element, num ) )
939 for( size_type i = 0 ; i < num ; i++ )
941 const pointer_diff_type &d = elist[ i ];
942 num_painted += po[ d.diff1 ] != output_value ? 1 : 0;
944 po[ d.diff1 ] = output_value;
948 for( size_type i = 0 ; i < ulist.size( ) ; i++ )
950 const pointer_diff_type &d = ulist[ i ];
951 if( ( pw[ d.diff2 ] & 0xf0 ) == 0 )
953 pw[ d.diff2 ] |= 0xf0;
954 que.push_back( pointer_diff_type( cur.diff1 + d.diff1, cur.diff2 + d.diff2 ) );
961 return( num_painted );
982 template <
class Array1,
class Array2,
class Po
intList,
class Component,
class Condition >
983 typename Array1::difference_type
region_growing(
const Array1 &in, Array2 &out,
const PointList &start_points,
typename Array2::value_type output_value,
986 return(
region_growing( in, out, __region_growing_utility__::no_mask( ), start_points, output_value, components, condition, max_paint ) );
998 #endif // __INCLUDE_MIST_REGIONGROWING__