cvmorphcontours.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 856 行 · 第 1/2 页

SVN-BASE
856
字号
    w1 = W[i-1][j-1].w_east + _cvBendingWork(&edges1[i-2],
                                            &edges1[i-1],                                           
                                            /*&null_edge*/&small_edge,
                                            &edges2[j-1]/*,
                                            &edges2[j-2]*/);

    w2 = W[i-1][j-1].w_southeast + _cvBendingWork(  &edges1[i-2],
                                                    &edges1[i-1],
                                                    &edges2[j-2],
                                                    &edges2[j-1]/*,
                                                    NULL*/);

    small_edge.x = NULL_EDGE*edges2[j-2].x;
    small_edge.y = NULL_EDGE*edges2[j-2].y;

    w3 = W[i-1][j-1].w_south + _cvBendingWork(  /*&null_edge*/&small_edge,
                                                &edges1[i-1],                                           
                                                &edges2[j-2],
                                                &edges2[j-1]/*,
                                                &edges1[i-2]*/);

    if( w1<w2 )
    {
        if(w1<w3)
        {
            W[i][j].w_southeast = w1 + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );
            W[i][j].path_se = PATH_TO_E;
        }
        else
        {
            W[i][j].w_southeast = w3 + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );
            W[i][j].path_se = 3;
        }
    }
    else
    {
        if( w2<w3)
        {
            W[i][j].w_southeast = w2 + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );
            W[i][j].path_se = PATH_TO_SE;
        }
        else
        {
            W[i][j].w_southeast = w3 + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );
            W[i][j].path_se = 3;
        }
    }
}


//////////////////////////////////////////////////////////////////////////////////////
void _cvWorkSouth(int i, int j, _CvWork** W, CvPoint2D32f* edges1, CvPoint2D32f* edges2)
{
    double w1,w2;
    CvPoint2D32f small_edge;

    //W[i,j].w_south

    small_edge.x = NULL_EDGE*edges2[j-1].x;
    small_edge.y = NULL_EDGE*edges2[j-1].y;

    w1 = W[i][j-1].w_southeast + _cvBendingWork(&edges1[i-1],
                                                /*&null_edge*/&small_edge,
                                                &edges2[j-2],
                                                &edges2[j-1]/*,
                                                &edges1[i]*/);

    w2 = W[i][j-1].w_south /*+ _cvBendingWork(  &null_edge ,
                                            &null_edge,
                                            &edges2[j-2],
                                            &edges2[j-1],
                                            NULL)*/;

    if( w1<w2 )
    {
        W[i][j].w_south = w1 + _cvStretchingWork( &null_edge, &edges2[j-1] );
        W[i][j].path_s = PATH_TO_SE;
    }
    else
    {
        W[i][j].w_south = w2 + _cvStretchingWork( &null_edge, &edges2[j-1] );
        W[i][j].path_s = 3;
    }
}

//===================================================
CvPoint2D32f Q(CvPoint2D32f q0,CvPoint2D32f q1,CvPoint2D32f q2,double t)
{
    CvPoint2D32f q;

    q.x = (float)(q0.x*(1-t)*(1-t) + 2*q1.x*t*(1-t) + q2.x*t*t);
    q.y = (float)(q0.y*(1-t)*(1-t) + 2*q1.y*t*(1-t) + q2.y*t*t);

    return q;       
}

double angle(CvPoint2D32f A, CvPoint2D32f B)
{
    return acos( (A.x*B.x + A.y*B.y)/sqrt( (double)(A.x*A.x + A.y*A.y)*(B.x*B.x + B.y*B.y) ) );
}

/***************************************************************************************\
*
*   This function compute intermediate polygon between contour1 and contour2
*
*   Correspondence between points of contours specify by corr
*
*   param = [0,1];  0 correspondence to contour1, 1 - contour2
*
\***************************************************************************************/
CvSeq* icvBlendContours(CvSeq* contour1, 
                        CvSeq* contour2,
                        CvSeq* corr,
                        double param,
                        CvMemStorage* storage)
{
    int j;
    
    CvSeqWriter writer01;
    CvSeqReader reader01;

    int Ni,Nj;              // size of contours
    int i;                  // counter

    CvPoint* point1;        // array of first contour point
    CvPoint* point2;        // array of second contour point

    CvPoint point_output;   // intermediate storage of ouput point

    int corr_point;

    // Create output sequence.
    CvSeq* output = cvCreateSeq(0,                      
                                sizeof(CvSeq),
                                sizeof(CvPoint),
                                storage );

    // Find size of contours.
    Ni = contour1->total + 1;
    Nj = contour2->total + 1;

    point1 = (CvPoint* )malloc( Ni*sizeof(CvPoint) );
    point2 = (CvPoint* )malloc( Nj*sizeof(CvPoint) );

    // Initialize arrays of point 
    cvCvtSeqToArray( contour1, point1, CV_WHOLE_SEQ );
    cvCvtSeqToArray( contour2, point2, CV_WHOLE_SEQ );

    // First and last point mast be equal.
    point1[Ni-1] = point1[0];
    point2[Nj-1] = point2[0];

    // Initializes process of writing to sequence.
    cvStartAppendToSeq( output, &writer01);

    i = Ni-1; //correspondence to points of contour1
    for( ; corr; corr = corr->h_next )
    {       
        //Initializes process of sequential reading from sequence
        cvStartReadSeq( corr, &reader01, 0 );

        for(j=0; j < corr->total; j++)
        {
            // Read element from sequence.
            CV_READ_SEQ_ELEM( corr_point, reader01 );

            // Compute point of intermediate polygon.
            point_output.x = cvRound(point1[i].x + param*( point2[corr_point].x - point1[i].x ));
            point_output.y = cvRound(point1[i].y + param*( point2[corr_point].y - point1[i].y ));
            
            // Write element to sequence.
            CV_WRITE_SEQ_ELEM( point_output, writer01 );
        }
        i--;
    }
    // Updates sequence header.
    cvFlushSeqWriter( &writer01 );
    
    return output;
}

/**************************************************************************************************
*
*
*
*
*
*
*
*
*
*
**************************************************************************************************/


void icvCalcContoursCorrespondence(CvSeq* contour1, 
                                   CvSeq* contour2, 
                                   CvSeq** corr, 
                                   CvMemStorage* storage)
{
    int i,j;                    // counter of cycles
    int Ni,Nj;                  // size of contours
    _CvWork** W;                // graph for search minimum of work

    CvPoint* point1;            // array of first contour point
    CvPoint* point2;            // array of second contour point
    CvPoint2D32f* edges1;       // array of first contour edge
    CvPoint2D32f* edges2;       // array of second contour edge

    //CvPoint null_edge = {0,0};    //
    CvPoint2D32f small_edge;
    //double inf;                   // infinity

    CvSeq* corr01;
    CvSeqWriter writer;

    char path;                  //

    // Find size of contours
    Ni = contour1->total + 1;
    Nj = contour2->total + 1;

    // Create arrays
    W = (_CvWork**)malloc(sizeof(_CvWork*)*Ni);
    for(i=0; i<Ni; i++)
    {
        W[i] = (_CvWork*)malloc(sizeof(_CvWork)*Nj);
    }

    point1 = (CvPoint* )malloc( Ni*sizeof(CvPoint) );
    point2 = (CvPoint* )malloc( Nj*sizeof(CvPoint) );
    edges1 = (CvPoint2D32f* )malloc( (Ni-1)*sizeof(CvPoint2D32f) );
    edges2 = (CvPoint2D32f* )malloc( (Nj-1)*sizeof(CvPoint2D32f) );

    // Initialize arrays of point 
    cvCvtSeqToArray( contour1, point1, CV_WHOLE_SEQ );
    cvCvtSeqToArray( contour2, point2, CV_WHOLE_SEQ );

    point1[Ni-1] = point1[0];
    point2[Nj-1] = point2[0];

    for(i=0;i<Ni-1;i++)
    {
        edges1[i].x = (float)( point1[i+1].x - point1[i].x );
        edges1[i].y = (float)( point1[i+1].y - point1[i].y );
    };

    for(i=0;i<Nj-1;i++)
    {
        edges2[i].x = (float)( point2[i+1].x - point2[i].x );
        edges2[i].y = (float)( point2[i+1].y - point2[i].y );
    };

    // Find infinity constant 
    //inf=1;
/////////////

//Find min path in graph

/////////////
    W[0][0].w_east      = 0;
    W[0][0].w_south     = 0;
    W[0][0].w_southeast = 0;

    W[1][1].w_southeast = _cvStretchingWork( &edges1[0], &edges2[0] );
    W[1][1].w_east = inf;
    W[1][1].w_south = inf;
    W[1][1].path_se = PATH_TO_SE;

    W[0][1].w_south =  _cvStretchingWork( &null_edge, &edges2[0] );
    W[0][1].path_s = 3;
    W[1][0].w_east =  _cvStretchingWork( &edges2[0], &null_edge );
    W[1][0].path_e = PATH_TO_E;

    for( i=1; i<Ni; i++ )
    {
        W[i][0].w_south     = inf;
        W[i][0].w_southeast = inf;
    }

    for(j=1; j<Nj; j++)
    {
        W[0][j].w_east      = inf;
        W[0][j].w_southeast = inf;
    }

    for(i=2; i<Ni; i++)
    {
        j=0;/////////
        W[i][j].w_east = W[i-1][j].w_east;
        W[i][j].w_east = W[i][j].w_east /*+ 
            _cvBendingWork( &edges1[i-2], &edges1[i-1], &null_edge, &null_edge, NULL )*/;
        W[i][j].w_east = W[i][j].w_east + _cvStretchingWork( &edges2[i-1], &null_edge );
        W[i][j].path_e = PATH_TO_E;
        
        j=1;//////////
        W[i][j].w_south = inf;

        _cvWorkEast (i, j, W, edges1, edges2);

        W[i][j].w_southeast = W[i-1][j-1].w_east;
        W[i][j].w_southeast = W[i][j].w_southeast + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );

        small_edge.x = NULL_EDGE*edges1[i-2].x;
        small_edge.y = NULL_EDGE*edges1[i-2].y;

        W[i][j].w_southeast = W[i][j].w_southeast + 
            _cvBendingWork( &edges1[i-2], &edges1[i-1], /*&null_edge*/&small_edge, &edges2[j-1]/*, &edges2[Nj-2]*/);

        W[i][j].path_se = PATH_TO_E;
    }

    for(j=2; j<Nj; j++)
    {       
        i=0;//////////
        W[i][j].w_south = W[i][j-1].w_south;
        W[i][j].w_south = W[i][j].w_south + _cvStretchingWork( &null_edge, &edges2[j-1] );
        W[i][j].w_south = W[i][j].w_south /*+ 
            _cvBendingWork( &null_edge, &null_edge, &edges2[j-2], &edges2[j-1], NULL )*/;
        W[i][j].path_s = 3;

        i=1;///////////
        W[i][j].w_east= inf;

        _cvWorkSouth(i, j, W, edges1, edges2);

        W[i][j].w_southeast = W[i-1][j-1].w_south;
        W[i][j].w_southeast = W[i][j].w_southeast + _cvStretchingWork( &edges1[i-1], &edges2[j-1] );

        small_edge.x = NULL_EDGE*edges2[j-2].x;
        small_edge.y = NULL_EDGE*edges2[j-2].y;

        W[i][j].w_southeast = W[i][j].w_southeast + 
            _cvBendingWork( /*&null_edge*/&small_edge, &edges1[i-1], &edges2[j-2], &edges2[j-1]/*, &edges1[Ni-2]*/);
        W[i][j].path_se = 3;
    }

    for(i=2; i<Ni; i++)
        for(j=2; j<Nj; j++)
        {
            _cvWorkEast     (i, j, W, edges1, edges2);
            _cvWorkSouthEast(i, j, W, edges1, edges2);
            _cvWorkSouth    (i, j, W, edges1, edges2);
        }

    i=Ni-1;j=Nj-1;

    *corr = cvCreateSeq(0,                    
                        sizeof(CvSeq),        
                        sizeof(int),
                        storage );

    corr01 = *corr;
    cvStartAppendToSeq( corr01, &writer );
    if( W[i][j].w_east > W[i][j].w_southeast )
        {
            if( W[i][j].w_southeast > W[i][j].w_south )
            {
                path = 3;
            }
            else
            {
                path = PATH_TO_SE;
            }
        }
        else
        {
            if( W[i][j].w_east < W[i][j].w_south )
            {
                path = PATH_TO_E;
            }
            else
            {
                path = 3;
            }
        }
    do
    {
        CV_WRITE_SEQ_ELEM( j, writer );

        switch( path ) 
        {
        case PATH_TO_E:
            path = W[i][j].path_e;
            i--;
            cvFlushSeqWriter( &writer );
            corr01->h_next = cvCreateSeq(   0,                    
                                            sizeof(CvSeq),        
                                            sizeof(int),
                                            storage );
            corr01 = corr01->h_next;
            cvStartAppendToSeq( corr01, &writer );
            break;
        
        case PATH_TO_SE:
            path = W[i][j].path_se;
            j--; i--;
            cvFlushSeqWriter( &writer );
            corr01->h_next = cvCreateSeq(   0,                    
                                            sizeof(CvSeq),        
                                            sizeof(int),
                                            storage );
            corr01 = corr01->h_next;
            cvStartAppendToSeq( corr01, &writer );
            break;

        case 3:
            path = W[i][j].path_s;
            j--;
            break;
        }

    } while( (i>=0) && (j>=0) );
    cvFlushSeqWriter( &writer );

    // Free memory
    for(i=1;i<Ni;i++)
    {
        free(W[i]);
    }
    free(W);
    free(point1);
    free(point2);
    free(edges1);
    free(edges2);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?