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 + -
显示快捷键?