使用OpenCV绘制带旋转角度的十字光标和旋转矩形

本文介绍了如何使用OpenCV库在图像中绘制不旋转的十字光标和根据给定角度旋转的矩形。通过pointRotate函数实现点的旋转,并展示了如何在不同场景下应用drawCross和RotatedRect进行图形绘制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、先看十字光标怎么绘制

源码如下:

void pointRotate(const cv::Point2d &src, const cv::Point2d &base, double angle, cv::Point2d &dst)
{
    //旋转角度参数angle,单位是角度,非弧度
    //点A(x1, y1)基于点O(x0, y0)逆时针旋转angle角度后,得到点B(x2,y2),求解点B坐标
    double x1 = src.x; //点A
    double y1 = src.y;
    double x0 = base.x;
    double y0 = base.y; //点O

    double theta = angle * CV_PI / 180.0;                             //角度转弧度
    double x2 = (x1 - x0) * cos(theta) - (y1 - y0) * sin(theta) + x0; //点B
    double y2 = (x1 - x0) * sin(theta) + (y1 - y0) * cos(theta) + y0;

    dst.x = x2;
    dst.y = y2;
}

void drawCross(cv::Mat &image, cv::Point center, int len, cv::Scalar color, int thickness, double angle)
{
    //不旋转
    if (fabs(angle) < 0.001)
    {
        //绘制横线
        cv::line(image, cv::Point(center.x - len / 2, center.y), cv::Point(center.x + len / 2, center.y), color, thickness);

        //绘制竖线
        cv::line(image, cv::Point(center.x, center.y - len / 2), cv::Point(center.x, center.y + len / 2), color, thickness);
        return;
    }

    //旋转角度angle,单位是角度,非弧度
    cv::Point2d p1;
    cv::Point2d p2;

    //绘制x线
    double x1 = center.x - len / 2;
    double x2 = center.x + len / 2;
    double y = center.y;
    pointRotate(cv::Point2d(x1, y), center, angle, p1);
    pointRotate(cv::Point2d(x2, y), center, angle, p2);
    cv::line(image, p1, p2, color, thickness);

    //绘制y线
    double y1 = center.y - len / 2;
    double y2 = center.y + len / 2;
    double x = center.x;
    pointRotate(cv::Point2d(x, y1), center, angle, p1);
    pointRotate(cv::Point2d(x, y2), center, angle, p2);
    cv::line(image, p1, p2, color, thickness);
}

测试:

cv::circle(imageMatch, cv::Point(col, row), 10, cv::Scalar(0, 0, 255), 1);

drawCross(imageMatch, cv::Point(col, row), 10, cv::Scalar(0, 0, 255), 1, angle);

二、再看旋转矩形怎么绘制

cv::Mat output, cv::Point center, float angle, cv::Rect valid;
int linesize = 2;

//画矩形框
if (fabs(angle) < 0.0001)
{
    cv::rectangle(output, valid, cv::Scalar(255, 0, 0), linesize); //不旋转
}
else
{
    float deg = angle * 180 / CV_PI;                                    //弧度转角度
    cv::RotatedRect rRect = cv::RotatedRect(center, valid.size(), deg); //旋转矩形
    cv::Point2f vertices[4];
    rRect.points(vertices);
    for (int i = 0; i < 4; i++)
    {
        cv::line(output, vertices[i], vertices[(i + 1) % 4], cv::Scalar(255, 0, 0), linesize);
    }
}

三、已知矩形A,求旋转矩形B,再由B求最小外接矩形C

cv::Rect region;//已知矩形A
cv::Point2d base;
double degree;
std::vector<Point2d> vertices(4);//待求的旋转矩形B的4个顶点
cv::Point2d p1 = cv::Point2d(region.x, region.y);
cv::Point2d p2 = cv::Point2d(region.x + region.width, region.y);
cv::Point2d p3 = cv::Point2d(region.x + region.width, region.y + region.height);
cv::Point2d p4 = cv::Point2d(region.x, region.y + region.height);
pointRotate(p1, base, -degree, vertices[0]);
pointRotate(p2, base, -degree, vertices[1]);
pointRotate(p3, base, -degree, vertices[2]);
pointRotate(p4, base, -degree, vertices[3]);

//请注意,cv::boundingRect不接受std::vector<Point2d>类型,所以转换为std::vector<Point2f>
std::vector<Point2f> v;
for (auto p : vertices)
{
     v.emplace_back(p);
}

cv::Rect r = cv::boundingRect(v); //最小外接矩形C

---

引申阅读,旋转矩形

OpenCV之RotatedRect基本用法和角度探究_sandalphon4869的博客-CSDN博客_rotatedrect

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值