# fitEllipse - angle of resulting rotated rect

It seems that fitEllipse realization miss the result RotatedRect angle computing in some cases.

...
box.center.x = (float)rp[0] + c.x;
box.center.y = (float)rp[1] + c.y;
box.size.width = (float)(rp[2]*2);
box.size.height = (float)(rp[3]*2);
if( box.size.width > box.size.height )
{
float tmp;
CV_SWAP( box.size.width, box.size.height, tmp );
box.angle = (float)(90 + rp[4]*180/CV_PI);
}
if( box.angle < -180 )
box.angle += 360;
if( box.angle > 360 )
box.angle -= 360;

return box;


If box.size.width <= box.size.height the angle of rotated rect would be indefinite. Please correct me, if I am wrong.

edit retag close merge delete

1

Thank you for reporting, it seems that you're right - would be nice if you could fix it and make a pull-request!

( 2014-08-11 14:50:49 -0600 )edit
1

Indeed, take a look at the how to contribute page. It would be nice if you provided a fix for this.

( 2014-08-12 05:54:37 -0600 )edit

Sort by ยป oldest newest most voted

to understand and test i tried to implement the code below. May be it will be helpful for some one who want to fix

#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;
using namespace std;

void process( Mat src );

int main()
{
Mat clk(640,640,CV_8UC3);

Point cent(320,320);
Point perim(320,0);

float sec_angle=270;

while(1)
{
if(sec_angle>360)sec_angle=sec_angle-360;

perim.x =  (int)round(cent.x + 200 * cos(sec_angle * CV_PI / 180.0));
perim.y =  (int)round(cent.y + 200 * sin(sec_angle * CV_PI / 180.0));
line( clk,cent,perim, Scalar(0,255,255), 8 );

process( clk );
putText( clk, format("%f",sec_angle), perim, FONT_HERSHEY_PLAIN, 2, Scalar(0,0,255) );

imshow("Clock",clk);
clk.setTo(0);

sec_angle ++;

char c=waitKey();
if(c==27)break;
}
return 0;
}

void process( Mat src )
{
Mat gray;
cvtColor( src, gray, COLOR_BGR2GRAY );
gray = gray >  127;

vector<vector<Point> > contours;

findContours(gray.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

RotatedRect _minAreaRect;

for (size_t i = 0; i < contours.size(); ++i)
{
_minAreaRect = minAreaRect( Mat(contours[i]) );
Point2f pts[4];
_minAreaRect.points(pts);

double angle = atan2(pts[0].y - pts[1].y,pts[0].x - pts[1].x) * 180.0 / CV_PI;
putText( src, format("minAreaRect : %f, %f",_minAreaRect.angle, angle), Point(30,30), FONT_HERSHEY_PLAIN, 2, Scalar(0,0,255) );

for( int j = 0; j < 4; j++ )
line(src, pts[j], pts[(j+1)%4], Scalar(0, 255, 0), 2, LINE_AA);

_minAreaRect = fitEllipse( Mat(contours[i]) ) ;
_minAreaRect.points(pts);
angle = atan2(pts[0].y - pts[1].y,pts[0].x - pts[1].x) * 180.0 / CV_PI;
putText( src, format("fitEllipse : %f, %f",_minAreaRect.angle, angle ), Point(30,70), FONT_HERSHEY_PLAIN, 2, Scalar(0,0,255) );

for( int j = 0; j < 4; j++ )
line(src, pts[j], pts[(j+1)%4], Scalar(0, 0, 255), 1, LINE_AA);

}
}

more

I want to dig this old thread because this bug isn't fixed until now. I think changing this piece of code to

...
box.center.x = (float)rp[0] + c.x;
box.center.y = (float)rp[1] + c.y;
box.size.width = (float)(rp[2]*2);
box.size.height = (float)(rp[3]*2);
box.angle = (float)(rp[4]*180/CV_PI);

if( box.size.width > box.size.height )
{
float tmp;
CV_SWAP( box.size.width, box.size.height, tmp );
box.angle += 90;
}

if( box.angle < -180 )
box.angle += 360;
if( box.angle > 180 )
box.angle -= 360;

return box;


should fix it. And I think the angle range should be between -180 and +180 degrees (or even between -90 and +90 degrees?), so I changed the last condition, too.

more

1

Again I would ask if you could provide a PR with the fix. It wil make sure that a possible fix for the problem gets inside the source code!

( 2015-11-17 01:57:30 -0600 )edit

@matman i tested your proposed fix. but i think it is not correct.

( 2015-12-07 10:51:18 -0600 )edit

Official site

GitHub

Wiki

Documentation