cvshapedescr.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 1,147 行 · 第 1/3 页
SVN-BASE
1,147 行
ptfl.y = (float)((CvPoint*)reader.ptr)->y;
}
else
{
ptfl = *(CvPoint2D32f*)reader.ptr;
}
CV_NEXT_SEQ_ELEM( sequence->elem_size, reader );
if( !icvIsPtInCircle( ptfl, center, radius ))
{
pts[3] = ptfl;
break;
}
}
if( i == count )
break;
}
__END__;
*_center = center;
*_radius = radius;
}
/* area of a whole sequence */
static CvStatus
icvContourArea( const CvSeq* contour, double *area )
{
if( contour->total )
{
CvSeqReader reader;
int lpt = contour->total;
double a00 = 0, xi_1, yi_1;
int is_float = CV_SEQ_ELTYPE(contour) == CV_32FC2;
cvStartReadSeq( contour, &reader, 0 );
if( !is_float )
{
xi_1 = ((CvPoint*)(reader.ptr))->x;
yi_1 = ((CvPoint*)(reader.ptr))->y;
}
else
{
xi_1 = ((CvPoint2D32f*)(reader.ptr))->x;
yi_1 = ((CvPoint2D32f*)(reader.ptr))->y;
}
CV_NEXT_SEQ_ELEM( contour->elem_size, reader );
while( lpt-- > 0 )
{
double dxy, xi, yi;
if( !is_float )
{
xi = ((CvPoint*)(reader.ptr))->x;
yi = ((CvPoint*)(reader.ptr))->y;
}
else
{
xi = ((CvPoint2D32f*)(reader.ptr))->x;
yi = ((CvPoint2D32f*)(reader.ptr))->y;
}
CV_NEXT_SEQ_ELEM( contour->elem_size, reader );
dxy = xi_1 * yi - xi * yi_1;
a00 += dxy;
xi_1 = xi;
yi_1 = yi;
}
*area = a00 * 0.5;
}
else
*area = 0;
return CV_OK;
}
/****************************************************************************************\
copy data from one buffer to other buffer
\****************************************************************************************/
CvStatus
icvMemCopy( double **buf1, double **buf2, double **buf3, int *b_max )
{
int bb;
if( *buf1 == NULL && *buf2 == NULL || *buf3 == NULL )
return CV_NULLPTR_ERR;
bb = *b_max;
if( *buf2 == NULL )
{
*b_max = 2 * (*b_max);
*buf2 = (double *) icvAlloc( (*b_max) * sizeof( double ));
if( *buf2 == NULL )
return CV_OUTOFMEM_ERR;
memcpy( *buf2, *buf3, bb * sizeof( double ));
*buf3 = *buf2;
icvFree( &(*buf1) );
*buf1 = NULL;
}
else
{
*b_max = 2 * (*b_max);
*buf1 = (double *) icvAlloc( (*b_max) * sizeof( double ));
if( *buf1 == NULL )
return CV_OUTOFMEM_ERR;
memcpy( *buf1, *buf3, bb * sizeof( double ));
*buf3 = *buf1;
icvFree( &(*buf2) );
*buf2 = NULL;
}
return CV_OK;
}
/* area of a contour sector */
static CvStatus icvContourSecArea( CvSeq * contour, CvSlice slice, double *area )
{
CvPoint pt; /* pointer to points */
CvPoint pt_s, pt_e; /* first and last points */
CvSeqReader reader; /* points reader of contour */
int p_max = 2, p_ind;
int lpt, flag, i;
double a00; /* unnormalized moments m00 */
double xi, yi, xi_1, yi_1, x0, y0, dxy, sk, sk1, t;
double x_s, y_s, nx, ny, dx, dy, du, dv;
double eps = 1.e-5;
double *p_are1, *p_are2, *p_are;
assert( contour != NULL );
if( contour == NULL )
return CV_NULLPTR_ERR;
if( !CV_IS_SEQ_POLYGON( contour ))
return CV_BADFLAG_ERR;
lpt = icvSliceLength( slice, contour );
/*if( n2 >= n1 )
lpt = n2 - n1 + 1;
else
lpt = contour->total - n1 + n2 + 1;*/
if( contour->total && lpt > 2 )
{
a00 = x0 = y0 = xi_1 = yi_1 = 0;
sk1 = 0;
flag = 0;
dxy = 0;
p_are1 = (double *) icvAlloc( p_max * sizeof( double ));
if( p_are1 == NULL )
return CV_OUTOFMEM_ERR;
p_are = p_are1;
p_are2 = NULL;
cvStartReadSeq( contour, &reader, 0 );
cvSetSeqReaderPos( &reader, slice.startIndex );
CV_READ_SEQ_ELEM( pt_s, reader );
p_ind = 0;
cvSetSeqReaderPos( &reader, slice.endIndex );
CV_READ_SEQ_ELEM( pt_e, reader );
/* normal coefficients */
nx = pt_s.y - pt_e.y;
ny = pt_e.x - pt_s.x;
cvSetSeqReaderPos( &reader, slice.startIndex );
while( lpt-- > 0 )
{
CV_READ_SEQ_ELEM( pt, reader );
if( flag == 0 )
{
xi_1 = (double) pt.x;
yi_1 = (double) pt.y;
x0 = xi_1;
y0 = yi_1;
sk1 = 0;
flag = 1;
}
else
{
xi = (double) pt.x;
yi = (double) pt.y;
/**************** edges intersection examination **************************/
sk = nx * (xi - pt_s.x) + ny * (yi - pt_s.y);
if( fabs( sk ) < eps && lpt > 0 || sk * sk1 < -eps )
{
if( fabs( sk ) < eps )
{
dxy = xi_1 * yi - xi * yi_1;
a00 = a00 + dxy;
dxy = xi * y0 - x0 * yi;
a00 = a00 + dxy;
if( p_ind >= p_max )
icvMemCopy( &p_are1, &p_are2, &p_are, &p_max );
p_are[p_ind] = a00 / 2.;
p_ind++;
a00 = 0;
sk1 = 0;
x0 = xi;
y0 = yi;
dxy = 0;
}
else
{
/* define intersection point */
dv = yi - yi_1;
du = xi - xi_1;
dx = ny;
dy = -nx;
if( fabs( du ) > eps )
t = ((yi_1 - pt_s.y) * du + dv * (pt_s.x - xi_1)) /
(du * dy - dx * dv);
else
t = (xi_1 - pt_s.x) / dx;
if( t > eps && t < 1 - eps )
{
x_s = pt_s.x + t * dx;
y_s = pt_s.y + t * dy;
dxy = xi_1 * y_s - x_s * yi_1;
a00 += dxy;
dxy = x_s * y0 - x0 * y_s;
a00 += dxy;
if( p_ind >= p_max )
icvMemCopy( &p_are1, &p_are2, &p_are, &p_max );
p_are[p_ind] = a00 / 2.;
p_ind++;
a00 = 0;
sk1 = 0;
x0 = x_s;
y0 = y_s;
dxy = x_s * yi - xi * y_s;
}
}
}
else
dxy = xi_1 * yi - xi * yi_1;
a00 += dxy;
xi_1 = xi;
yi_1 = yi;
sk1 = sk;
}
}
xi = x0;
yi = y0;
dxy = xi_1 * yi - xi * yi_1;
a00 += dxy;
if( p_ind >= p_max )
icvMemCopy( &p_are1, &p_are2, &p_are, &p_max );
p_are[p_ind] = a00 / 2.;
p_ind++;
/* common area calculation */
*area = 0;
for( i = 0; i < p_ind; i++ )
(*area) += fabs( p_are[i] );
if( p_are1 != NULL )
icvFree( &p_are1 );
else if( p_are2 != NULL )
icvFree( &p_are2 );
return CV_OK;
}
else
return CV_BADSIZE_ERR;
}
/* external contour area function */
CV_IMPL double
cvContourArea( const void *array, CvSlice slice )
{
double area = 0;
CV_FUNCNAME( "cvContourArea" );
__BEGIN__;
CvContour contour_header;
CvSeq* contour = 0;
CvSeqBlock block;
if( CV_IS_SEQ( array ))
{
contour = (CvSeq*)array;
if( !CV_IS_SEQ_POLYLINE( contour ))
CV_ERROR( CV_StsBadArg, "Unsupported sequence type" );
}
else
{
CV_CALL( contour = icvPointSeqFromMat(
CV_SEQ_KIND_CURVE, array, &contour_header, &block ));
}
if( icvSliceLength( slice, contour ) == contour->total )
{
IPPI_CALL( icvContourArea( contour, &area ));
}
else
{
if( CV_SEQ_ELTYPE( contour ) != CV_32SC2 )
CV_ERROR( CV_StsUnsupportedFormat,
"Only curves with integer coordinates are supported in case of contour slice" );
IPPI_CALL( icvContourSecArea( contour, slice, &area ));
}
__END__;
return area;
}
/* for now this function works bad with singular cases
You can see in the code, that when some troubles with
matrices or some variables occur -
box filled with zero values is returned.
However in general function works fine.
*/
static CvStatus icvFitEllipse_32f( CvSeq* points, CvBox2D* box )
{
CvStatus status = CV_OK;
CvStatus status1;
float u[6];
CvMatr32f D = 0;
float S[36]; /* S = D' * D */
float C[36];
float INVQ[36];
/* transposed eigenvectors */
float INVEIGV[36];
/* auxulary matrices */
float TMP1[36];
float TMP2[36];
int i, index = -1;
float eigenvalues[6];
float a, b, c, d, e, f;
float offx, offy;
float *matr;
int n = points->total;
CvSeqReader reader;
int is_float = CV_SEQ_ELTYPE(points) == CV_32FC2;
/* create matrix D of input points */
D = icvCreateMatrix_32f( 6, n );
offx = offy = 0;
cvStartReadSeq( points, &reader );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?