【问题标题】:OpenCV minimum upright bounding rect of a RotatedRectRotatedRect 的 OpenCV 最小直立边界矩形
【发布时间】:2015-12-31 10:42:25
【问题描述】:

我正在尝试确定旋转矩形的最小边界矩形。我尝试了几个示例,例如来自 RotatedRect 参考的this 或来自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()
  • 黄色 - 想要的结果

【问题讨论】:

    标签: c++ opencv bounding-box


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-23
      • 2019-08-11
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      相关资源
      最近更新 更多