📄 cvrotcalipers.cpp
字号:
switch (mode)
{
case CV_CALIPERS_MAXHEIGHT:
{
/* now main element lies on edge alligned to calipers side */
/* find opposite element i.e. transform */
/* 0->2, 1->3, 2->0, 3->1 */
int opposite_el = main_element ^ 2;
float dx = points[seq[opposite_el]].x - points[seq[main_element]].x;
float dy = points[seq[opposite_el]].y - points[seq[main_element]].y;
float dist;
if( main_element & 1 )
dist = (float)fabs(dx * base_a + dy * base_b);
else
dist = (float)fabs(dx * (-base_b) + dy * base_a);
if( dist > max_dist )
max_dist = dist;
break;
}
case CV_CALIPERS_MINAREARECT:
/* find area of rectangle */
{
float height;
float area;
/* find vector left-right */
float dx = points[seq[1]].x - points[seq[3]].x;
float dy = points[seq[1]].y - points[seq[3]].y;
/* dotproduct */
float width = dx * base_a + dy * base_b;
/* find vector left-right */
dx = points[seq[2]].x - points[seq[0]].x;
dy = points[seq[2]].y - points[seq[0]].y;
/* dotproduct */
height = -dx * base_b + dy * base_a;
area = width * height;
if( area <= minarea )
{
float *buf = (float *) buffer;
minarea = area;
/* leftist point */
((int *) buf)[0] = seq[3];
buf[1] = base_a;
buf[2] = width;
buf[3] = base_b;
buf[4] = height;
/* bottom point */
((int *) buf)[5] = seq[0];
buf[6] = area;
}
break;
}
} /*switch */
} /* for */
switch (mode)
{
case CV_CALIPERS_MINAREARECT:
{
float *buf = (float *) buffer;
float A1 = buf[1];
float B1 = buf[3];
float A2 = -buf[3];
float B2 = buf[1];
float C1 = A1 * points[((int *) buf)[0]].x + points[((int *) buf)[0]].y * B1;
float C2 = A2 * points[((int *) buf)[5]].x + points[((int *) buf)[5]].y * B2;
float idet = 1.f / (A1 * B2 - A2 * B1);
float px = (C1 * B2 - C2 * B1) * idet;
float py = (A1 * C2 - A2 * C1) * idet;
out[0] = px;
out[1] = py;
out[2] = A1 * buf[2];
out[3] = B1 * buf[2];
out[4] = A2 * buf[4];
out[5] = B2 * buf[4];
}
break;
case CV_CALIPERS_MAXHEIGHT:
{
out[0] = max_dist;
}
break;
}
cvFree( &vect );
cvFree( &inv_vect_length );
}
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -