OpenCV的RotatedRect是否存在bug?

4
我写了以下代码:
#include<iostream>
#include<opencv2/core/core.hpp>
using namespace std;
using namespace cv;

int main()
{
    Point2f p[4];
    RotatedRect rr(Point2f(),Size2f(1,2),0);
    rr.points(p);
    for(int i = 0;i < 4;i++) cout<<p[i]<<endl;
    Rect r = rr.boundingRect();
    cout<< r.x << " " << r.y << " " << r.br().x << " " << r.br().y <<endl;
    return 0;
}

旋转矩形rr的左上角为(-0.5,-1),右下角为(0.5,1)。因此包含旋转矩形的最小正矩形为[(-1,-1),(1,1)],(-1,-1)为左上角,(1,1)为右下角。但是结果矩形的右下角为(2,2)。

我查看了源代码:

Rect RotatedRect::boundingRect() const
{
    Point2f pt[4];
    points(pt);
    Rect r(cvFloor(std::min(std::min(std::min(pt[0].x, pt[1].x), pt[2].x), pt[3].x)),
           cvFloor(std::min(std::min(std::min(pt[0].y, pt[1].y), pt[2].y), pt[3].y)),
           cvCeil(std::max(std::max(std::max(pt[0].x, pt[1].x), pt[2].x), pt[3].x)),
           cvCeil(std::max(std::max(std::max(pt[0].y, pt[1].y), pt[2].y), pt[3].y)));
    r.width -= r.x - 1;
    r.height -= r.y - 1;
    return r;
}

我想知道代码 r.width -= r.x - 1;r.height -= r.y - 1; 的意思。 我认为应该是 r.width -= r.x;r.height -= r.y; 谁能告诉我这个源代码是否有误?

旋转矩形本身没问题吗?如果将旋转矩形的角点推回到std :: vector中,并计算这些点的通用cv :: boundingRect,结果会怎样呢? - Micka
cv::boundingRect没问题。RotatedRect::boundingRect()可能有错误。 - Gauss
1个回答

2

看起来cv::boundingRectRotatedRect::boundingRect不一致。我使用了这个小测试应用程序。

int main(int argc, char* argv[])
{
    cv::Mat input = cv::imread("C:/StackOverflow/Input/Lenna.png");

    //cv::RotatedRect rr = cv::RotatedRect(cv::Point2f(), cv::Size2f(1, 2), 0);

    cv::RotatedRect rr = cv::RotatedRect(cv::Point2f(256,256), cv::Size2f(150, 100), 45);

    cv::Rect rect1 = rr.boundingRect();

    cv::Point2f pt[4];
    rr.points(pt);

    std::vector<cv::Point> pts;
    pts.push_back(pt[0]);
    pts.push_back(pt[1]);
    pts.push_back(pt[2]);
    pts.push_back(pt[3]);

    cv::Rect rect2 = cv::boundingRect(pts);

    std::cout << "RotatedRect::boundingRect: " << rect1 << std::endl;
    std::cout << "cv::boundingRect: " << rect2 << std::endl;

    cv::line(input, pt[0], pt[1], cv::Scalar(0, 0, 255));
    cv::line(input, pt[1], pt[2], cv::Scalar(0, 0, 255));
    cv::line(input, pt[2], pt[3], cv::Scalar(0, 0, 255));
    cv::line(input, pt[3], pt[0], cv::Scalar(0, 0, 255));

    cv::rectangle(input, rect1, cv::Scalar(255, 0, 0));
    cv::rectangle(input, rect2, cv::Scalar(0, 255, 0));

    cv::imshow("input", input);
    cv::waitKey(0);
    return 0;
}

结果会给出稍微不同的边界矩形(RotatedRect::boundingRect将点包围,而cv::boundingRect放置在点上)。这可能真的是一个错误,也许最初cv::RotatedRect::boundingRect是cv::boundingRect的优化副本,并且cv::boundingRect中的错误修复没有更新成员函数。不确定... 我建议始终使用通用的cv::boundingRect(尽管没有测量速度)。 enter image description here

我在电脑上尝试了RotatedRect::boundingRectcv::boundingRect两种方法。然而,它们的输出结果是相同的。它们都能够将点包围起来。 - Galaxy
@Galaxy,你用的是哪个OpenCV版本?我的是2.4.9或2.4.11。 - Micka
@Galaxy,在你的系统上,我的测试代码对于rect1和rect2产生了相同的结果吗? - Micka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接