Reputation: 1436
I'm trying to determin minimum bouding rect of a rotated rectangle. I tried a couple of samples like this from RotatedRect reference or from this tutorial about ellipses and bounding boxes. Nothing with satisfactory results. On the image bellow, yellow rectangle is the desired result.
Example data for my test:
Image:
Width: 1500
Height: 843
RotatedRect:
Center:
X: 783.490417
Y: 433.673492
Size:
Width: 810.946899
Height: 841.796997
Angle: 95.4092407
Sample code:
cv::RotatedRect r(cv::Point2f(783.490417, 433.673492),
cv::Size2f(810.946899, 841.796997),
95.4092407);
cv::Mat img = Mat::zeros(843, 1500, CV_8UC3);
cv::Rect rect = r.boundingRect();
cv::ellipse(img, r, cv::Scalar(0, 0, 255)); // RED
Point2f vertices[4];
r.points(vertices);
for (int i = 0; i < 4; i++)
line(img, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0)); // GREEN
rectangle(img, rect, Scalar(255, 0, 0)); // BLUE
cv::imshow("Result", img);
Upvotes: 4
Views: 4573
Reputation: 3550
i think here you can find a function doing your desired result.
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
int main( int argc, char**)
{
RotatedRect r ;
r.center = cv::Point2f(783.490417, 433.673492);
r.angle = 95.4092407;
r.size = cv::Size2f(810.946899, 841.796997);
cv::Mat img = Mat::zeros(843, 1500, CV_8UC3);
cv::Rect rect = r.boundingRect();
cv::ellipse(img, r, cv::Scalar(0, 0, 255)); // RED
Point2f vertices[4];
r.points(vertices);
for (int i = 0; i < 4; i++)
line(img, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0)); // GREEN
rectangle(img, rect, Scalar(255, 0, 0)); // BLUE
float degree = r.angle*3.1415/180;
float majorAxe = r.size.width/2;
float minorAxe = r.size.height/2;
float x = r.center.x;
float y = r.center.y;
float c_degree = cos(degree);
float s_degree = sin(degree);
float t1 = atan(-(majorAxe*s_degree)/(minorAxe*c_degree));
float c_t1 = cos(t1);
float s_t1 = sin(t1);
float w1 = majorAxe*c_t1*c_degree;
float w2 = minorAxe*s_t1*s_degree;
float maxX = x + w1-w2;
float minX = x - w1+w2;
t1 = atan((minorAxe*c_degree)/(majorAxe*s_degree));
c_t1 = cos(t1);
s_t1 = sin(t1);
w1 = minorAxe*s_t1*c_degree;
w2 = majorAxe*c_t1*s_degree;
float maxY = y + w1+w2;
float minY = y - w1-w2;
if (minY > maxY)
{
float temp = minY;
minY = maxY;
maxY = temp;
}
if (minX > maxX)
{
float temp = minX;
minX = maxX;
maxX = temp;
}
Rect yellowrect(minX,minY,maxX-minX+1,maxY-minY+1);
rectangle(img, yellowrect, Scalar(0, 255, 255)); // YELLOW
cv::imshow("Result", img);
waitKey();
}
Upvotes: 5