RotatedRect 的 OpenCV 最小直立边界矩形
OpenCV minimum upright bounding rect of a RotatedRect
我正在尝试确定旋转矩形的最小边界矩形。我尝试了几个示例,例如 this from RotatedRect reference or from this 关于椭圆和边界框的教程。没有令人满意的结果。在下图中,黄色矩形是想要的结果。
我的测试示例数据:
Image:
Width: 1500
Height: 843
RotatedRect:
Center:
X: 783.490417
Y: 433.673492
Size:
Width: 810.946899
Height: 841.796997
Angle: 95.4092407
示例代码:
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);
- RED - 计算最小布丁矩形的 RotatedRect
- 蓝色 - r.boundingRect()
- 绿色 - r.points()
- 黄色 - 期望的结果
我认为 here 你可以找到一个函数来实现你想要的结果。
#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();
}
我正在尝试确定旋转矩形的最小边界矩形。我尝试了几个示例,例如 this from RotatedRect reference or from this 关于椭圆和边界框的教程。没有令人满意的结果。在下图中,黄色矩形是想要的结果。
我的测试示例数据:
Image:
Width: 1500
Height: 843
RotatedRect:
Center:
X: 783.490417
Y: 433.673492
Size:
Width: 810.946899
Height: 841.796997
Angle: 95.4092407
示例代码:
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);
- RED - 计算最小布丁矩形的 RotatedRect
- 蓝色 - r.boundingRect()
- 绿色 - r.points()
- 黄色 - 期望的结果
我认为 here 你可以找到一个函数来实现你想要的结果。
#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();
}