Esempio n. 1
0
/*F///////////////////////////////////////////////////////////////////////////////////////
//    Name: icvContourFromContourTree
//    Purpose:
//    reconstracts contour from binary tree representation  
//    Context:
//    Parameters:
//      tree   -  pointer to the input binary tree representation 
//      storage - pointer to the current storage block
//      contour - pointer to output contour object.
//      criteria - criteria for the definition threshold value
//                 for the contour reconstracting (level or precision)
//F*/
CV_IMPL CvSeq*
cvContourFromContourTree( const CvContourTree*  tree,
                          CvMemStorage*  storage,
                          CvTermCriteria  criteria )
{
    CvSeq* contour = 0;
    _CvTrianAttr **ptr_buf = 0;     /*  pointer to the pointer's buffer  */
    int *level_buf = 0;
    int i_buf;

    int lpt;
    double area_all;
    double threshold;
    int cur_level;
    int level;
    int seq_flags;
    char log_iter, log_eps;
    int out_hearder_size;
    _CvTrianAttr *tree_one = 0, tree_root;  /*  current vertex  */

    CvSeqReader reader;
    CvSeqWriter writer;

    CV_FUNCNAME("cvContourFromContourTree");

    __BEGIN__;

    if( !tree )
        CV_ERROR( CV_StsNullPtr, "" );

    if( !CV_IS_SEQ_POLYGON_TREE( tree ))
        CV_ERROR_FROM_STATUS( CV_BADFLAG_ERR );

    criteria = cvCheckTermCriteria( criteria, 0., 100 );

    lpt = tree->total;
    ptr_buf = NULL;
    level_buf = NULL;
    i_buf = 0;
    cur_level = 0;
    log_iter = (char) (criteria.type == CV_TERMCRIT_ITER ||
                       (criteria.type == CV_TERMCRIT_ITER + CV_TERMCRIT_EPS));
    log_eps = (char) (criteria.type == CV_TERMCRIT_EPS ||
                      (criteria.type == CV_TERMCRIT_ITER + CV_TERMCRIT_EPS));

    cvStartReadSeq( (CvSeq *) tree, &reader, 0 );

    out_hearder_size = sizeof( CvContour );

    seq_flags = CV_SEQ_POLYGON;
    cvStartWriteSeq( seq_flags, out_hearder_size, sizeof( CvPoint ), storage, &writer );

    ptr_buf = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * ));
    if( ptr_buf == NULL )
        CV_ERROR_FROM_STATUS( CV_OUTOFMEM_ERR );
    if( log_iter )
    {
        level_buf = (int *) cvAlloc( lpt * (sizeof( int )));

        if( level_buf == NULL )
            CV_ERROR_FROM_STATUS( CV_OUTOFMEM_ERR );
    }

    memset( ptr_buf, 0, lpt * sizeof( _CvTrianAttr * ));

/*     write the first tree root's point as a start point of the result contour  */
    CV_WRITE_SEQ_ELEM( tree->p1, writer );
/*     write the second tree root"s point into buffer    */

/*     read the root of the tree   */
    CV_READ_SEQ_ELEM( tree_root, reader );

    tree_one = &tree_root;
    area_all = tree_one->area;

    if( log_eps )
        threshold = criteria.epsilon * area_all;
    else
        threshold = 10 * area_all;

    if( log_iter )
        level = criteria.max_iter;
    else
        level = -1;

/*  contour from binary tree constraction    */
    while( i_buf >= 0 )
    {
        if( tree_one != NULL && (cur_level <= level || tree_one->area >= threshold) )
/*   go to left sub tree for the vertex and save pointer to the right vertex   */
/*   into the buffer     */
        {
            ptr_buf[i_buf] = tree_one;
            if( log_iter )
            {
                level_buf[i_buf] = cur_level;
                cur_level++;
            }
            i_buf++;
            tree_one = tree_one->next_v1;
        }
        else
        {
            i_buf--;
            if( i_buf >= 0 )
            {
                CvPoint pt = ptr_buf[i_buf]->pt;
                CV_WRITE_SEQ_ELEM( pt, writer );
                tree_one = ptr_buf[i_buf]->next_v2;
                if( log_iter )
                {
                    cur_level = level_buf[i_buf] + 1;
                }
            }
        }
    }

    contour = cvEndWriteSeq( &writer );
    cvBoundingRect( contour, 1 );

    __CLEANUP__;
    __END__;

    cvFree( &level_buf );
    cvFree( &ptr_buf );

    return contour;
}
Esempio n. 2
0
CV_IMPL  CvBox2D
cvMinAreaRect2( const CvArr* array, CvMemStorage* storage )
{
    CvMemStorage* temp_storage = 0;
    CvBox2D box;
    CvPoint2D32f* points = 0;
    
    CV_FUNCNAME( "cvMinAreaRect2" );

    memset(&box, 0, sizeof(box));

    __BEGIN__;

    int i, n;
    CvSeqReader reader;
    CvContour contour_header;
    CvSeqBlock block;
    CvSeq* ptseq = (CvSeq*)array;
    CvPoint2D32f out[3];

    if( CV_IS_SEQ(ptseq) )
    {
        if( !CV_IS_SEQ_POINT_SET(ptseq) &&
            (CV_SEQ_KIND(ptseq) != CV_SEQ_KIND_CURVE || !CV_IS_SEQ_CONVEX(ptseq) ||
            CV_SEQ_ELTYPE(ptseq) != CV_SEQ_ELTYPE_PPOINT ))
            CV_ERROR( CV_StsUnsupportedFormat,
                "Input sequence must consist of 2d points or pointers to 2d points" );
        if( !storage )
            storage = ptseq->storage;
    }
    else
    {
        CV_CALL( ptseq = cvPointSeqFromMat(
            CV_SEQ_KIND_GENERIC, array, &contour_header, &block ));
    }

    if( storage )
    {
        CV_CALL( temp_storage = cvCreateChildMemStorage( storage ));
    }
    else
    {
        CV_CALL( temp_storage = cvCreateMemStorage(1 << 10));
    }

    if( !CV_IS_SEQ_CONVEX( ptseq ))
    {
        CV_CALL( ptseq = cvConvexHull2( ptseq, temp_storage, CV_CLOCKWISE, 1 ));
    }
    else if( !CV_IS_SEQ_POINT_SET( ptseq ))
    {
        CvSeqWriter writer;
        
        if( !CV_IS_SEQ(ptseq->v_prev) || !CV_IS_SEQ_POINT_SET(ptseq->v_prev))
            CV_ERROR( CV_StsBadArg,
            "Convex hull must have valid pointer to point sequence stored in v_prev" );
        cvStartReadSeq( ptseq, &reader );
        cvStartWriteSeq( CV_SEQ_KIND_CURVE|CV_SEQ_FLAG_CONVEX|CV_SEQ_ELTYPE(ptseq->v_prev),
                         sizeof(CvContour), CV_ELEM_SIZE(ptseq->v_prev->flags),
                         temp_storage, &writer );
            
        for( i = 0; i < ptseq->total; i++ )
        {
            CvPoint pt = **(CvPoint**)(reader.ptr);
            CV_WRITE_SEQ_ELEM( pt, writer );
        }

        ptseq = cvEndWriteSeq( &writer );
    }

    n = ptseq->total;

    CV_CALL( points = (CvPoint2D32f*)cvAlloc( n*sizeof(points[0]) ));
    cvStartReadSeq( ptseq, &reader );

    if( CV_SEQ_ELTYPE( ptseq ) == CV_32SC2 )
    {
        for( i = 0; i < n; i++ )
        {
            CvPoint pt;
            CV_READ_SEQ_ELEM( pt, reader );
            points[i].x = (float)pt.x;
            points[i].y = (float)pt.y;
        }
    }
    else
    {
        for( i = 0; i < n; i++ )
        {
            CV_READ_SEQ_ELEM( points[i], reader );
        }
    }
    
    if( n > 2 )
    {
        icvRotatingCalipers( points, n, CV_CALIPERS_MINAREARECT, (float*)out );
        box.center.x = out[0].x + (out[1].x + out[2].x)*0.5f;
        box.center.y = out[0].y + (out[1].y + out[2].y)*0.5f;
        box.size.height = (float)sqrt((double)out[1].x*out[1].x + (double)out[1].y*out[1].y);
        box.size.width = (float)sqrt((double)out[2].x*out[2].x + (double)out[2].y*out[2].y);
        box.angle = (float)atan2( -(double)out[1].y, (double)out[1].x );
    }
    else if( n == 2 )
    {
        box.center.x = (points[0].x + points[1].x)*0.5f;
        box.center.y = (points[0].y + points[1].y)*0.5f;
        double dx = points[1].x - points[0].x;
        double dy = points[1].y - points[0].y;
        box.size.height = (float)sqrt(dx*dx + dy*dy);
        box.size.width = 0;
        box.angle = (float)atan2( -dy, dx );
    }
    else
    {
        if( n == 1 )
            box.center = points[0];
    }

    box.angle = (float)(box.angle*180/CV_PI);

    __END__; 

    cvReleaseMemStorage( &temp_storage );
    cvFree( &points );

    return box;
}
Esempio n. 3
0
static CvSeq*
icvGetComponent(uchar* img, int step, CvRect rect,
CvMemStorage* storage) {
    const char nbd = 4;
    int  deltas[16];
    int  x, y;
    CvSeq* exterior = 0;
    char* ptr;

    /* initialize local state */
    CV_INIT_3X3_DELTAS(deltas, step, 1);
    memcpy(deltas + 8, deltas, 8 * sizeof(deltas[0]));

    ptr = (char*)(img + step * rect.y);
    rect.width += rect.x;
    rect.height += rect.y;

    for (y = rect.y; y < rect.height; y++, ptr += step) {
        int prev = ptr[rect.x - 1] & -2;

        for (x = rect.x; x < rect.width; x++) {
            int p = ptr[x] & -2;

            //assert( exterior || ((p | prev) & -4) == 0 );

            if (p != prev) {
                CvSeq* seq = 0;
                int is_hole = 0;
                CvSeqWriter  writer;
                char*  i0, *i1, *i3, *i4 = 0;
                int  prev_s = -1, s, s_end;
                CvPoint pt = { x, y };

                if (!(prev == 0 && p == 2)) {   /* if not external contour */
                    /* check hole */
                    if (p != 0 || prev < 1) {
                        prev = p;
                        continue;
                    }

                    is_hole = 1;
                    if (!exterior) {
                        assert(0);
                        return 0;
                    }
                }

                cvStartWriteSeq(CV_SEQ_CONTOUR | (is_hole ? CV_SEQ_FLAG_HOLE : 0),
                sizeof(CvContour), sizeof(CvPoint), storage, &writer);
                s_end = s = is_hole ? 0 : 4;
                i0 = ptr + x - is_hole;

                do {
                    s = (s - 1) & 7;
                    i1 = i0 + deltas[s];
                    if ((*i1 & -2) != 0) {
                        break;
                    }
                } while (s != s_end);

                if (s == s_end) {           /* single pixel domain */
                    *i0 = (char)(nbd | -128);
                    CV_WRITE_SEQ_ELEM(pt, writer);
                } else {
                    i3 = i0;
                    prev_s = s ^ 4;

                    /* follow border */
                    for (;;) {
                        s_end = s;

                        for (;;) {
                            i4 = i3 + deltas[++s];
                            if ((*i4 & -2) != 0) {
                                break;
                            }
                        }
                        s &= 7;

                        /* check "right" bound */
                        if ((unsigned)(s - 1) < (unsigned) s_end) {
                            *i3 = (char)(nbd | -128);
                        } else if (*i3 > 0) {
                            *i3 = nbd;
                        }

                        if (s != prev_s) {
                            CV_WRITE_SEQ_ELEM(pt, writer);
                            prev_s = s;
                        }

                        pt.x += icvCodeDeltas[s].x;
                        pt.y += icvCodeDeltas[s].y;

                        if (i4 == i0 && i3 == i1) {
                            break;
                        }

                        i3 = i4;
                        s = (s + 4) & 7;
                    }                       /* end of border following loop */
                }

                seq = cvEndWriteSeq(&writer);
                cvContourBoundingRect(seq, 1);

                if (!is_hole) {
                    exterior = seq;
                } else {
                    seq->v_prev = exterior;
                    seq->h_next = exterior->v_next;
                    if (seq->h_next) {
                        seq->h_next->h_prev = seq;
                    }
                    exterior->v_next = seq;
                }

                prev = ptr[x] & -2;
            }
        }
    }

    return exterior;
}
Esempio n. 4
0
/*F///////////////////////////////////////////////////////////////////////////////////////
//    Name: icvCreateContourTree
//    Purpose:
//    Create binary tree representation for the contour 
//    Context:
//    Parameters:
//      contour - pointer to input contour object.
//      storage - pointer to the current storage block
//      tree   -  output pointer to the binary tree representation 
//      threshold - threshold for the binary tree building 
//
//F*/
static CvStatus
icvCreateContourTree( const CvSeq * contour, CvMemStorage * storage,
                      CvContourTree ** tree, double threshold )
{
    CvPoint *pt_p;              /*  pointer to previos points   */
    CvPoint *pt_n;              /*  pointer to next points      */
    CvPoint *pt1, *pt2;         /*  pointer to current points   */

    CvPoint t, tp1, tp2, tp3, tn1, tn2, tn3;
    int lpt, flag, i, j, i_tree, j_1, j_3, i_buf;
    double s, sp1, sp2, sn1, sn2, s_c, sp1_c, sp2_c, sn1_c, sn2_c, h, hp1, hp2, hn1, hn2,
        a, ap1, ap2, an1, an2, b, bp1, bp2, bn1, bn2;
    double a_s_c, a_sp1_c;

    _CvTrianAttr **ptr_p, **ptr_n, **ptr1, **ptr2;      /*  pointers to pointers of triangles  */
    _CvTrianAttr *cur_adr;

    int *num_p, *num_n, *num1, *num2;   /*   numbers of input contour points   */
    int nm, nmp1, nmp2, nmp3, nmn1, nmn2, nmn3;
    int seq_flags = 1, i_end, prev_null, prev2_null;
    double koef = 1.5;
    double eps = 1.e-7;
    double e;
    CvStatus status;
    int hearder_size;
    _CvTrianAttr tree_one, tree_two, *tree_end, *tree_root;

    CvSeqWriter writer;

    assert( contour != NULL && contour->total >= 4 );
    status = CV_OK;

    if( contour == NULL )
        return CV_NULLPTR_ERR;
    if( contour->total < 4 )
        return CV_BADSIZE_ERR;

    if( !CV_IS_SEQ_POLYGON( contour ))
        return CV_BADFLAG_ERR;


/*   Convert Sequence to array    */
    lpt = contour->total;
    pt_p = pt_n = NULL;
    num_p = num_n = NULL;
    ptr_p = ptr_n = ptr1 = ptr2 = NULL;
    tree_end = NULL;

    pt_p = (CvPoint *) cvAlloc( lpt * sizeof( CvPoint ));
    pt_n = (CvPoint *) cvAlloc( lpt * sizeof( CvPoint ));

    num_p = (int *) cvAlloc( lpt * sizeof( int ));
    num_n = (int *) cvAlloc( lpt * sizeof( int ));

    hearder_size = sizeof( CvContourTree );
    seq_flags = CV_SEQ_POLYGON_TREE;
    cvStartWriteSeq( seq_flags, hearder_size, sizeof( _CvTrianAttr ), storage, &writer );

    ptr_p = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * ));
    ptr_n = (_CvTrianAttr **) cvAlloc( lpt * sizeof( _CvTrianAttr * ));

    memset( ptr_p, 0, lpt * sizeof( _CvTrianAttr * ));
    memset( ptr_n, 0, lpt * sizeof( _CvTrianAttr * ));

    if( pt_p == NULL || pt_n == NULL )
        return CV_OUTOFMEM_ERR;
    if( ptr_p == NULL || ptr_n == NULL )
        return CV_OUTOFMEM_ERR;

/*     write fild for the binary tree root   */
/*  start_writer = writer;   */

    tree_one.pt.x = tree_one.pt.y = 0;
    tree_one.sign = 0;
    tree_one.area = 0;
    tree_one.r1 = tree_one.r2 = 0;
    tree_one.next_v1 = tree_one.next_v2 = tree_one.prev_v = NULL;

    CV_WRITE_SEQ_ELEM( tree_one, writer );
    tree_root = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

    if( cvCvtSeqToArray( contour, (char *) pt_p ) == (char *) contour )
        return CV_BADPOINT_ERR;

    for( i = 0; i < lpt; i++ )
        num_p[i] = i;

    i = lpt;
    flag = 0;
    i_tree = 0;
    e = 20.;                    /*  initial threshold value   */
    ptr1 = ptr_p;
    ptr2 = ptr_n;
    pt1 = pt_p;
    pt2 = pt_n;
    num1 = num_p;
    num2 = num_n;
/*  binary tree constraction    */
    while( i > 4 )
    {
        if( flag == 0 )
        {
            ptr1 = ptr_p;
            ptr2 = ptr_n;
            pt1 = pt_p;
            pt2 = pt_n;
            num1 = num_p;
            num2 = num_n;
            flag = 1;
        }
        else
        {
            ptr1 = ptr_n;
            ptr2 = ptr_p;
            pt1 = pt_n;
            pt2 = pt_p;
            num1 = num_n;
            num2 = num_p;
            flag = 0;
        }
        t = pt1[0];
        nm = num1[0];
        tp1 = pt1[i - 1];
        nmp1 = num1[i - 1];
        tp2 = pt1[i - 2];
        nmp2 = num1[i - 2];
        tp3 = pt1[i - 3];
        nmp3 = num1[i - 3];
        tn1 = pt1[1];
        nmn1 = num1[1];
        tn2 = pt1[2];
        nmn2 = num1[2];

        i_buf = 0;
        i_end = -1;
        CV_MATCH_CHECK( status,
                        icvCalcTriAttr( contour, t, tp1, nmp1, tn1, nmn1, &s, &s_c, &h, &a,
                                        &b ));
        CV_MATCH_CHECK( status,
                        icvCalcTriAttr( contour, tp1, tp2, nmp2, t, nm, &sp1, &sp1_c, &hp1,
                                        &ap1, &bp1 ));
        CV_MATCH_CHECK( status,
                        icvCalcTriAttr( contour, tp2, tp3, nmp3, tp1, nmp1, &sp2, &sp2_c, &hp2,
                                        &ap2, &bp2 ));
        CV_MATCH_CHECK( status,
                        icvCalcTriAttr( contour, tn1, t, nm, tn2, nmn2, &sn1, &sn1_c, &hn1,
                                        &an1, &bn1 ));


        j_3 = 3;
        prev_null = prev2_null = 0;
        for( j = 0; j < i; j++ )
        {
            tn3 = pt1[j_3];
            nmn3 = num1[j_3];
            if( j == 0 )
                j_1 = i - 1;
            else
                j_1 = j - 1;

            CV_MATCH_CHECK( status, icvCalcTriAttr( contour, tn2, tn1, nmn1, tn3, nmn3,
                                                    &sn2, &sn2_c, &hn2, &an2, &bn2 ));

            if( (s_c < sp1_c && s_c < sp2_c && s_c <= sn1_c && s_c <= sn2_c && s_c < e) ||
                (s_c == sp1_c && s_c <= sp2_c || s_c == sp2_c && s_c <= sp1_c) && s_c <= sn1_c
                && s_c <= sn2_c && s_c < e && j > 1 && prev2_null == 0 || (s_c < eps && j > 0
                                                                           && prev_null == 0) )

            {
                prev_null = prev2_null = 1;
                if( s_c < threshold )
                {
                    if( ptr1[j_1] == NULL && ptr1[j] == NULL )
                    {
                        if( i_buf > 0 )
                            ptr2[i_buf - 1] = NULL;
                        else
                            i_end = 0;
                    }
                    else
                    {
/*   form next vertex  */
                        tree_one.pt = t;
                        tree_one.sign = (char) (CV_SIGN( s ));
                        tree_one.r1 = h / a;
                        tree_one.r2 = b / a;
                        tree_one.area = fabs( s );
                        tree_one.next_v1 = ptr1[j_1];
                        tree_one.next_v2 = ptr1[j];

                        CV_WRITE_SEQ_ELEM( tree_one, writer );
                        cur_adr = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

                        if( ptr1[j_1] != NULL )
                            ptr1[j_1]->prev_v = cur_adr;
                        if( ptr1[j] != NULL )
                            ptr1[j]->prev_v = cur_adr;

                        if( i_buf > 0 )
                            ptr2[i_buf - 1] = cur_adr;
                        else
                        {
                            tree_end = (_CvTrianAttr *) writer.ptr;
                            i_end = 1;
                        }
                        i_tree++;
                    }
                }
                else
/*   form next vertex    */
                {
                    tree_one.pt = t;
                    tree_one.sign = (char) (CV_SIGN( s ));
                    tree_one.area = fabs( s );
                    tree_one.r1 = h / a;
                    tree_one.r2 = b / a;
                    tree_one.next_v1 = ptr1[j_1];
                    tree_one.next_v2 = ptr1[j];

                    CV_WRITE_SEQ_ELEM( tree_one, writer );
                    cur_adr = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

                    if( ptr1[j_1] != NULL )
                        ptr1[j_1]->prev_v = cur_adr;
                    if( ptr1[j] != NULL )
                        ptr1[j]->prev_v = cur_adr;

                    if( i_buf > 0 )
                        ptr2[i_buf - 1] = cur_adr;
                    else
                    {
                        tree_end = cur_adr;
                        i_end = 1;
                    }
                    i_tree++;
                }
            }
            else
/*   the current triangle is'not LMIAT    */
            {
                prev_null = 0;
                switch (prev2_null)
                {
                case 0:
                    break;
                case 1:
                    {
                        prev2_null = 2;
                        break;
                    }
                case 2:
                    {
                        prev2_null = 0;
                        break;
                    }
                }
                if( j != i - 1 || i_end == -1 )
                    ptr2[i_buf] = ptr1[j];
                else if( i_end == 0 )
                    ptr2[i_buf] = NULL;
                else
                    ptr2[i_buf] = tree_end;
                pt2[i_buf] = t;
                num2[i_buf] = num1[j];
                i_buf++;
            }
/*    go to next vertex    */
            tp3 = tp2;
            tp2 = tp1;
            tp1 = t;
            t = tn1;
            tn1 = tn2;
            tn2 = tn3;
            nmp3 = nmp2;
            nmp2 = nmp1;
            nmp1 = nm;
            nm = nmn1;
            nmn1 = nmn2;
            nmn2 = nmn3;

            sp2 = sp1;
            sp1 = s;
            s = sn1;
            sn1 = sn2;
            sp2_c = sp1_c;
            sp1_c = s_c;
            s_c = sn1_c;
            sn1_c = sn2_c;

            ap2 = ap1;
            ap1 = a;
            a = an1;
            an1 = an2;
            bp2 = bp1;
            bp1 = b;
            b = bn1;
            bn1 = bn2;
            hp2 = hp1;
            hp1 = h;
            h = hn1;
            hn1 = hn2;
            j_3++;
            if( j_3 >= i )
                j_3 = 0;
        }

        i = i_buf;
        e = e * koef;
    }

/*  constract tree root  */
    if( i != 4 )
        return CV_BADFACTOR_ERR;

    t = pt2[0];
    tn1 = pt2[1];
    tn2 = pt2[2];
    tp1 = pt2[3];
    nm = num2[0];
    nmn1 = num2[1];
    nmn2 = num2[2];
    nmp1 = num2[3];
/*   first pair of the triangles   */
    CV_MATCH_CHECK( status,
                    icvCalcTriAttr( contour, t, tp1, nmp1, tn1, nmn1, &s, &s_c, &h, &a, &b ));
    CV_MATCH_CHECK( status,
                    icvCalcTriAttr( contour, tn2, tn1, nmn1, tp1, nmp1, &sn2, &sn2_c, &hn2,
                                    &an2, &bn2 ));
/*   second pair of the triangles   */
    CV_MATCH_CHECK( status,
                    icvCalcTriAttr( contour, tn1, t, nm, tn2, nmn2, &sn1, &sn1_c, &hn1, &an1,
                                    &bn1 ));
    CV_MATCH_CHECK( status,
                    icvCalcTriAttr( contour, tp1, tn2, nmn2, t, nm, &sp1, &sp1_c, &hp1, &ap1,
                                    &bp1 ));

    a_s_c = fabs( s_c - sn2_c );
    a_sp1_c = fabs( sp1_c - sn1_c );

    if( a_s_c > a_sp1_c )
/*   form child vertexs for the root     */
    {
        tree_one.pt = t;
        tree_one.sign = (char) (CV_SIGN( s ));
        tree_one.area = fabs( s );
        tree_one.r1 = h / a;
        tree_one.r2 = b / a;
        tree_one.next_v1 = ptr2[3];
        tree_one.next_v2 = ptr2[0];

        tree_two.pt = tn2;
        tree_two.sign = (char) (CV_SIGN( sn2 ));
        tree_two.area = fabs( sn2 );
        tree_two.r1 = hn2 / an2;
        tree_two.r2 = bn2 / an2;
        tree_two.next_v1 = ptr2[1];
        tree_two.next_v2 = ptr2[2];

        CV_WRITE_SEQ_ELEM( tree_one, writer );
        cur_adr = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

        if( s_c > sn2_c )
        {
            if( ptr2[3] != NULL )
                ptr2[3]->prev_v = cur_adr;
            if( ptr2[0] != NULL )
                ptr2[0]->prev_v = cur_adr;
            ptr1[0] = cur_adr;

            i_tree++;

            CV_WRITE_SEQ_ELEM( tree_two, writer );
            cur_adr = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

            if( ptr2[1] != NULL )
                ptr2[1]->prev_v = cur_adr;
            if( ptr2[2] != NULL )
                ptr2[2]->prev_v = cur_adr;
            ptr1[1] = cur_adr;

            i_tree++;

            pt1[0] = tp1;
            pt1[1] = tn1;
        }
        else
        {
            CV_WRITE_SEQ_ELEM( tree_two, writer );
            cur_adr = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

            if( ptr2[1] != NULL )
                ptr2[1]->prev_v = cur_adr;
            if( ptr2[2] != NULL )
                ptr2[2]->prev_v = cur_adr;
            ptr1[0] = cur_adr;

            i_tree++;

            CV_WRITE_SEQ_ELEM( tree_one, writer );
            cur_adr = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

            if( ptr2[3] != NULL )
                ptr2[3]->prev_v = cur_adr;
            if( ptr2[0] != NULL )
                ptr2[0]->prev_v = cur_adr;
            ptr1[1] = cur_adr;

            i_tree++;

            pt1[0] = tn1;
            pt1[1] = tp1;
        }
    }
    else
    {
        tree_one.pt = tp1;
        tree_one.sign = (char) (CV_SIGN( sp1 ));
        tree_one.area = fabs( sp1 );
        tree_one.r1 = hp1 / ap1;
        tree_one.r2 = bp1 / ap1;
        tree_one.next_v1 = ptr2[2];
        tree_one.next_v2 = ptr2[3];

        tree_two.pt = tn1;
        tree_two.sign = (char) (CV_SIGN( sn1 ));
        tree_two.area = fabs( sn1 );
        tree_two.r1 = hn1 / an1;
        tree_two.r2 = bn1 / an1;
        tree_two.next_v1 = ptr2[0];
        tree_two.next_v2 = ptr2[1];

        CV_WRITE_SEQ_ELEM( tree_one, writer );
        cur_adr = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

        if( sp1_c > sn1_c )
        {
            if( ptr2[2] != NULL )
                ptr2[2]->prev_v = cur_adr;
            if( ptr2[3] != NULL )
                ptr2[3]->prev_v = cur_adr;
            ptr1[0] = cur_adr;

            i_tree++;

            CV_WRITE_SEQ_ELEM( tree_two, writer );
            cur_adr = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

            if( ptr2[0] != NULL )
                ptr2[0]->prev_v = cur_adr;
            if( ptr2[1] != NULL )
                ptr2[1]->prev_v = cur_adr;
            ptr1[1] = cur_adr;

            i_tree++;

            pt1[0] = tn2;
            pt1[1] = t;
        }
        else
        {
            CV_WRITE_SEQ_ELEM( tree_two, writer );
            cur_adr = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

            if( ptr2[0] != NULL )
                ptr2[0]->prev_v = cur_adr;
            if( ptr2[1] != NULL )
                ptr2[1]->prev_v = cur_adr;
            ptr1[0] = cur_adr;

            i_tree++;

            CV_WRITE_SEQ_ELEM( tree_one, writer );
            cur_adr = (_CvTrianAttr *) (writer.ptr - writer.seq->elem_size);

            if( ptr2[2] != NULL )
                ptr2[2]->prev_v = cur_adr;
            if( ptr2[3] != NULL )
                ptr2[3]->prev_v = cur_adr;
            ptr1[1] = cur_adr;

            i_tree++;

            pt1[0] = t;
            pt1[1] = tn2;

        }
    }

/*    form root   */
    s = cvContourArea( contour );

    tree_root->pt = pt1[1];
    tree_root->sign = 0;
    tree_root->area = fabs( s );
    tree_root->r1 = 0;
    tree_root->r2 = 0;
    tree_root->next_v1 = ptr1[0];
    tree_root->next_v2 = ptr1[1];
    tree_root->prev_v = NULL;

    ptr1[0]->prev_v = (_CvTrianAttr *) tree_root;
    ptr1[1]->prev_v = (_CvTrianAttr *) tree_root;

/*     write binary tree root   */
/*    CV_WRITE_SEQ_ELEM (tree_one, start_writer);   */
    i_tree++;
/*  create Sequence hearder     */
    *((CvSeq **) tree) = cvEndWriteSeq( &writer );
/*   write points for the main segment into sequence header   */
    (*tree)->p1 = pt1[0];

  M_END:

    cvFree( &ptr_n );
    cvFree( &ptr_p );
    cvFree( &num_n );
    cvFree( &num_p );
    cvFree( &pt_n );
    cvFree( &pt_p );

    return status;
}
Esempio n. 5
0
static int
icvFindContoursInInterval( const CvArr* src,
                           /*int minValue, int maxValue,*/
                           CvMemStorage* storage,
                           CvSeq** result,
                           int contourHeaderSize )
{
    int count = 0;
    CvMemStorage* storage00 = 0;
    CvMemStorage* storage01 = 0;
    CvSeq* first = 0;

    CV_FUNCNAME( "icvFindContoursInInterval" );

    __BEGIN__;

    int i, j, k, n;

    uchar*  src_data = 0;
    int  img_step = 0;
    CvSize  img_size;

    int  connect_flag;
    int  lower_total;
    int  upper_total;
    int  all_total;

    CvSeq*  runs;
    CvLinkedRunPoint  tmp;
    CvLinkedRunPoint*  tmp_prev;
    CvLinkedRunPoint*  upper_line = 0;
    CvLinkedRunPoint*  lower_line = 0;
    CvLinkedRunPoint*  last_elem;

    CvLinkedRunPoint*  upper_run = 0;
    CvLinkedRunPoint*  lower_run = 0;
    CvLinkedRunPoint*  prev_point = 0;

    CvSeqWriter  writer_ext;
    CvSeqWriter  writer_int;
    CvSeqWriter  writer;
    CvSeqReader  reader;

    CvSeq* external_contours;
    CvSeq* internal_contours;
    CvSeq* prev = 0;

    if( !storage )
        CV_ERROR( CV_StsNullPtr, "NULL storage pointer" );

    if( !result )
        CV_ERROR( CV_StsNullPtr, "NULL double CvSeq pointer" );

    if( contourHeaderSize < (int)sizeof(CvContour))
        CV_ERROR( CV_StsBadSize, "Contour header size must be >= sizeof(CvContour)" );

    CV_CALL( storage00 = cvCreateChildMemStorage(storage));
    CV_CALL( storage01 = cvCreateChildMemStorage(storage));

    {
        CvMat stub, *mat;

        CV_CALL( mat = cvGetMat( src, &stub ));
        if( !CV_IS_MASK_ARR(mat))
            CV_ERROR( CV_StsBadArg, "Input array must be 8uC1 or 8sC1" );
        src_data = mat->data.ptr;
        img_step = mat->step;
        img_size = cvGetMatSize( mat );
    }

    // Create temporary sequences
    runs = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvLinkedRunPoint), storage00 );
    cvStartAppendToSeq( runs, &writer );

    cvStartWriteSeq( 0, sizeof(CvSeq), sizeof(CvLinkedRunPoint*), storage01, &writer_ext );
    cvStartWriteSeq( 0, sizeof(CvSeq), sizeof(CvLinkedRunPoint*), storage01, &writer_int );

    tmp_prev = &(tmp);
    tmp_prev->next = 0;
    tmp_prev->link = 0;
    
    // First line. None of runs is binded
    tmp.pt.y = 0;
    i = 0;
    CV_WRITE_SEQ_ELEM( tmp, writer );
    upper_line = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer );
    
    tmp_prev = upper_line;
    for( j = 0; j < img_size.width; )
    {
        for( ; j < img_size.width && !ICV_IS_COMPONENT_POINT(src_data[j]); j++ )
            ;
        if( j == img_size.width )
            break;

        tmp.pt.x = j;
        CV_WRITE_SEQ_ELEM( tmp, writer );
        tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer );
        tmp_prev = tmp_prev->next;

        for( ; j < img_size.width && ICV_IS_COMPONENT_POINT(src_data[j]); j++ )
            ;

        tmp.pt.x = j-1;
        CV_WRITE_SEQ_ELEM( tmp, writer );
        tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer );
        tmp_prev->link = tmp_prev->next;
        // First point of contour
        CV_WRITE_SEQ_ELEM( tmp_prev, writer_ext );
        tmp_prev = tmp_prev->next;
    }
    cvFlushSeqWriter( &writer );
    upper_line = upper_line->next;
    upper_total = runs->total - 1;
    last_elem = tmp_prev;
    tmp_prev->next = 0;
    
    for( i = 1; i < img_size.height; i++ )
    {
//------// Find runs in next line
        src_data += img_step;
        tmp.pt.y = i;
        all_total = runs->total;
        for( j = 0; j < img_size.width; )
        {
            for( ; j < img_size.width && !ICV_IS_COMPONENT_POINT(src_data[j]); j++ )
                ;
            if( j == img_size.width ) break;

            tmp.pt.x = j;
            CV_WRITE_SEQ_ELEM( tmp, writer );
            tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer );
            tmp_prev = tmp_prev->next;

            for( ; j < img_size.width && ICV_IS_COMPONENT_POINT(src_data[j]); j++ )
                ;

            tmp.pt.x = j-1;
            CV_WRITE_SEQ_ELEM( tmp, writer );
            tmp_prev = tmp_prev->next = (CvLinkedRunPoint*)CV_GET_WRITTEN_ELEM( writer );
        }//j
        cvFlushSeqWriter( &writer );
        lower_line = last_elem->next;
        lower_total = runs->total - all_total;
        last_elem = tmp_prev;
        tmp_prev->next = 0;
//------//
//------// Find links between runs of lower_line and upper_line
        upper_run = upper_line;
        lower_run = lower_line;
        connect_flag = ICV_SINGLE;

        for( k = 0, n = 0; k < upper_total/2 && n < lower_total/2; )
        {
            switch( connect_flag )
            {
            case ICV_SINGLE:
                if( upper_run->next->pt.x < lower_run->next->pt.x )
                {
                    if( upper_run->next->pt.x >= lower_run->pt.x  -1 )
                    {
                        lower_run->link = upper_run;
                        connect_flag = ICV_CONNECTING_ABOVE;
                        prev_point = upper_run->next;
                    }
                    else
                        upper_run->next->link = upper_run;
                    k++;
                    upper_run = upper_run->next->next;
                }
                else
                {
                    if( upper_run->pt.x <= lower_run->next->pt.x  +1 )
                    {
                        lower_run->link = upper_run;
                        connect_flag = ICV_CONNECTING_BELOW;
                        prev_point = lower_run->next;
                    }
                    else
                    {
                        lower_run->link = lower_run->next;
                        // First point of contour
                        CV_WRITE_SEQ_ELEM( lower_run, writer_ext );
                    }
                    n++;
                    lower_run = lower_run->next->next;
                }
                break;
            case ICV_CONNECTING_ABOVE:
                if( upper_run->pt.x > lower_run->next->pt.x +1 )
                {
                    prev_point->link = lower_run->next;
                    connect_flag = ICV_SINGLE;
                    n++;
                    lower_run = lower_run->next->next;
                }
                else
                {
                    prev_point->link = upper_run;
                    if( upper_run->next->pt.x < lower_run->next->pt.x )
                    {
                        k++;
                        prev_point = upper_run->next;
                        upper_run = upper_run->next->next;
                    }
                    else
                    {
                        connect_flag = ICV_CONNECTING_BELOW;
                        prev_point = lower_run->next;
                        n++;
                        lower_run = lower_run->next->next;
                    }
                }
                break;
            case ICV_CONNECTING_BELOW:
                if( lower_run->pt.x > upper_run->next->pt.x +1 )
                {
                    upper_run->next->link = prev_point;
                    connect_flag = ICV_SINGLE;
                    k++;
                    upper_run = upper_run->next->next;
                }
                else
                {
                    // First point of contour
                    CV_WRITE_SEQ_ELEM( lower_run, writer_int );

                    lower_run->link = prev_point;
                    if( lower_run->next->pt.x < upper_run->next->pt.x )
                    {
                        n++;
                        prev_point = lower_run->next;
                        lower_run = lower_run->next->next;
                    }
                    else
                    {
                        connect_flag = ICV_CONNECTING_ABOVE;
                        k++;
                        prev_point = upper_run->next;
                        upper_run = upper_run->next->next;
                    }
                }
                break;          
            }
        }// k, n

        for( ; n < lower_total/2; n++ )
        {
            if( connect_flag != ICV_SINGLE )
            {
                prev_point->link = lower_run->next;
                connect_flag = ICV_SINGLE;
                lower_run = lower_run->next->next;
                continue;
            }
            lower_run->link = lower_run->next;

            //First point of contour
            CV_WRITE_SEQ_ELEM( lower_run, writer_ext );

            lower_run = lower_run->next->next;
        }

        for( ; k < upper_total/2; k++ )
        {
            if( connect_flag != ICV_SINGLE )
            {
                upper_run->next->link = prev_point;
                connect_flag = ICV_SINGLE;
                upper_run = upper_run->next->next;
                continue;
            }
            upper_run->next->link = upper_run;
            upper_run = upper_run->next->next;
        }
        upper_line = lower_line;
        upper_total = lower_total;
    }//i

    upper_run = upper_line;

    //the last line of image
    for( k = 0; k < upper_total/2; k++ )
    {
        upper_run->next->link = upper_run;
        upper_run = upper_run->next->next;
    }

//------//
//------//Find end read contours
    external_contours = cvEndWriteSeq( &writer_ext );
    internal_contours = cvEndWriteSeq( &writer_int );

    for( k = 0; k < 2; k++ )
    {
        CvSeq* contours = k == 0 ? external_contours : internal_contours;

        cvStartReadSeq( contours, &reader );

        for( j = 0; j < contours->total; j++, count++ )
        {
            CvLinkedRunPoint* p_temp;
            CvLinkedRunPoint* p00;
            CvLinkedRunPoint* p01;
            CvSeq* contour;

            CV_READ_SEQ_ELEM( p00, reader );
            p01 = p00;

            if( !p00->link )
                continue;

            cvStartWriteSeq( CV_SEQ_ELTYPE_POINT | CV_SEQ_POLYLINE | CV_SEQ_FLAG_CLOSED,
                             contourHeaderSize, sizeof(CvPoint), storage, &writer );
            do
            {
                CV_WRITE_SEQ_ELEM( p00->pt, writer );
                p_temp = p00;
                p00 = p00->link;
                p_temp->link = 0;
            }
            while( p00 != p01 );

            contour = cvEndWriteSeq( &writer );
            cvBoundingRect( contour, 1 );

            if( k != 0 )
                contour->flags |= CV_SEQ_FLAG_HOLE;

            if( !first )
                prev = first = contour;
            else
            {
                contour->h_prev = prev;
                prev = prev->h_next = contour;
            }
        }
    }

    __END__;

    if( !first )
        count = -1;

    if( result )
        *result = first;

    cvReleaseMemStorage(&storage00);
    cvReleaseMemStorage(&storage01);

    return count;
}
Esempio n. 6
0
static CvStatus
icvFindDominantPointsIPAN( CvSeq * contour,
                           CvMemStorage * storage,
                           CvSeq ** corners, int dmin2, int dmax2, int dneigh2, float amax )
{
    CvStatus status = CV_OK;

    /* variables */
    int n = contour->total;

    float *sharpness;
    float *distance;
    icvPointInfo *ptInf;

    int i, j, k;

    CvSeqWriter writer;

    float mincos = (float) cos( 3.14159265359 * amax / 180 );

    /* check bad arguments */
    if( contour == NULL )
        return CV_NULLPTR_ERR;
    if( storage == NULL )
        return CV_NULLPTR_ERR;
    if( corners == NULL )
        return CV_NULLPTR_ERR;
    if( dmin2 < 0 )
        return CV_BADSIZE_ERR;
    if( dmax2 < dmin2 )
        return CV_BADSIZE_ERR;
    if( (dneigh2 > dmax2) || (dneigh2 < 0) )
        return CV_BADSIZE_ERR;
    if( (amax < 0) || (amax > 180) )
        return CV_BADSIZE_ERR;

    sharpness = (float *) cvAlloc( n * sizeof( float ));
    distance = (float *) cvAlloc( n * sizeof( float ));

    ptInf = (icvPointInfo *) cvAlloc( n * sizeof( icvPointInfo ));

/*****************************************************************************************/
/*                                 First pass                                            */
/*****************************************************************************************/

    if( CV_IS_SEQ_CHAIN_CONTOUR( contour ))
    {
        CvChainPtReader reader;

        cvStartReadChainPoints( (CvChain *) contour, &reader );

        for( i = 0; i < n; i++ )
        {
            CV_READ_CHAIN_POINT( ptInf[i].pt, reader );
        }
    }
    else if( CV_IS_SEQ_POLYGON( contour ))
    {
        CvSeqReader reader;

        cvStartReadSeq( contour, &reader, 0 );

        for( i = 0; i < n; i++ )
        {
            CV_READ_SEQ_ELEM( ptInf[i].pt, reader );
        }
    }
    else
    {
        return CV_BADFLAG_ERR;
    }

    for( i = 0; i < n; i++ )
    {
        /* find nearest suitable points
           which satisfy distance constraint >dmin */
        int left_near = 0;
        int right_near = 0;
        int left_far, right_far;

        float dist_l = 0;
        float dist_r = 0;

        int i_plus = 0;
        int i_minus = 0;

        float max_cos_alpha;

        /* find  right minimum */
        while( dist_r < dmin2 )
        {
            float dx, dy;
            int ind;

            if( i_plus >= n )
                goto error;

            right_near = i_plus;

            if( dist_r < dneigh2 )
                ptInf[i].right_neigh = i_plus;

            i_plus++;

            ind = (i + i_plus) % n;
            dx = (float) (ptInf[i].pt.x - ptInf[ind].pt.x);
            dy = (float) (ptInf[i].pt.y - ptInf[ind].pt.y);
            dist_r = dx * dx + dy * dy;
        }
        /* find right maximum */
        while( dist_r <= dmax2 )
        {
            float dx, dy;
            int ind;

            if( i_plus >= n )
                goto error;

            distance[(i + i_plus) % n] = cvSqrt( dist_r );

            if( dist_r < dneigh2 )
                ptInf[i].right_neigh = i_plus;

            i_plus++;

            right_far = i_plus;

            ind = (i + i_plus) % n;

            dx = (float) (ptInf[i].pt.x - ptInf[ind].pt.x);
            dy = (float) (ptInf[i].pt.y - ptInf[ind].pt.y);
            dist_r = dx * dx + dy * dy;
        }
        right_far = i_plus;

        /* left minimum */
        while( dist_l < dmin2 )
        {
            float dx, dy;
            int ind;

            if( i_minus <= -n )
                goto error;

            left_near = i_minus;

            if( dist_l < dneigh2 )
                ptInf[i].left_neigh = i_minus;

            i_minus--;

            ind = i + i_minus;
            ind = (ind < 0) ? (n + ind) : ind;

            dx = (float) (ptInf[i].pt.x - ptInf[ind].pt.x);
            dy = (float) (ptInf[i].pt.y - ptInf[ind].pt.y);
            dist_l = dx * dx + dy * dy;
        }

        /* find left maximum */
        while( dist_l <= dmax2 )
        {
            float dx, dy;
            int ind;

            if( i_minus <= -n )
                goto error;

            ind = i + i_minus;
            ind = (ind < 0) ? (n + ind) : ind;

            distance[ind] = cvSqrt( dist_l );

            if( dist_l < dneigh2 )
                ptInf[i].left_neigh = i_minus;

            i_minus--;

            left_far = i_minus;

            ind = i + i_minus;
            ind = (ind < 0) ? (n + ind) : ind;

            dx = (float) (ptInf[i].pt.x - ptInf[ind].pt.x);
            dy = (float) (ptInf[i].pt.y - ptInf[ind].pt.y);
            dist_l = dx * dx + dy * dy;
        }
        left_far = i_minus;

        if( (i_plus - i_minus) > n + 2 )
            goto error;

        max_cos_alpha = -1;
        for( j = left_far + 1; j < left_near; j++ )
        {
            float dx, dy;
            float a, a2;
            int leftind = i + j;

            leftind = (leftind < 0) ? (n + leftind) : leftind;

            a = distance[leftind];
            a2 = a * a;

            for( k = right_near + 1; k < right_far; k++ )
            {
                int ind = (i + k) % n;
                float c2, cosalpha;
                float b = distance[ind];
                float b2 = b * b;

                /* compute cosinus */
                dx = (float) (ptInf[leftind].pt.x - ptInf[ind].pt.x);
                dy = (float) (ptInf[leftind].pt.y - ptInf[ind].pt.y);

                c2 = dx * dx + dy * dy;
                cosalpha = (a2 + b2 - c2) / (2 * a * b);

                max_cos_alpha = MAX( max_cos_alpha, cosalpha );

                if( max_cos_alpha < mincos )
                    max_cos_alpha = -1;

                sharpness[i] = max_cos_alpha;
            }
        }
    }
/*****************************************************************************************/
/*                                 Second pass                                           */
/*****************************************************************************************/

    cvStartWriteSeq( (contour->flags & ~CV_SEQ_ELTYPE_MASK) | CV_SEQ_ELTYPE_INDEX,
                     sizeof( CvSeq ), sizeof( int ), storage, &writer );

    /* second pass - nonmaxima suppression */
    /* neighborhood of point < dneigh2 */
    for( i = 0; i < n; i++ )
    {
        int suppressed = 0;
        if( sharpness[i] == -1 )
            continue;

        for( j = 1; (j <= ptInf[i].right_neigh) && (suppressed == 0); j++ )
        {
            if( sharpness[i] < sharpness[(i + j) % n] )
                suppressed = 1;
        }

        for( j = -1; (j >= ptInf[i].left_neigh) && (suppressed == 0); j-- )
        {
            int ind = i + j;

            ind = (ind < 0) ? (n + ind) : ind;
            if( sharpness[i] < sharpness[ind] )
                suppressed = 1;
        }

        if( !suppressed )
            CV_WRITE_SEQ_ELEM( i, writer );
    }

    *corners = cvEndWriteSeq( &writer );

    cvFree( &sharpness );
    cvFree( &distance );
    cvFree( &ptInf );

    return status;

  error:
    /* dmax is so big (more than contour diameter)
       that algorithm could become infinite cycle */
    cvFree( &sharpness );
    cvFree( &distance );
    cvFree( &ptInf );

    return CV_BADRANGE_ERR;
}
Esempio n. 7
0
  void Gesture1::trackMarker (IplImage* destImg, CvPoint _r, CvPoint _b, CvPoint _g, CvPoint _y) {
    
    // find tissue box!
    CvPoint* objPoints = objectDetector->detect(destImg);

    // draw
    world->Step(1.0F/6.0F, 10, 10);
    cvLine(destImg, cvPoint(0,HEIGHT), cvPoint(1000,HEIGHT), CV_RGB(0,255,0), 3);
    for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) {
      //printf("**draw body\n");
      Box2DData* userData = (Box2DData*)b->GetUserData();
      if (userData != NULL) {
        if (strcmp(userData->type, "Circle") == 0) {
          //b2Vec2 v = b->GetWorldCenter();
          b2Vec2 v = b->GetPosition();
          //printf("** x=%f y=%f r=%f\n", v.x, v.y, userData->radius);
          CvPoint center = cvPoint(v.x*WORLD_SCALE, v.y*WORLD_SCALE);
          cvCircle(destImg, center, userData->radius*WORLD_SCALE, CV_RGB(255,0,0), -1);
        } else if (strcmp(userData->type, "Box") == 0) {
          world->DestroyBody(b);
        }
      }      
    }
    if (objPoints != NULL) {
      printf("construct body\n");
      b2PolygonShape cs;
      b2Vec2 vertices[4] = {
        b2Vec2((float)(objPoints[0].x)/WORLD_SCALE, (float)(objPoints[0].y)/WORLD_SCALE),
        b2Vec2((float)(objPoints[1].x)/WORLD_SCALE, (float)(objPoints[1].y)/WORLD_SCALE),
        b2Vec2((float)(objPoints[2].x)/WORLD_SCALE, (float)(objPoints[2].y)/WORLD_SCALE),
        b2Vec2((float)(objPoints[3].x)/WORLD_SCALE, (float)(objPoints[3].y)/WORLD_SCALE)
      };
      cs.Set(vertices, 4);
      b2BodyDef bd;
      //bd.type = b2_staticBody;
      Box2DData* obj = new Box2DData();
      strcpy(obj->type, "Box");
      bd.userData = obj;
      b2Body* body1 = world->CreateBody(&bd);
      body1->CreateFixture(&cs, 0.0f);
    }

    if (_r.x < 0) return;
    Point2D r = toPoint2D(_r);
    
    // if marker is not moving for a while, reset the path
    int len = path.size();
    if (len > KEEP_MAX) {
      path.erase(path.begin());
    }
    int nearCount = 0;
    int actual = min(KEEP_COUNT, len);
    
    /*
     for(int i=0; i<actual; i++){
     Point2D p = path[len-1-i];
     double d = dist(p, r);
     //printf("dist=%f\n", d);
     if (d < NEAR_THRESHOLD) ++nearCount;
     }
     if (nearCount > (double)actual * DONT_MOVE_THRESHOLD_RATE) {
     // marker is not moving, so clear the path
     printf("cleared\n");
     path.clear();
     }
     */
    
    path.push_back(r);

    // decide if we should recognize
    time_t current;
    time(&current);
    double interval = difftime(current, lastTime);
    printf("interval=%f\n", interval);
    if (interval < INTERVAL_SEC) return;

    len = path.size();
    if (len < 5) return;

    RecognitionResult res = g.recognize(path);
    printf("%s:%f\n", res.name.c_str(), res.score);
    if (res.name == "Circle" && res.score > SCORE_THRESHOLD) {
      printf("##circle detect##\n");
      // convert to vector<Point2D> to CvSeq<CvPoint>
      CvSeqWriter writer;
      CvMemStorage* storage = cvCreateMemStorage(0);
      cvStartWriteSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage, &writer);
      for (int i=0; i<len; i++) {
        CvPoint pt = toCvPoint(path[i]);
        CV_WRITE_SEQ_ELEM(pt, writer);
      }
      CvSeq* seq = cvEndWriteSeq(&writer);
      CvBox2D ellipse = cvFitEllipse2(seq);
      float radius = std::min(ellipse.size.width, ellipse.size.height)/(4.0F*WORLD_SCALE);
      cvEllipseBox(destImg, ellipse, CV_RGB(0,255,255), -1);

      // add Box2D object
      {
        b2CircleShape cs;
        cs.m_radius = radius;
        printf(" x=%f y=%f radius:%f\n", ellipse.center.x/WORLD_SCALE, ellipse.center.y/WORLD_SCALE, radius);
        b2BodyDef bd;
        bd.type = b2_dynamicBody;
        bd.position.Set(ellipse.center.x/WORLD_SCALE, ellipse.center.y/WORLD_SCALE);
        Box2DData* obj = new Box2DData();
        strcpy(obj->type, "Circle");
        obj->radius = radius;
        bd.userData = obj;
        b2Body* body1 = world->CreateBody(&bd);
        b2FixtureDef fixtureDef;
        fixtureDef.shape = &cs;
        fixtureDef.density = 1.0f;
        fixtureDef.friction = 0.3f;
        fixtureDef.restitution = 0.6f;
        body1->CreateFixture(&fixtureDef);
      }

      time(&lastTime);

      //cvEllipseBox(destImg, ellipse, CV_RGB(125,125,255));
    }
  }
Esempio n. 8
0
//makes vertical list of segments for 1 contour
CvSeq* icvCutContourRaster(CvSeq* current, CvMemStorage* storage, IplImage* image /*tmp image*/) {
    //iplSet(image, 0 ); // this can cause double edges if two contours have common edge
    // for example if object is circle with 1 pixel width
    // to remove such problem - remove this iplSet

    //approx contour by single edges
    CvSeqReader reader;
    CvSeqWriter writer;

    int writing = 0;
    cvStartReadSeq(current, &reader, 0);
    //below line just to avoid warning
    cvStartWriteSeq(current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer);

    CvSeq* output = 0;
    CvSeq* tail = 0;

    //first pass through contour - compute number of branches at every point
    int i;
    for (i = 0; i < current->total; i++) {
        CvPoint cur;

        CV_READ_SEQ_ELEM(cur, reader);

        //mark point
        ((uchar*)image->imageData)[image->widthStep * cur.y + cur.x]++;
        assert(((uchar*)image->imageData)[image->widthStep* cur.y + cur.x] != 255);

    }

    //second pass - create separate edges
    for (i = 0; i < current->total; i++) {
        CvPoint cur;

        CV_READ_SEQ_ELEM(cur, reader);

        //get pixel at this point
        uchar flag = image->imageData[image->widthStep * cur.y + cur.x];
        if (flag != 255 && flag < 3) {  //
            if (!writing) {
                cvStartWriteSeq(current->flags, sizeof(CvContour), sizeof(CvPoint), storage, &writer);
                writing = 1 ;
            }

            //mark point
            if (flag < 3) { ((uchar*)image->imageData)[image->widthStep* cur.y + cur.x] = 255; }
            //add it to another seq
            CV_WRITE_SEQ_ELEM(cur, writer);

        } else {
            //exclude this point from contour
            if (writing) {
                CvSeq* newseq = cvEndWriteSeq(&writer);
                writing = 0;

                if (tail) {
                    tail->v_next = newseq;
                    newseq->v_prev = tail;
                    tail = newseq;
                } else {
                    output = tail = newseq;
                }
            }
        }
    }


    if (writing) {   //if were not self intersections
        CvSeq* newseq = cvEndWriteSeq(&writer);
        writing = 0;

        if (tail) {
            tail->v_next = newseq;
            newseq->v_prev = tail;
            tail = newseq;
        } else {
            output = tail = newseq;
        }
    }


    return output;

}
Esempio n. 9
0
static int fmaConvexHullContour(void* prm)
{ 
    long lErrors = 0;     
    
    static int  read_param = 0;
    int i,j;
    
    CvRect rect;
   
    int minx = 1000000, maxx = -10000;
    int miny = 1000000, maxy = -10000;
    long lParam = (long)prm;

    CvPoint* points;
    CvPoint** pointers;
    
    CvSeqWriter writer;
    CvSeqReader reader;

    CvSeq* contour;
    CvSeq* hull = NULL;
    CvMemStorage* storage;

    if(!read_param)
    {
        read_param=1;
        
        /* Reading test-parameters */
        trslRead( &lNumPoints, "4096", "Maximal number of points" ); 
        trslRead( &lLoopsProp, "100", "Loops" ); 
    }

    storage = cvCreateMemStorage(0);
    cvClearMemStorage( storage );
   
    points =  (CvPoint*)icvAlloc( lNumPoints * sizeof(CvPoint) );
    pointers = (CvPoint**)icvAlloc( lNumPoints * sizeof(CvPoint*) );
    
    for( j = 0; j < lLoopsProp; j++ )
    {
        int numpts;
        /* Allocating points */
                
        cvStartWriteSeq( CV_SEQ_SIMPLE_POLYGON , sizeof(CvSeq),
                                sizeof(CvPoint), storage, &writer );

        ats1iInitRandom( 5, lNumPoints, &numpts, 1 );
        
        /* init points */
        ats1iInitRandom( 5, 1024, &lScreenSize, 1 );
        
        for( i = 0; i < numpts ; i++ )
        {
            CvPoint pt;
            ats1iInitRandom( 0, lScreenSize, (int*)&pt, 2 );
            CV_WRITE_SEQ_ELEM( pt, writer );
        
            minx = MIN(pt.x, minx );
            maxx = MAX(pt.x, maxx );
            miny = MIN(pt.y, miny );
            maxy = MAX(pt.y, maxy );  
        }
        contour = cvEndWriteSeq( &writer );

        rect.x = minx;
        rect.y = miny;
        rect.width = maxx- minx + 1;
        rect.height = maxy- miny + 1;
    
        switch (lParam)
        {
        case APPROX:
            hull = cvContourConvexHullApprox( contour, 1, CV_COUNTER_CLOCKWISE,
                                                    storage );   
            break;
        case EXACT:
            hull = cvContourConvexHull( contour,CV_COUNTER_CLOCKWISE,
                                                    storage );   
            break;
        
        }/*switch */

        /* check errors */
        
        cvStartReadSeq( contour, &reader, 0 );
        for( i = 0; i < contour->total; i++ )
        {      
            CV_READ_SEQ_ELEM( points[i], reader );
        }
        cvStartReadSeq( hull, &reader, 0 );
        for( i = 0; i < hull->total; i++ )
        {      
            CV_READ_SEQ_ELEM( pointers[i], reader );
            
        }

        cvClearMemStorage( storage );

        lErrors += atsCheckConvexHullP( points, contour->total, pointers, hull->total,
                                       CV_COUNTER_CLOCKWISE );
        
        
    } /* for */

    icvFree(&points);
    icvFree(&pointers);
    cvReleaseMemStorage(&storage);
    
   if( lErrors == 0 ) return trsResult( TRS_OK, "No errors fixed for this test" );
   else return trsResult( TRS_FAIL, "Total fixed %d errors", lErrors );

}