Commit dc4d0398 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

converted few more comp. geometry functions to C++

parent c2241dcc
...@@ -52,16 +52,6 @@ CV_INLINE float icvDistanceL2_32f( CvPoint2D32f pt1, CvPoint2D32f pt2 ) ...@@ -52,16 +52,6 @@ CV_INLINE float icvDistanceL2_32f( CvPoint2D32f pt1, CvPoint2D32f pt2 )
} }
int icvIntersectLines( double x1, double dx1, double y1, double dy1,
double x2, double dx2, double y2, double dy2,
double* t2 );
void icvIntersectLines3( double* a0, double* b0, double* c0,
double* a1, double* b1, double* c1,
CvPoint2D32f* point );
/* curvature: 0 - 1-curvature, 1 - k-cosine curvature. */ /* curvature: 0 - 1-curvature, 1 - k-cosine curvature. */
CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size, CvMemStorage* storage, int method ); CvSeq* icvApproximateChainTC89( CvChain* chain, int header_size, CvMemStorage* storage, int method );
......
...@@ -1753,85 +1753,4 @@ void cv::findContours( InputOutputArray _image, OutputArrayOfArrays _contours, ...@@ -1753,85 +1753,4 @@ void cv::findContours( InputOutputArray _image, OutputArrayOfArrays _contours,
findContours(_image, _contours, noArray(), mode, method, offset); findContours(_image, _contours, noArray(), mode, method, offset);
} }
double cv::arcLength( InputArray _curve, bool closed )
{
Mat curve = _curve.getMat();
CV_Assert(curve.checkVector(2) >= 0 && (curve.depth() == CV_32F || curve.depth() == CV_32S));
CvMat _ccurve = curve;
return cvArcLength(&_ccurve, CV_WHOLE_SEQ, closed);
}
cv::Rect cv::boundingRect( InputArray _points )
{
Mat points = _points.getMat();
CV_Assert(points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S));
CvMat _cpoints = points;
return cvBoundingRect(&_cpoints, 0);
}
double cv::contourArea( InputArray _contour, bool oriented )
{
Mat contour = _contour.getMat();
CV_Assert(contour.checkVector(2) >= 0 && (contour.depth() == CV_32F || contour.depth() == CV_32S));
CvMat _ccontour = contour;
return cvContourArea(&_ccontour, CV_WHOLE_SEQ, oriented);
}
cv::RotatedRect cv::minAreaRect( InputArray _points )
{
Mat points = _points.getMat();
CV_Assert(points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S));
CvMat _cpoints = points;
return cvMinAreaRect2(&_cpoints, 0);
}
void cv::minEnclosingCircle( InputArray _points,
Point2f& center, float& radius )
{
Mat points = _points.getMat();
CV_Assert(points.checkVector(2) >= 0 && (points.depth() == CV_32F || points.depth() == CV_32S));
CvMat _cpoints = points;
cvMinEnclosingCircle( &_cpoints, (CvPoint2D32f*)&center, &radius );
}
double cv::matchShapes( InputArray _contour1,
InputArray _contour2,
int method, double parameter )
{
Mat contour1 = _contour1.getMat(), contour2 = _contour2.getMat();
CV_Assert(contour1.checkVector(2) >= 0 && contour2.checkVector(2) >= 0 &&
(contour1.depth() == CV_32F || contour1.depth() == CV_32S) &&
contour1.depth() == contour2.depth());
CvMat c1 = Mat(contour1), c2 = Mat(contour2);
return cvMatchShapes(&c1, &c2, method, parameter);
}
cv::RotatedRect cv::fitEllipse( InputArray _points )
{
Mat points = _points.getMat();
CV_Assert(points.checkVector(2) >= 0 &&
(points.depth() == CV_32F || points.depth() == CV_32S));
CvMat _cpoints = points;
return cvFitEllipse2(&_cpoints);
}
double cv::pointPolygonTest( InputArray _contour,
Point2f pt, bool measureDist )
{
Mat contour = _contour.getMat();
CV_Assert(contour.checkVector(2) >= 0 &&
(contour.depth() == CV_32F || contour.depth() == CV_32S));
CvMat c = Mat(contour);
return cvPointPolygonTest( &c, pt, measureDist );
}
/* End of file. */ /* End of file. */
...@@ -92,97 +92,38 @@ cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] ) ...@@ -92,97 +92,38 @@ cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] )
} }
int double cv::pointPolygonTest( InputArray _contour, Point2f pt, bool measureDist )
icvIntersectLines( double x1, double dx1, double y1, double dy1,
double x2, double dx2, double y2, double dy2, double *t2 )
{
double d = dx1 * dy2 - dx2 * dy1;
int result = -1;
if( d != 0 )
{
*t2 = ((x2 - x1) * dy1 - (y2 - y1) * dx1) / d;
result = 0;
}
return result;
}
void
icvIntersectLines3( double *a0, double *b0, double *c0,
double *a1, double *b1, double *c1, CvPoint2D32f * point )
{
double det = a0[0] * b1[0] - a1[0] * b0[0];
if( det != 0 )
{
det = 1. / det;
point->x = (float) ((b0[0] * c1[0] - b1[0] * c0[0]) * det);
point->y = (float) ((a1[0] * c0[0] - a0[0] * c1[0]) * det);
}
else
{
point->x = point->y = FLT_MAX;
}
}
CV_IMPL double
cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist )
{ {
double result = 0; double result = 0;
Mat contour = _contour.getMat();
int i, total = contour.checkVector(2), counter = 0;
int depth = contour.depth();
CV_Assert( total >= 0 && (depth == CV_32S || depth == CV_32F));
CvSeqBlock block; bool is_float = depth == CV_32F;
CvContour header;
CvSeq* contour = (CvSeq*)_contour;
CvSeqReader reader;
int i, total, counter = 0;
int is_float;
double min_dist_num = FLT_MAX, min_dist_denom = 1; double min_dist_num = FLT_MAX, min_dist_denom = 1;
CvPoint ip = {0,0}; Point ip(cvRound(pt.x), cvRound(pt.y));
if( !CV_IS_SEQ(contour) ) if( total == 0 )
{ return measureDist ? -DBL_MAX : -1;
contour = cvPointSeqFromMat( CV_SEQ_KIND_CURVE + CV_SEQ_FLAG_CLOSED,
_contour, &header, &block );
}
else if( CV_IS_SEQ_POINT_SET(contour) )
{
if( contour->header_size == sizeof(CvContour) && !measure_dist )
{
CvRect r = ((CvContour*)contour)->rect;
if( pt.x < r.x || pt.y < r.y ||
pt.x >= r.x + r.width || pt.y >= r.y + r.height )
return -1;
}
}
else if( CV_IS_SEQ_CHAIN(contour) )
{
CV_Error( CV_StsBadArg,
"Chains are not supported. Convert them to polygonal representation using cvApproxChains()" );
}
else
CV_Error( CV_StsBadArg, "Input contour is neither a valid sequence nor a matrix" );
total = contour->total; const Point* cnt = (const Point*)contour.data;
is_float = CV_SEQ_ELTYPE(contour) == CV_32FC2; const Point2f* cntf = (const Point2f*)cnt;
cvStartReadSeq( contour, &reader, -1 );
if( !is_float && !measure_dist && (ip.x = cvRound(pt.x)) == pt.x && (ip.y = cvRound(pt.y)) == pt.y ) if( !is_float && !measureDist && ip.x == pt.x && ip.y == pt.y )
{ {
// the fastest "pure integer" branch // the fastest "purely integer" branch
CvPoint v0, v; Point v0, v = cnt[total-1];
CV_READ_SEQ_ELEM( v, reader );
for( i = 0; i < total; i++ ) for( i = 0; i < total; i++ )
{ {
int dist; int dist;
v0 = v; v0 = v;
CV_READ_SEQ_ELEM( v, reader ); v = cnt[i];
if( (v0.y <= ip.y && v.y <= ip.y) || if( (v0.y <= ip.y && v.y <= ip.y) ||
(v0.y > ip.y && v.y > ip.y) || (v0.y > ip.y && v.y > ip.y) ||
(v0.x < ip.x && v.x < ip.x) ) (v0.x < ip.x && v.x < ip.x) )
{ {
if( ip.y == v.y && (ip.x == v.x || (ip.y == v0.y && if( ip.y == v.y && (ip.x == v.x || (ip.y == v0.y &&
((v0.x <= ip.x && ip.x <= v.x) || (v.x <= ip.x && ip.x <= v0.x)))) ) ((v0.x <= ip.x && ip.x <= v.x) || (v.x <= ip.x && ip.x <= v0.x)))) )
...@@ -202,38 +143,32 @@ cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist ) ...@@ -202,38 +143,32 @@ cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist )
} }
else else
{ {
CvPoint2D32f v0, v; Point2f v0, v;
CvPoint iv; Point iv;
if( is_float ) if( is_float )
{ {
CV_READ_SEQ_ELEM( v, reader ); v = cntf[total-1];
} }
else else
{ {
CV_READ_SEQ_ELEM( iv, reader ); v = cnt[total-1];
v = cvPointTo32f( iv );
} }
if( !measure_dist ) if( !measureDist )
{ {
for( i = 0; i < total; i++ ) for( i = 0; i < total; i++ )
{ {
double dist; double dist;
v0 = v; v0 = v;
if( is_float ) if( is_float )
{ v = cntf[i];
CV_READ_SEQ_ELEM( v, reader );
}
else else
{ v = cnt[i];
CV_READ_SEQ_ELEM( iv, reader );
v = cvPointTo32f( iv );
}
if( (v0.y <= pt.y && v.y <= pt.y) || if( (v0.y <= pt.y && v.y <= pt.y) ||
(v0.y > pt.y && v.y > pt.y) || (v0.y > pt.y && v.y > pt.y) ||
(v0.x < pt.x && v.x < pt.x) ) (v0.x < pt.x && v.x < pt.x) )
{ {
if( pt.y == v.y && (pt.x == v.x || (pt.y == v0.y && if( pt.y == v.y && (pt.x == v.x || (pt.y == v0.y &&
((v0.x <= pt.x && pt.x <= v.x) || (v.x <= pt.x && pt.x <= v0.x)))) ) ((v0.x <= pt.x && pt.x <= v.x) || (v.x <= pt.x && pt.x <= v0.x)))) )
...@@ -259,14 +194,9 @@ cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist ) ...@@ -259,14 +194,9 @@ cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist )
v0 = v; v0 = v;
if( is_float ) if( is_float )
{ v = cntf[i];
CV_READ_SEQ_ELEM( v, reader );
}
else else
{ v = cnt[i];
CV_READ_SEQ_ELEM( iv, reader );
v = cvPointTo32f( iv );
}
dx = v.x - v0.x; dy = v.y - v0.y; dx = v.x - v0.x; dy = v.y - v0.y;
dx1 = pt.x - v0.x; dy1 = pt.y - v0.y; dx1 = pt.x - v0.x; dy1 = pt.y - v0.y;
...@@ -292,8 +222,8 @@ cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist ) ...@@ -292,8 +222,8 @@ cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist )
} }
if( (v0.y <= pt.y && v.y <= pt.y) || if( (v0.y <= pt.y && v.y <= pt.y) ||
(v0.y > pt.y && v.y > pt.y) || (v0.y > pt.y && v.y > pt.y) ||
(v0.x < pt.x && v.x < pt.x) ) (v0.x < pt.x && v.x < pt.x) )
continue; continue;
dist_num = dy1*dx - dx1*dy; dist_num = dy1*dx - dx1*dy;
...@@ -301,17 +231,25 @@ cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist ) ...@@ -301,17 +231,25 @@ cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist )
dist_num = -dist_num; dist_num = -dist_num;
counter += dist_num > 0; counter += dist_num > 0;
} }
result = sqrt(min_dist_num/min_dist_denom); result = sqrt(min_dist_num/min_dist_denom);
if( counter % 2 == 0 ) if( counter % 2 == 0 )
result = -result; result = -result;
} }
} }
return result; return result;
} }
CV_IMPL double
cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist )
{
cv::AutoBuffer<double> abuf;
cv::Mat contour = cv::cvarrToMat(_contour, false, false, 0, &abuf);
return cv::pointPolygonTest(contour, pt, measure_dist != 0);
}
/* /*
This code is described in "Computational Geometry in C" (Second Edition), This code is described in "Computational Geometry in C" (Second Edition),
Chapter 7. It is not written to be comprehensible without the Chapter 7. It is not written to be comprehensible without the
......
...@@ -40,159 +40,122 @@ ...@@ -40,159 +40,122 @@
//M*/ //M*/
#include "precomp.hpp" #include "precomp.hpp"
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: cvMatchContours double cv::matchShapes(InputArray contour1, InputArray contour2, int method, double)
// Purpose:
// Calculates matching of the two contours
// Context:
// Parameters:
// contour_1 - pointer to the first input contour object.
// contour_2 - pointer to the second input contour object.
// method - method for the matching calculation
// (now CV_IPPI_CONTOURS_MATCH_I1, CV_CONTOURS_MATCH_I2 or
// CV_CONTOURS_MATCH_I3 only )
// rezult - output calculated measure
//
//F*/
CV_IMPL double
cvMatchShapes( const void* contour1, const void* contour2,
int method, double /*parameter*/ )
{ {
CvMoments moments;
CvHuMoments huMoments;
double ma[7], mb[7]; double ma[7], mb[7];
int i, sma, smb; int i, sma, smb;
double eps = 1.e-5; double eps = 1.e-5;
double mmm; double mmm;
double result = 0; double result = 0;
if( !contour1 || !contour2 ) HuMoments( moments(contour1), ma );
CV_Error( CV_StsNullPtr, "" ); HuMoments( moments(contour2), mb );
// calculate moments of the first shape
cvMoments( contour1, &moments );
cvGetHuMoments( &moments, &huMoments );
ma[0] = huMoments.hu1;
ma[1] = huMoments.hu2;
ma[2] = huMoments.hu3;
ma[3] = huMoments.hu4;
ma[4] = huMoments.hu5;
ma[5] = huMoments.hu6;
ma[6] = huMoments.hu7;
// calculate moments of the second shape
cvMoments( contour2, &moments );
cvGetHuMoments( &moments, &huMoments );
mb[0] = huMoments.hu1;
mb[1] = huMoments.hu2;
mb[2] = huMoments.hu3;
mb[3] = huMoments.hu4;
mb[4] = huMoments.hu5;
mb[5] = huMoments.hu6;
mb[6] = huMoments.hu7;
switch (method) switch (method)
{ {
case 1: case 1:
for( i = 0; i < 7; i++ )
{ {
for( i = 0; i < 7; i++ ) double ama = fabs( ma[i] );
double amb = fabs( mb[i] );
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
sma = -1;
else
sma = 0;
if( mb[i] > 0 )
smb = 1;
else if( mb[i] < 0 )
smb = -1;
else
smb = 0;
if( ama > eps && amb > eps )
{ {
double ama = fabs( ma[i] ); ama = 1. / (sma * log10( ama ));
double amb = fabs( mb[i] ); amb = 1. / (smb * log10( amb ));
result += fabs( -ama + amb );
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
sma = -1;
else
sma = 0;
if( mb[i] > 0 )
smb = 1;
else if( mb[i] < 0 )
smb = -1;
else
smb = 0;
if( ama > eps && amb > eps )
{
ama = 1. / (sma * log10( ama ));
amb = 1. / (smb * log10( amb ));
result += fabs( -ama + amb );
}
} }
break;
} }
break;
case 2: case 2:
for( i = 0; i < 7; i++ )
{ {
for( i = 0; i < 7; i++ ) double ama = fabs( ma[i] );
double amb = fabs( mb[i] );
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
sma = -1;
else
sma = 0;
if( mb[i] > 0 )
smb = 1;
else if( mb[i] < 0 )
smb = -1;
else
smb = 0;
if( ama > eps && amb > eps )
{ {
double ama = fabs( ma[i] ); ama = sma * log10( ama );
double amb = fabs( mb[i] ); amb = smb * log10( amb );
result += fabs( -ama + amb );
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
sma = -1;
else
sma = 0;
if( mb[i] > 0 )
smb = 1;
else if( mb[i] < 0 )
smb = -1;
else
smb = 0;
if( ama > eps && amb > eps )
{
ama = sma * log10( ama );
amb = smb * log10( amb );
result += fabs( -ama + amb );
}
} }
break;
} }
break;
case 3: case 3:
for( i = 0; i < 7; i++ )
{ {
for( i = 0; i < 7; i++ ) double ama = fabs( ma[i] );
double amb = fabs( mb[i] );
if( ma[i] > 0 )
sma = 1;
else if( ma[i] < 0 )
sma = -1;
else
sma = 0;
if( mb[i] > 0 )
smb = 1;
else if( mb[i] < 0 )
smb = -1;
else
smb = 0;
if( ama > eps && amb > eps )
{ {
double ama = fabs( ma[i] ); ama = sma * log10( ama );
double amb = fabs( mb[i] ); amb = smb * log10( amb );
mmm = fabs( (ama - amb) / ama );
if( ma[i] > 0 ) if( result < mmm )
sma = 1; result = mmm;
else if( ma[i] < 0 )
sma = -1;
else
sma = 0;
if( mb[i] > 0 )
smb = 1;
else if( mb[i] < 0 )
smb = -1;
else
smb = 0;
if( ama > eps && amb > eps )
{
ama = sma * log10( ama );
amb = smb * log10( amb );
mmm = fabs( (ama - amb) / ama );
if( result < mmm )
result = mmm;
}
} }
break;
} }
break;
default: default:
CV_Error( CV_StsBadArg, "Unknown comparison method" ); CV_Error( CV_StsBadArg, "Unknown comparison method" );
} }
return result; return result;
} }
CV_IMPL double
cvMatchShapes( const void* _contour1, const void* _contour2,
int method, double parameter )
{
cv::AutoBuffer<double> abuf1, abuf2;
cv::Mat contour1 = cv::cvarrToMat(_contour1, false, false, 0, &abuf1);
cv::Mat contour2 = cv::cvarrToMat(_contour2, false, false, 0, &abuf2);
return cv::matchShapes(contour1, contour2, method, parameter);
}
/* End of file. */ /* End of file. */
This diff is collapsed.
This diff is collapsed.
...@@ -13,7 +13,7 @@ static void help() ...@@ -13,7 +13,7 @@ static void help()
"Random points are generated and then enclosed.\n" "Random points are generated and then enclosed.\n"
"Call:\n" "Call:\n"
"./minarea\n" "./minarea\n"
"Using OpenCV version %s\n" << CV_VERSION << "\n" << endl; "Using OpenCV v" << CV_VERSION << "\n" << endl;
} }
int main( int /*argc*/, char** /*argv*/ ) int main( int /*argc*/, char** /*argv*/ )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment