简体   繁体   English

这是opencv RotatedRect的错误吗?

[英]Is it a bug of opencv RotatedRect?

I wrote the following code: 我写了以下代码:

#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;
}

The top-left corner of RotatedRect rr is (-0.5,-1),and the bottom-right corner of RotatedRect rr is (0.5,1).So the minminimal up-right rectangle containing the rotated rectangle is [(-1,-1),(1,1)],(-1,-1) is the top-left corner,(1,1) is the bottom-right corner.But the result rect's bottom-right corner is (2,2). RotatedRect rr的左上角是(-0.5,-1),RotatedRect rr的右下角是(0.5,1)。所以包含旋转矩形的最小右上角是[( - 1, -1),(1,1)],( - 1,-1)是左上角,(1,1)是右下角。但是结果rect的右下角是(2,2) )。

And I read the source: 我读了消息来源:

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

I wonder the code r.width -= rx - 1; 我想知道代码r.width -= rx - 1; and r.height -= ry - 1; r.height -= ry - 1; And I think it should be r.width -= rx; 我认为它应该是r.width -= rx; and r.height -= ry; r.height -= ry; Who can tell me is it the source wrong? 谁能告诉我这是错误的来源?

Looks like cv::boundingRect and RotatedRect::boundingRect are not consistent. 看起来像cv::boundingRectRotatedRect::boundingRect不一致。 I used this little test application 我使用了这个小测试应用程序

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

The result gives slightly different bounding rects (RotatedRect::boundingRect surrounds the points while cv::boundingRect is placed ON the points). 结果给出了稍微不同的边界值(RotatedRect :: boundingRect围绕点,而cv :: boundingRect放在点上)。 This might really be a bug, maybe initially cv::RotatedRect::boundingRect was an optimized copy of cv::boundingRect, and a bugfix in cv::boundingRect didn't update the member function. 这可能真的是一个错误,也许最初cv :: RotatedRect :: boundingRect是cv :: boundingRect的优化副本,而cv :: boundingRect中的错误修复没有更新成员函数。 Not sure... I would recommend to use the general purpose cv::boundingRect all the time (didn't measure speed though). 不确定......我建议一直使用通用的cv :: boundingRect(虽然没有测量速度)。

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM