Beispiel #1
0
CV_IMPL CvSeq* cvPointSeqFromMat( int seq_kind, const CvArr* arr,
                                  CvContour* contour_header, CvSeqBlock* block )
{
    CV_Assert( arr != 0 && contour_header != 0 && block != 0 );

    int eltype;
    CvMat* mat = (CvMat*)arr;
    
    if( !CV_IS_MAT( mat ))
        CV_Error( CV_StsBadArg, "Input array is not a valid matrix" ); 

    eltype = CV_MAT_TYPE( mat->type );
    if( eltype != CV_32SC2 && eltype != CV_32FC2 )
        CV_Error( CV_StsUnsupportedFormat,
        "The matrix can not be converted to point sequence because of "
        "inappropriate element type" );

    if( (mat->width != 1 && mat->height != 1) || !CV_IS_MAT_CONT(mat->type))
        CV_Error( CV_StsBadArg,
        "The matrix converted to point sequence must be "
        "1-dimensional and continuous" );

    cvMakeSeqHeaderForArray(
            (seq_kind & (CV_SEQ_KIND_MASK|CV_SEQ_FLAG_CLOSED)) | eltype,
            sizeof(CvContour), CV_ELEM_SIZE(eltype), mat->data.ptr,
            mat->width*mat->height, (CvSeq*)contour_header, block );

    return (CvSeq*)contour_header;
}
CV_IMPL void
cvFitLine( const CvArr* array, int dist, double param,
           double reps, double aeps, float *line )
{
    cv::AutoBuffer<schar> buffer;

    schar* points = 0;
    union { CvContour contour; CvSeq seq; } header;
    CvSeqBlock block;
    CvSeq* ptseq = (CvSeq*)array;
    int type;

    if( !line )
        CV_Error( CV_StsNullPtr, "NULL pointer to line parameters" );

    if( CV_IS_SEQ(ptseq) )
    {
        type = CV_SEQ_ELTYPE(ptseq);
        if( ptseq->total == 0 )
            CV_Error( CV_StsBadSize, "The sequence has no points" );
        if( (type!=CV_32FC2 && type!=CV_32FC3 && type!=CV_32SC2 && type!=CV_32SC3) ||
            CV_ELEM_SIZE(type) != ptseq->elem_size )
            CV_Error( CV_StsUnsupportedFormat,
                "Input sequence must consist of 2d points or 3d points" );
    }
    else
    {
        CvMat* mat = (CvMat*)array;
        type = CV_MAT_TYPE(mat->type);
        if( !CV_IS_MAT(mat))
            CV_Error( CV_StsBadArg, "Input array is not a sequence nor matrix" );

        if( !CV_IS_MAT_CONT(mat->type) ||
            (type!=CV_32FC2 && type!=CV_32FC3 && type!=CV_32SC2 && type!=CV_32SC3) ||
            (mat->width != 1 && mat->height != 1))
            CV_Error( CV_StsBadArg,
            "Input array must be 1d continuous array of 2d or 3d points" );

        ptseq = cvMakeSeqHeaderForArray(
            CV_SEQ_KIND_GENERIC|type, sizeof(CvContour), CV_ELEM_SIZE(type), mat->data.ptr,
            mat->width + mat->height - 1, &header.seq, &block );
    }

    if( reps < 0 || aeps < 0 )
        CV_Error( CV_StsOutOfRange, "Both reps and aeps must be non-negative" );

    if( CV_MAT_DEPTH(type) == CV_32F && ptseq->first->next == ptseq->first )
    {
        /* no need to copy data in this case */
        points = ptseq->first->data;
    }
    else
    {
        buffer.allocate(ptseq->total*CV_ELEM_SIZE(type));
        points = buffer;
        cvCvtSeqToArray( ptseq, points, CV_WHOLE_SEQ );

        if( CV_MAT_DEPTH(type) != CV_32F )
        {
            int i, total = ptseq->total*CV_MAT_CN(type);
            assert( CV_MAT_DEPTH(type) == CV_32S );

            for( i = 0; i < total; i++ )
                ((float*)points)[i] = (float)((int*)points)[i];
        }
    }

    if( dist == CV_DIST_USER )
        CV_Error( CV_StsBadArg, "User-defined distance is not allowed" );

    if( CV_MAT_CN(type) == 2 )
    {
        IPPI_CALL( icvFitLine2D( (CvPoint2D32f*)points, ptseq->total,
                                 dist, (float)param, (float)reps, (float)aeps, line ));
    }
    else
    {
        IPPI_CALL( icvFitLine3D( (CvPoint3D32f*)points, ptseq->total,
                                 dist, (float)param, (float)reps, (float)aeps, line ));
    }
}
Beispiel #3
0
/* it must have more than 3 points  */
CV_IMPL CvSeq*
cvConvexityDefects( const CvArr* array,
                    const CvArr* hullarray,
                    CvMemStorage* storage )
{
    CvSeq* defects = 0;

    CV_FUNCNAME( "cvConvexityDefects" );

    __BEGIN__;

    int i, index;
    CvPoint* hull_cur;

    /* is orientation of hull different from contour one */
    int rev_orientation;

    CvContour contour_header;
    union { CvContour c; CvSeq s; } hull_header;
    CvSeqBlock block, hullblock;
    CvSeq *ptseq = (CvSeq*)array, *hull = (CvSeq*)hullarray;

    CvSeqReader hull_reader;
    CvSeqReader ptseq_reader;
    CvSeqWriter writer;
    int is_index;

    if( CV_IS_SEQ( ptseq ))
    {
        if( !CV_IS_SEQ_POINT_SET( ptseq ))
            CV_ERROR( CV_StsUnsupportedFormat,
                "Input sequence is not a sequence of points" );
        if( !storage )
            storage = ptseq->storage;
    }
    else
    {
        CV_CALL( ptseq = cvPointSeqFromMat(
            CV_SEQ_KIND_GENERIC, array, &contour_header, &block ));
    }

    if( CV_SEQ_ELTYPE( ptseq ) != CV_32SC2 )
        CV_ERROR( CV_StsUnsupportedFormat,
            "Floating-point coordinates are not supported here" );

    if( CV_IS_SEQ( hull ))
    {
        int hulltype = CV_SEQ_ELTYPE( hull );
        if( hulltype != CV_SEQ_ELTYPE_PPOINT && hulltype != CV_SEQ_ELTYPE_INDEX )
            CV_ERROR( CV_StsUnsupportedFormat,
                "Convex hull must represented as a sequence "
                "of indices or sequence of pointers" );
        if( !storage )
            storage = hull->storage;
    }
    else
    {
        CvMat* mat = (CvMat*)hull;

        if( !CV_IS_MAT( hull ))
            CV_ERROR(CV_StsBadArg, "Convex hull is neither sequence nor matrix");

        if( mat->cols != 1 && mat->rows != 1 ||
            !CV_IS_MAT_CONT(mat->type) || CV_MAT_TYPE(mat->type) != CV_32SC1 )
            CV_ERROR( CV_StsBadArg,
            "The matrix should be 1-dimensional and continuous array of int's" );

        if( mat->cols + mat->rows - 1 > ptseq->total )
            CV_ERROR( CV_StsBadSize, "Convex hull is larger than the point sequence" );

        CV_CALL( hull = cvMakeSeqHeaderForArray(
            CV_SEQ_KIND_CURVE|CV_MAT_TYPE(mat->type)|CV_SEQ_FLAG_CLOSED,
            sizeof(CvContour), CV_ELEM_SIZE(mat->type), mat->data.ptr,
            mat->cols + mat->rows - 1, &hull_header.s, &hullblock ));
    }

    is_index = CV_SEQ_ELTYPE(hull) == CV_SEQ_ELTYPE_INDEX;

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

    CV_CALL( defects = cvCreateSeq( CV_SEQ_KIND_GENERIC, sizeof(CvSeq),
                                    sizeof(CvConvexityDefect), storage ));

    if( ptseq->total < 4 || hull->total < 3)
    {
        //CV_ERROR( CV_StsBadSize,
        //    "point seq size must be >= 4, convex hull size must be >= 3" );
        EXIT;
    }

    /* recognize co-orientation of ptseq and its hull */
    {
        int sign = 0;
        int index1, index2, index3;

        if( !is_index )
        {
            CvPoint* pos = *CV_SEQ_ELEM( hull, CvPoint*, 0 );
            CV_CALL( index1 = cvSeqElemIdx( ptseq, pos ));

            pos = *CV_SEQ_ELEM( hull, CvPoint*, 1 );
            CV_CALL( index2 = cvSeqElemIdx( ptseq, pos ));

            pos = *CV_SEQ_ELEM( hull, CvPoint*, 2 );
            CV_CALL( index3 = cvSeqElemIdx( ptseq, pos ));
        }
        else
        {
Beispiel #4
0
CV_IMPL CvSeq*
cvConvexHull2( const CvArr* array, void* hull_storage,
               int orientation, int return_points )
{
    union { CvContour* c; CvSeq* s; } hull;
    CvPoint** pointer = 0;
    CvPoint2D32f** pointerf = 0;
    int* stack = 0;

    CV_FUNCNAME( "cvConvexHull2" );

    hull.s = 0;

    __BEGIN__;

    CvMat* mat = 0;
    CvSeqReader reader;
    CvSeqWriter writer;
    CvContour contour_header;
    union { CvContour c; CvSeq s; } hull_header;
    CvSeqBlock block, hullblock;
    CvSeq* ptseq = 0;
    CvSeq* hullseq = 0;
    int is_float;
    int* t_stack;
    int t_count;
    int i, miny_ind = 0, maxy_ind = 0, total;
    int hulltype;
    int stop_idx;
    sklansky_func sklansky;

    if( CV_IS_SEQ( array ))
    {
        ptseq = (CvSeq*)array;
        if( !CV_IS_SEQ_POINT_SET( ptseq ))
            CV_ERROR( CV_StsBadArg, "Unsupported sequence type" );
        if( hull_storage == 0 )
            hull_storage = ptseq->storage;
    }
    else
    {
        CV_CALL( ptseq = cvPointSeqFromMat(
            CV_SEQ_KIND_GENERIC, array, &contour_header, &block ));
    }

    if( CV_IS_STORAGE( hull_storage ))
    {
        if( return_points )
        {
            CV_CALL( hullseq = cvCreateSeq(
                CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE(ptseq)|
                CV_SEQ_FLAG_CLOSED|CV_SEQ_FLAG_CONVEX,
                sizeof(CvContour), sizeof(CvPoint),(CvMemStorage*)hull_storage ));
        }
        else
        {
            CV_CALL( hullseq = cvCreateSeq(
                CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE_PPOINT|
                CV_SEQ_FLAG_CLOSED|CV_SEQ_FLAG_CONVEX,
                sizeof(CvContour), sizeof(CvPoint*), (CvMemStorage*)hull_storage ));
        }
    }
    else
    {
        if( !CV_IS_MAT( hull_storage ))
            CV_ERROR(CV_StsBadArg, "Destination must be valid memory storage or matrix");

        mat = (CvMat*)hull_storage;

        if( mat->cols != 1 && mat->rows != 1 || !CV_IS_MAT_CONT(mat->type))
            CV_ERROR( CV_StsBadArg,
            "The hull matrix should be continuous and have a single row or a single column" );

        if( mat->cols + mat->rows - 1 < ptseq->total )
            CV_ERROR( CV_StsBadSize, "The hull matrix size might be not enough to fit the hull" );

        if( CV_MAT_TYPE(mat->type) != CV_SEQ_ELTYPE(ptseq) &&
            CV_MAT_TYPE(mat->type) != CV_32SC1 )
            CV_ERROR( CV_StsUnsupportedFormat,
            "The hull matrix must have the same type as input or 32sC1 (integers)" );

        CV_CALL( hullseq = cvMakeSeqHeaderForArray(
            CV_SEQ_KIND_CURVE|CV_MAT_TYPE(mat->type)|CV_SEQ_FLAG_CLOSED,
            sizeof(contour_header), CV_ELEM_SIZE(mat->type), mat->data.ptr,
            mat->cols + mat->rows - 1, &hull_header.s, &hullblock ));

        cvClearSeq( hullseq );
    }

    total = ptseq->total;
    if( total == 0 )
    {
        if( mat )
            CV_ERROR( CV_StsBadSize,
            "Point sequence can not be empty if the output is matrix" );
        EXIT;
    }

    cvStartAppendToSeq( hullseq, &writer );

    is_float = CV_SEQ_ELTYPE(ptseq) == CV_32FC2;
    hulltype = CV_SEQ_ELTYPE(hullseq);
    sklansky = !is_float ? (sklansky_func)icvSklansky_32s :
                           (sklansky_func)icvSklansky_32f;

    CV_CALL( pointer = (CvPoint**)cvAlloc( ptseq->total*sizeof(pointer[0]) ));
    CV_CALL( stack = (int*)cvAlloc( (ptseq->total + 2)*sizeof(stack[0]) ));
    pointerf = (CvPoint2D32f**)pointer;

    cvStartReadSeq( ptseq, &reader );

    for( i = 0; i < total; i++ )
    {
        pointer[i] = (CvPoint*)reader.ptr;
        CV_NEXT_SEQ_ELEM( ptseq->elem_size, reader );
    }

    // sort the point set by x-coordinate, find min and max y
    if( !is_float )
    {
        icvSortPointsByPointers_32s( pointer, total, 0 );
        for( i = 1; i < total; i++ )
        {
            int y = pointer[i]->y;
            if( pointer[miny_ind]->y > y )
                miny_ind = i;
            if( pointer[maxy_ind]->y < y )
                maxy_ind = i;
        }
    }
    else
    {
        icvSortPointsByPointers_32f( pointerf, total, 0 );
        for( i = 1; i < total; i++ )
        {
            float y = pointerf[i]->y;
            if( pointerf[miny_ind]->y > y )
                miny_ind = i;
            if( pointerf[maxy_ind]->y < y )
                maxy_ind = i;
        }
    }

    if( pointer[0]->x == pointer[total-1]->x &&
        pointer[0]->y == pointer[total-1]->y )
    {
        if( hulltype == CV_SEQ_ELTYPE_PPOINT )
        {
            CV_WRITE_SEQ_ELEM( pointer[0], writer );
        }
        else if( hulltype == CV_SEQ_ELTYPE_INDEX )
        {
            int index = 0;
            CV_WRITE_SEQ_ELEM( index, writer );
        }
        else
        {
            CvPoint pt = pointer[0][0];
            CV_WRITE_SEQ_ELEM( pt, writer );
        }
        goto finish_hull;
    }

    /*upper half */
    {
        int *tl_stack = stack;
        int tl_count = sklansky( pointer, 0, maxy_ind, tl_stack, -1, 1 );
        int *tr_stack = tl_stack + tl_count;
        int tr_count = sklansky( pointer, ptseq->total - 1, maxy_ind, tr_stack, -1, -1 );

        /* gather upper part of convex hull to output */
        if( orientation == CV_COUNTER_CLOCKWISE )
        {
            CV_SWAP( tl_stack, tr_stack, t_stack );
            CV_SWAP( tl_count, tr_count, t_count );
        }

        if( hulltype == CV_SEQ_ELTYPE_PPOINT )
        {
            for( i = 0; i < tl_count - 1; i++ )
                CV_WRITE_SEQ_ELEM( pointer[tl_stack[i]], writer );

            for( i = tr_count - 1; i > 0; i-- )
                CV_WRITE_SEQ_ELEM( pointer[tr_stack[i]], writer );
        }
        else if( hulltype == CV_SEQ_ELTYPE_INDEX )
        {
            CV_CALL( icvCalcAndWritePtIndices( pointer, tl_stack,
                                               0, tl_count-1, ptseq, &writer ));
            CV_CALL( icvCalcAndWritePtIndices( pointer, tr_stack,
                                               tr_count-1, 0, ptseq, &writer ));
        }
        else
        {
            for( i = 0; i < tl_count - 1; i++ )
                CV_WRITE_SEQ_ELEM( pointer[tl_stack[i]][0], writer );

            for( i = tr_count - 1; i > 0; i-- )
                CV_WRITE_SEQ_ELEM( pointer[tr_stack[i]][0], writer );
        }
        stop_idx = tr_count > 2 ? tr_stack[1] : tl_count > 2 ? tl_stack[tl_count - 2] : -1;
    }

    /* lower half */
    {
        int *bl_stack = stack;
        int bl_count = sklansky( pointer, 0, miny_ind, bl_stack, 1, -1 );
        int *br_stack = stack + bl_count;
        int br_count = sklansky( pointer, ptseq->total - 1, miny_ind, br_stack, 1, 1 );

        if( orientation != CV_COUNTER_CLOCKWISE )
        {
            CV_SWAP( bl_stack, br_stack, t_stack );
            CV_SWAP( bl_count, br_count, t_count );
        }

        if( stop_idx >= 0 )
        {
            int check_idx = bl_count > 2 ? bl_stack[1] :
                            bl_count + br_count > 2 ? br_stack[2-bl_count] : -1;
            if( check_idx == stop_idx || check_idx >= 0 &&
                pointer[check_idx]->x == pointer[stop_idx]->x &&
                pointer[check_idx]->y == pointer[stop_idx]->y )
            {
                /* if all the points lie on the same line, then
                   the bottom part of the convex hull is the mirrored top part
                   (except the exteme points).*/
                bl_count = MIN( bl_count, 2 );
                br_count = MIN( br_count, 2 );
            }
        }

        if( hulltype == CV_SEQ_ELTYPE_PPOINT )
        {
            for( i = 0; i < bl_count - 1; i++ )
                CV_WRITE_SEQ_ELEM( pointer[bl_stack[i]], writer );

            for( i = br_count - 1; i > 0; i-- )
                CV_WRITE_SEQ_ELEM( pointer[br_stack[i]], writer );
        }
        else if( hulltype == CV_SEQ_ELTYPE_INDEX )
        {
            CV_CALL( icvCalcAndWritePtIndices( pointer, bl_stack,
                                               0, bl_count-1, ptseq, &writer ));
            CV_CALL( icvCalcAndWritePtIndices( pointer, br_stack,
                                               br_count-1, 0, ptseq, &writer ));
        }
        else
        {
            for( i = 0; i < bl_count - 1; i++ )
                CV_WRITE_SEQ_ELEM( pointer[bl_stack[i]][0], writer );

            for( i = br_count - 1; i > 0; i-- )
                CV_WRITE_SEQ_ELEM( pointer[br_stack[i]][0], writer );
        }
    }

finish_hull:
    CV_CALL( cvEndWriteSeq( &writer ));

    if( mat )
    {
        if( mat->rows > mat->cols )
            mat->rows = hullseq->total;
        else
            mat->cols = hullseq->total;
    }
    else
    {
        hull.s = hullseq;
        hull.c->rect = cvBoundingRect( ptseq,
            ptseq->header_size < (int)sizeof(CvContour) ||
            &ptseq->flags == &contour_header.flags );

        /*if( ptseq != (CvSeq*)&contour_header )
            hullseq->v_prev = ptseq;*/
    }

    __END__;

    cvFree( &pointer );
    cvFree( &stack );

    return hull.s;
}
Beispiel #5
0
CV_IMPL CvSeq*
cvConvexHull2( const CvArr* array, void* hull_storage,
               int orientation, int return_points )
{
    CvMat* mat = 0;
    CvContour contour_header;
    CvSeq hull_header;
    CvSeqBlock block, hullblock;
    CvSeq* ptseq = 0;
    CvSeq* hullseq = 0;

    if( CV_IS_SEQ( array ))
    {
        ptseq = (CvSeq*)array;
        if( !CV_IS_SEQ_POINT_SET( ptseq ))
            CV_Error( CV_StsBadArg, "Unsupported sequence type" );
        if( hull_storage == 0 )
            hull_storage = ptseq->storage;
    }
    else
    {
        ptseq = cvPointSeqFromMat( CV_SEQ_KIND_GENERIC, array, &contour_header, &block );
    }

    bool isStorage = isStorageOrMat(hull_storage);

    if(isStorage)
    {
        if( return_points )
        {
            hullseq = cvCreateSeq(CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE(ptseq)|
                                  CV_SEQ_FLAG_CLOSED|CV_SEQ_FLAG_CONVEX,
                                  sizeof(CvContour), sizeof(CvPoint),(CvMemStorage*)hull_storage );
        }
        else
        {
            hullseq = cvCreateSeq(
                                  CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE_PPOINT|
                                  CV_SEQ_FLAG_CLOSED|CV_SEQ_FLAG_CONVEX,
                                  sizeof(CvContour), sizeof(CvPoint*), (CvMemStorage*)hull_storage );
        }
    }
    else
    {
        mat = (CvMat*)hull_storage;

        if( (mat->cols != 1 && mat->rows != 1) || !CV_IS_MAT_CONT(mat->type))
            CV_Error( CV_StsBadArg,
                     "The hull matrix should be continuous and have a single row or a single column" );

        if( mat->cols + mat->rows - 1 < ptseq->total )
            CV_Error( CV_StsBadSize, "The hull matrix size might be not enough to fit the hull" );

        if( CV_MAT_TYPE(mat->type) != CV_SEQ_ELTYPE(ptseq) &&
           CV_MAT_TYPE(mat->type) != CV_32SC1 )
            CV_Error( CV_StsUnsupportedFormat,
                     "The hull matrix must have the same type as input or 32sC1 (integers)" );

        hullseq = cvMakeSeqHeaderForArray(
                                          CV_SEQ_KIND_CURVE|CV_MAT_TYPE(mat->type)|CV_SEQ_FLAG_CLOSED,
                                          sizeof(hull_header), CV_ELEM_SIZE(mat->type), mat->data.ptr,
                                          mat->cols + mat->rows - 1, &hull_header, &hullblock );
        cvClearSeq( hullseq );
    }

    int hulltype = CV_SEQ_ELTYPE(hullseq);
    int total = ptseq->total;
    if( total == 0 )
    {
        if( !isStorage )
            CV_Error( CV_StsBadSize,
                     "Point sequence can not be empty if the output is matrix" );
        return 0;
    }

    cv::AutoBuffer<double> _ptbuf;
    cv::Mat h0;
    cv::convexHull(cv::cvarrToMat(ptseq, false, false, 0, &_ptbuf), h0,
                   orientation == CV_CLOCKWISE, CV_MAT_CN(hulltype) == 2);


    if( hulltype == CV_SEQ_ELTYPE_PPOINT )
    {
        const int* idx = h0.ptr<int>();
        int ctotal = (int)h0.total();
        for( int i = 0; i < ctotal; i++ )
        {
            void* ptr = cvGetSeqElem(ptseq, idx[i]);
            cvSeqPush( hullseq, &ptr );
        }
    }
    else
        cvSeqPushMulti(hullseq, h0.ptr(), (int)h0.total());

    if (isStorage)
    {
        return hullseq;
    }
    else
    {
        if( mat->rows > mat->cols )
            mat->rows = hullseq->total;
        else
            mat->cols = hullseq->total;
        return 0;
    }
}
static int aMatchContourTrees(void)
{
    CvSeqBlock contour_blk1, contour_blk2;
    CvContour contour_h1, contour_h2;
    CvContourTree *tree1, *tree2;
    CvMemStorage *storage;   /*   storage for contour and tree writing */
    int block_size = 10000;

    CvRandState state;
    double lower, upper;
    int seed;
    float fr;
    int type_seq;
    int method;
    int nPoints1 = 12, nPoints2 = 12;
    int xc,yc,a1 = 10, b1 = 20, a2 = 10, b2 =20, fi = 0;
    int xmin,ymin,xmax,ymax;
    double error_test,rezult, eps_rez = 0.8;
    double pi = 3.1415926;
    double threshold = 1.e-7;
    double threshold2 = 5.;
    int i;
    int code = TRS_OK;

    int width=256,height=256;
    CvPoint *cp1,*cp2;

    /* read tests params */

    if (!trsiRead(&nPoints1,"20","Number of points first contour"))
        return TRS_UNDEF;
    if (!trsiRead(&nPoints2,"20","Number of points second contour"))
        return TRS_UNDEF;

    if(nPoints1>0&&nPoints2>0)
    {
        if (!trsiRead(&a1,"10","first radius of the first elipse"))
            return TRS_UNDEF;
        if (!trsiRead(&b1,"20","second radius of the first elipse"))
            return TRS_UNDEF;
        if (!trsiRead(&a2,"15","first radius of the second elipse"))
            return TRS_UNDEF;
        if (!trsiRead(&b2,"30","second radius of the second elipse"))
            return TRS_UNDEF;
        if (!trsiRead(&fi,"0","second radius of the second elipse"))
            return TRS_UNDEF;

        if (!trsdRead(&upper,"3","noise amplidude"))
            return TRS_UNDEF;

        xc = (int)(width/2.);
        yc = (int)(height/2.);
        xmin = width;
        ymin = height;
        xmax = 0;
        ymax = 0;

        cp1 = (CvPoint*) trsmAlloc(nPoints1*sizeof(CvPoint));
        cp2 = (CvPoint*) trsmAlloc(nPoints2*sizeof(CvPoint));

        for(i=0; i<nPoints1; i++)
        {
            cp1[i].x = (int)(a1*cos(2*pi*i/nPoints1))+xc;
            cp1[i].y = (int)(b1*sin(2*pi*i/nPoints1))+yc;
            if(xmin> cp1[i].x) xmin = cp1[i].x;
            if(xmax< cp1[i].x) xmax = cp1[i].x;
            if(ymin> cp1[i].y) ymin = cp1[i].y;
            if(ymax< cp1[i].y) ymax = cp1[i].y;
        }

        if(xmax>width||xmin<0||ymax>height||ymin<0) return TRS_FAIL;

        lower = -upper;
        /*     upper = 3;*/
        seed = 345753;
        cvRandInit(&state, (float)lower,(float)upper, seed );
        for(i=0; i<nPoints2; i++)
        {
            cvbRand( &state, &fr, 1 );
            cp2[i].x =(int)fr+(int)(a2*cos(2*pi*i/nPoints2)*cos(2*pi*fi/360.))-
                      (int)(b2*sin(2*pi*i/nPoints2)*sin(2*pi*fi/360.))+xc;
            cvbRand( &state, &fr, 1 );
            cp2[i].y =(int)fr+(int)(a2*cos(2*pi*i/nPoints2)*sin(2*pi*fi/360.))+
                      (int)(b2*sin(2*pi*i/nPoints2)*cos(2*pi*fi/360.))+yc;

            if(xmin> cp2[i].x) xmin = cp2[i].x;
            if(xmax< cp2[i].x) xmax = cp2[i].x;
            if(ymin> cp2[i].y) ymin = cp2[i].y;
            if(ymax< cp2[i].y) ymax = cp2[i].y;
        }
        if(xmax>width||xmin<0||ymax>height||ymin<0) return TRS_FAIL;

        /*   contours initialazing */
        type_seq = CV_SEQ_POLYGON;
        cvMakeSeqHeaderForArray( type_seq, sizeof(CvContour), sizeof(CvPoint),
                                 (char*)cp1, nPoints1, (CvSeq*)&contour_h1, &contour_blk1);

        cvMakeSeqHeaderForArray( type_seq, sizeof(CvContour), sizeof(CvPoint),
                                 (char*)cp2, nPoints2, (CvSeq*)&contour_h2, &contour_blk2);

        /*  contour trees created*/
        storage = cvCreateMemStorage( block_size );

        tree1 = cvCreateContourTree ((CvSeq*)&contour_h1, storage, threshold);
        tree2 = cvCreateContourTree ((CvSeq*)&contour_h2, storage, threshold);


        /*  countours matchig */
        error_test = 0.;
        method = 1;

        rezult = cvMatchContourTrees (tree1, tree2, (CvContourTreesMatchMethod)method,threshold2);
        error_test+=rezult;

        if(error_test > eps_rez ) code = TRS_FAIL;
        else code = TRS_OK;

        trsWrite( ATS_CON | ATS_LST | ATS_SUM, "contours matching error_test =%f \n",
                  error_test);

        cvReleaseMemStorage ( &storage );

        trsFree (cp2);
        trsFree (cp1);

    }


    /*    _getch();     */
    return code;
}