RotatedRect的OpenCV最小直立边界矩形

时间:2015-10-03 08:21:23

标签: c++ opencv bounding-box

我正在尝试确定旋转矩形的最小布局矩形。我尝试了几个样本,例如来自RotatedRect参考的STI table setup或来自this的关于省略号和边界框的教程。没有令人满意的结果。在下面的图像上,黄色矩形是期望的结果。

我测试的示例数据:

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);

示例代码:

[
    ['imageFiles'], 'file',
    'extensions' => 'png, jpg, jpeg, gif', 
    'mimeTypes' => 'image/jpeg, image/png',
    'maxFiles' => 4, 
    'minWidth' => 100, 
    'maxWidth' => 800, 
    'minHeight' => 100, 
    'maxHeight'=>600,
    'skipOnEmpty' => true
],
  • RED - RotatedRect,计算min bouding rect
  • BLUE - r.boundingRect()
  • 绿色 - r.points()
  • 黄色 - 期望的结果

this

1 个答案:

答案 0 :(得分:3)

我认为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();
}