From a937d9d43c7bc1345d6d43634a1731ec3d0330fa Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Mon, 29 Nov 2010 18:14:08 +0000 Subject: [PATCH] unified the coordinate interpretation in RotatedRect (ticket #425) --- .../core/include/opencv2/core/operations.hpp | 28 ----------------- modules/core/src/drawing.cpp | 2 +- modules/core/src/matrix.cpp | 31 +++++++++++++++++++ modules/imgproc/src/rotcalipers.cpp | 12 +++---- modules/video/src/camshift.cpp | 8 ++++- samples/cpp/camshiftdemo.cpp | 1 - samples/cpp/fitellipse.cpp | 6 +++- tests/cv/src/acamshift.cpp | 2 +- 8 files changed, 51 insertions(+), 39 deletions(-) diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index 8bfcd33147..1036564bf7 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -1765,34 +1765,6 @@ inline RotatedRect::operator CvBox2D() const CvBox2D box; box.center = center; box.size = size; box.angle = angle; return box; } -inline void RotatedRect::points(Point2f pt[]) const -{ - double _angle = angle*CV_PI/180.; - float a = (float)cos(_angle)*0.5f; - float b = (float)sin(_angle)*0.5f; - - pt[0].x = center.x - a*size.height - b*size.width; - pt[0].y = center.y + b*size.height - a*size.width; - pt[1].x = center.x + a*size.height - b*size.width; - pt[1].y = center.y - b*size.height - a*size.width; - pt[2].x = 2*center.x - pt[0].x; - pt[2].y = 2*center.y - pt[0].y; - pt[3].x = 2*center.x - pt[1].x; - pt[3].y = 2*center.y - pt[1].y; -} - -inline Rect RotatedRect::boundingRect() const -{ - Point2f pt[4]; - points(pt); - Rect r(cvFloor(min(min(min(pt[0].x, pt[1].x), pt[2].x), pt[3].x)), - cvFloor(min(min(min(pt[0].y, pt[1].y), pt[2].y), pt[3].y)), - cvCeil(max(max(max(pt[0].x, pt[1].x), pt[2].x), pt[3].x)), - cvCeil(max(max(max(pt[0].y, pt[1].y), pt[2].y), pt[3].y))); - r.width -= r.x - 1; - r.height -= r.y - 1; - return r; -} //////////////////////////////// Scalar_ /////////////////////////////// diff --git a/modules/core/src/drawing.cpp b/modules/core/src/drawing.cpp index 7ad66a3713..c8fbc3c533 100644 --- a/modules/core/src/drawing.cpp +++ b/modules/core/src/drawing.cpp @@ -877,7 +877,7 @@ void ellipse2Poly( Point center, Size axes, int angle, y = size_b * SinTable[angle]; Point pt; pt.x = cvRound( cx + x * alpha - y * beta ); - pt.y = cvRound( cy - x * beta - y * alpha ); + pt.y = cvRound( cy + x * beta + y * alpha ); if( pt != prevPt ) pts.push_back(pt); } diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index df7e340242..a3e8822bd8 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -3043,6 +3043,37 @@ void normalize( const SparseMat& src, SparseMat& dst, double a, int norm_type ) src.convertTo( dst, -1, scale ); } + +////////////////////// RotatedRect ////////////////////// + +void RotatedRect::points(Point2f pt[]) const +{ + double _angle = angle*CV_PI/180.; + float b = (float)cos(_angle)*0.5f; + float a = (float)sin(_angle)*0.5f; + + pt[0].x = center.x - a*size.height - b*size.width; + pt[0].y = center.y + b*size.height - a*size.width; + pt[1].x = center.x + a*size.height - b*size.width; + pt[1].y = center.y - b*size.height - a*size.width; + pt[2].x = 2*center.x - pt[0].x; + pt[2].y = 2*center.y - pt[0].y; + pt[3].x = 2*center.x - pt[1].x; + pt[3].y = 2*center.y - pt[1].y; +} + +inline Rect RotatedRect::boundingRect() const +{ + Point2f pt[4]; + points(pt); + Rect r(cvFloor(min(min(min(pt[0].x, pt[1].x), pt[2].x), pt[3].x)), + cvFloor(min(min(min(pt[0].y, pt[1].y), pt[2].y), pt[3].y)), + cvCeil(max(max(max(pt[0].x, pt[1].x), pt[2].x), pt[3].x)), + cvCeil(max(max(max(pt[0].y, pt[1].y), pt[2].y), pt[3].y))); + r.width -= r.x - 1; + r.height -= r.y - 1; + return r; +} } diff --git a/modules/imgproc/src/rotcalipers.cpp b/modules/imgproc/src/rotcalipers.cpp index 61c2a94f68..4ea8f75623 100644 --- a/modules/imgproc/src/rotcalipers.cpp +++ b/modules/imgproc/src/rotcalipers.cpp @@ -415,9 +415,9 @@ cvMinAreaRect2( const CvArr* array, CvMemStorage* storage ) 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 ); + box.size.width = (float)sqrt((double)out[1].x*out[1].x + (double)out[1].y*out[1].y); + box.size.height = (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 ) { @@ -425,9 +425,9 @@ cvMinAreaRect2( const CvArr* array, CvMemStorage* storage ) 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 ); + box.size.width = (float)sqrt(dx*dx + dy*dy); + box.size.height = 0; + box.angle = (float)atan2( dy, dx ); } else { diff --git a/modules/video/src/camshift.cpp b/modules/video/src/camshift.cpp index 908922e515..0c8bf119bf 100644 --- a/modules/video/src/camshift.cpp +++ b/modules/video/src/camshift.cpp @@ -275,7 +275,13 @@ cvCamShift( const void* imgProb, CvRect windowIn, { box->size.height = (float)length; box->size.width = (float)width; - box->angle = (float)(theta*180./CV_PI); + box->angle = (float)((CV_PI*0.5+theta)*180./CV_PI); + while(box->angle < 0) + box->angle += 360; + while(box->angle >= 360) + box->angle -= 360; + if(box->angle >= 180) + box->angle -= 180; box->center = cvPoint2D32f( comp.rect.x + comp.rect.width*0.5f, comp.rect.y + comp.rect.height*0.5f); } diff --git a/samples/cpp/camshiftdemo.cpp b/samples/cpp/camshiftdemo.cpp index dc321808ad..443392a619 100644 --- a/samples/cpp/camshiftdemo.cpp +++ b/samples/cpp/camshiftdemo.cpp @@ -130,7 +130,6 @@ int main( int argc, char** argv ) backproj &= mask; RotatedRect trackBox = CamShift(backproj, trackWindow, TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 )); - trackBox.angle = 90-trackBox.angle; if( backprojMode ) cvtColor( backproj, image, CV_GRAY2BGR ); diff --git a/samples/cpp/fitellipse.cpp b/samples/cpp/fitellipse.cpp index 22b1806ef1..c7a4ebabc1 100644 --- a/samples/cpp/fitellipse.cpp +++ b/samples/cpp/fitellipse.cpp @@ -71,12 +71,16 @@ void processImage(int h, void*) Mat(contours[i]).convertTo(pointsf, CV_32F); RotatedRect box = fitEllipse(pointsf); - box.angle = -box.angle; if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 ) continue; drawContours(cimage, contours, (int)i, Scalar::all(255), 1, 8); ellipse(cimage, box, Scalar(0,0,255), 1, CV_AA); + ellipse(cimage, box.center, box.size*0.5f, box.angle, 0, 360, Scalar(0,255,255), 1, CV_AA); + Point2f vtx[4]; + box.points(vtx); + for( int j = 0; j < 4; j++ ) + line(cimage, vtx[j], vtx[(j+1)%4], Scalar(0,255,0), 1, CV_AA); } imshow("result", cimage); diff --git a/tests/cv/src/acamshift.cpp b/tests/cv/src/acamshift.cpp index 5014dbb6f6..63322b38f7 100644 --- a/tests/cv/src/acamshift.cpp +++ b/tests/cv/src/acamshift.cpp @@ -134,7 +134,7 @@ void CV_TrackBaseTest::generate_object() double width = box0.size.width*0.5; double height = box0.size.height*0.5; double angle = box0.angle*CV_PI/180.; - double a = cos(angle), b = sin(angle); + double a = sin(angle), b = -cos(angle); double inv_ww = 1./(width*width), inv_hh = 1./(height*height); img = cvCreateMat( img_size.height, img_size.width, img_type ); -- 2.34.1