RotatedRect creation from vertices

asked 2016-09-16 12:50:24 -0600

vrain gravatar image

Hi everybody, I'm writing a program (a drone simulator) that does the following:

1) it creates a blank window with two orthogonal lines, to simulate a wall intersection; 2) it creates a RotatedRect, randomly placed and randomly tilted; 3) it translates this RotatedRect until it is close enough to the wall; 4) then it computes a 2D rotational matrix and applies it to each of the RotatedRect's corners, computed as 2D vectors with respect to the RotatedRect's center; the four corners are rotated and, if I draw a line between each corner and its following one, I get a rectangle with sides parallel to the walls; 5) a new RotatedRect is created from these new corners; 6) this new RotatedRect moves randomly and new data is extracted from it.

This code sometimes work and sometimes doesn't, and when it doesn't, it fails at step 5, with this error:

OpenCV Error: Assertion failed (abs(vecs[0].dot(vecs[1])) / (norm(vecs[0]) * norm(vecs[1])) <= FLT_EPSILON) in RotatedRect, file /home/wauro/opencv-3.1.0/modules/core/src/matrix.cpp, line 5462

terminate called after throwing an instance of 'cv::Exception' what(): /home/wauro/opencv-3.1.0/modules/core/src/matrix.cpp:5462: error: (-215) abs(vecs[0].dot(vecs[1])) / (norm(vecs[0]) * norm(vecs[1])) <= FLT_EPSILON in function RotatedRect

I know this kind of error is due to the failure of the RotatedRect's constructor:

RotatedRect (const Point2f &point1, const Point2f &point2, const Point2f &point3)

I've been searching on Google for three days, and I've attempted several ways to get over this error, but I can't figure it out. This is my code:

int height = 480;
int width = 640;

cv::Mat frame( height, width, CV_8UC1, cv::Scalar(0) );

int bound = 50;

cv::Point orig( 50, 50 );
cv::line( frame, orig, cv::Point( width, bound ), cv::Scalar( 255,255,255 ), 1, 8, 0 );
cv::line( frame, orig, cv::Point( bound, height ), cv::Scalar( 255,255,255 ), 1, 8, 0 );

std::srand(time(0));
cv::Point2f rect_center( (std::rand() % 490) + 2*bound, (std::rand() % 280) + 2*bound );
cv::RotatedRect r( rect_center, cv::Size2f(50, 100), std::rand()%360 ); 
cv::Rect brect = r.boundingRect();  

cv::Mat framerect = frame.clone();

cv::Point2f vertices[4];
r.points(vertices);
for (int i = 0; i < 4; i++)
    line(framerect, vertices[i], vertices[(i+1)%4], cv::Scalar(255,255,255));


cv::imshow( "frame", framerect );
cv::waitKey(0);



int distance = (int)cv::norm( r.boundingRect().tl() - orig );
int epsilon = 130;
int delta = 5;

//translation
while ( rect_center.x > epsilon && rect_center.y > epsilon )
{
    cv::Point2f step;

    std::srand( time(0) );
    step.x = (std::rand())%10;
    std::srand( time(0) );
    step.y = (std::rand())%10;
    rect_center -= step;

    r.center = rect_center;
    distance = (int)cv::norm( r.boundingRect().tl() - orig );

    for (int i = 0; i < 4; i++)
        line(framerect, vertices[i], vertices[(i+1)%4], cv::Scalar(255,255,255));

    framerect = frame.clone();
    cv::imshow( "frame", framerect );
    cv::waitKey(100); 
}


//coordinate system change


rect_center = r ...
(more)
edit retag flag offensive close merge delete

Comments

I also came across this issue some time ago. The error arises because the constructor identifies the two provided rectangle sides as non perpendicular. However, I too was using just clearly perpendicular sides (same x, same y, as you describe). I was unable to clearly reproduce the issue with a short example (in fact, error appeared quite randomly using the same input data). If you manage to create a reproducable sample, maybe the best is to create an issue here.

LorenaGdL gravatar imageLorenaGdL ( 2016-09-18 05:48:04 -0600 )edit