Example #1
0
static void make_adjacent( Segmenter *s, Region* r1, Region* r2 )
{
    if( !is_adjacent( r1, r2 ) ){
        if( r1->flags & SATURATED_REGION_FLAG ){
            r2->flags |= FRAGMENTED_REGION_FLAG;

        }else if( r2->flags & SATURATED_REGION_FLAG ){
            r1->flags |= FRAGMENTED_REGION_FLAG;

        }else{
            if( r1->adjacent_region_count == s->max_adjacent_regions ){
                make_saturated(r1);
                r2->flags |= FRAGMENTED_REGION_FLAG;

                if( r2->adjacent_region_count == s->max_adjacent_regions ){
                    make_saturated(r2);
                    r1->flags |= FRAGMENTED_REGION_FLAG;
                }
            }else if( r2->adjacent_region_count == s->max_adjacent_regions ){
                make_saturated(r2);
                r1->flags |= FRAGMENTED_REGION_FLAG;
            }else{
                assert( !(r1->flags & SATURATED_REGION_FLAG) );
                assert( !(r2->flags & SATURATED_REGION_FLAG) );
                assert( r1->adjacent_region_count < s->max_adjacent_regions );
                assert( r2->adjacent_region_count < s->max_adjacent_regions );
                r1->adjacent_regions[ r1->adjacent_region_count++ ] = r2;
                r2->adjacent_regions[ r2->adjacent_region_count++ ] = r1;
            }
        }
    }

    // postcondition, adjacency link is bi-directional or isn't created
    assert(
        (r1_adjacent_contains_r2( r1, r2 ) && r1_adjacent_contains_r2( r2, r1 ))
        ||
        (!r1_adjacent_contains_r2( r1, r2 ) && !r1_adjacent_contains_r2( r2, r1 ))
    );
}
Example #2
0
// merge r2 into r1 by first removing all common adjacencies from r2
// then transferring the remainder of adjacencies to r1 after discarding
// any excess adjacencies.
static void merge_regions( Segmenter *s, Region* r1, Region* r2 )
{
    int i;
 
    assert( r1 != r2 );
    assert( !r1_adjacent_contains_r2( r1, r2 ) && !r1_adjacent_contains_r2( r2, r1 ) );

    if( r1->flags & SATURATED_REGION_FLAG ){
        make_saturated( r2 );

        if( r2->flags & SATURATED_REGION_FLAG )
            make_saturated( r1 );

    }else if( r2->flags & SATURATED_REGION_FLAG ){
        make_saturated( r1 );

    }else{

        // remove adjacencies of r2 which are already in r1
        for( i = 0; i<r2->adjacent_region_count; ++i ){
            Region *a = r2->adjacent_regions[i];
            if( is_adjacent( a, r1 ) ){
                remove_adjacent_from( a, r2 );
                r2->adjacent_regions[i] = r2->adjacent_regions[ --r2->adjacent_region_count ];
            }
        }

        if( r1->adjacent_region_count + r2->adjacent_region_count > s->max_adjacent_regions ){
            make_saturated( r1 );
            make_saturated( r2 );
        }else{
            // remove adjacencies from r2 and add them to r1
            
            for( i=0; i < r2->adjacent_region_count; ++i ){
                Region *a = r2->adjacent_regions[ i ];

                replace_adjacent( a, r2, r1 ); // replace r2 with r1 in the adjacency list of a
                r1->adjacent_regions[r1->adjacent_region_count++] = a;

                assert( a->adjacent_region_count <= s->max_adjacent_regions );
                assert( r1->adjacent_region_count <= s->max_adjacent_regions );
            }

            r2->adjacent_region_count = 0;
        }
    }

    r1->flags |= r2->flags;

    if( r2->left < r1->left )
        r1->left = r2->left;

    if( r2->top < r1->top )
        r1->top = r2->top;

    if( r2->right > r1->right )
        r1->right = r2->right;

    if( r2->bottom > r1->bottom )
        r1->bottom = r2->bottom;

    // postcondition: all adjacencies to r1 are bidirectional

#ifndef NDEBUG
    for( i = 0; i < r1->adjacent_region_count; ++i ){
        Region *a = r1->adjacent_regions[i];
        assert( r1_adjacent_contains_r2( r1, a ) );
    }
#endif
}
Example #3
0
// recursively propagate descendent count and max depth upwards
// r->visit_counter is incremented each time we have an opportunity
// to traverse to a parent. we only actually visit it once the visit
// counter reaches adjacent_region_count - 1 i.e. that we have already
// visited all of its other children
// as we travel upwards we collect nodes with the constraints defined by
// min_target_root_descendent_count, max_target_root_descendent_count,
// min_depth and max_depth
// we never traverse above a node which exceeds these constraints. we also
// never traverse nodes which are saturated or fragmented because it is
// ambiguous whether such a node has a parent, or if all it's children are
// attched, and we can't determine this in a single pass (we could save a list
// of these nodes for a later pass but we don't bother.)
// during the calls to this function we store the maximum leaf-to-node depth
// in r->depth, later this field has a different meaning
static void propagate_descendent_count_and_max_depth_upwards(
        Segmenter *s, Region *r, FidtrackerX *ft)
{
    int i;
    Region *parent = 0;

    assert( r->level == NOT_TRAVERSED );
    assert( r->children_visited_count == (r->adjacent_region_count - 1)         // has an untraversed parent 
            || r->children_visited_count == r->adjacent_region_count );   // is adjacent to root region

    r->descendent_count = 0;
    r->depth = 0;
    r->level = TRAVERSING;

    for( i=0; i < r->adjacent_region_count; ++i ){
        Region *adjacent = r->adjacent_regions[i];
        assert( r1_adjacent_contains_r2( adjacent, r ) );

        if( adjacent->level == TRAVERSED ){
            r->descendent_count += (short)(adjacent->descendent_count + 1);
            r->depth = (short)MAX( r->depth, (adjacent->depth + 1) );
        }else{
            assert( parent == 0 );
            parent = adjacent;
        }
    }

    r->level = TRAVERSED;

    if( r->descendent_count == ft->max_target_root_descendent_count
            && r->depth >= ft->min_depth && r->depth <= ft->max_depth ){

        // found fiducial candidate
        link_region( &ft->root_regions_head, r );
    }else{

        if( r->descendent_count >= ft->min_target_root_descendent_count
            && r->descendent_count < ft->max_target_root_descendent_count
            && r->depth >= ft->min_depth && r->depth <= ft->max_depth ) {
				link_region( &ft->root_regions_head, r );
       } else if( r->descendent_count >= ft->min_target_root_descendent_count-3
            && r->descendent_count < ft->max_target_root_descendent_count+3
            && r->depth >= ft->min_depth-1 && r->depth <= ft->max_depth+1 ) {
				r->flags |= LOST_SYMBOL_FLAG;
				link_region( &ft->root_regions_head, r );
       }
  

        if( parent
                && !(r->flags & (   SATURATED_REGION_FLAG |
                                    ADJACENT_TO_ROOT_REGION_FLAG |
                                    FREE_REGION_FLAG ) ) ){
        

            ++parent->children_visited_count;

            if( r->descendent_count < ft->max_target_root_descendent_count
                    && r->depth < ft->max_depth ){

                // continue propagating depth and descendent count upwards
                // so long as parent isn't a saturated node in which case it is
                // ambiguous whether parent has a parent or not so we skip it

                if(
                    !(parent->flags & SATURATED_REGION_FLAG)
                    &&
                    ( ( (!(parent->flags & (ADJACENT_TO_ROOT_REGION_FLAG | FRAGMENTED_REGION_FLAG) )
                        && parent->children_visited_count == (parent->adjacent_region_count - 1))
                    ||
                    ((parent->flags & (ADJACENT_TO_ROOT_REGION_FLAG | FRAGMENTED_REGION_FLAG) )
                        && parent->children_visited_count == parent->adjacent_region_count) ) )
                        ){

                    assert( r1_adjacent_contains_r2( r, parent ) );
                    assert( r1_adjacent_contains_r2( parent, r ) );

                    propagate_descendent_count_and_max_depth_upwards( s, parent, ft);
                }
            }
        }
    }
}