OpenCV中两个旋转矩形RotatedRect的交集

OpenCV中两个旋转矩形RotatedRect的交集


#include <vector>
#include <iostream>
#include "opencv2/opencv.hpp"


static void DrawRotatedRect(cv::Mat& img, cv::RotatedRect& rr, cv::Scalar color)
{
    cv::Point2f pts[4] = { 0.0 };
    rr.points(pts);
    for (int i = 0; i < 4; i++)
    {
        cv::line(img, pts[i], pts[(i + 1) % 4], color, 1);
    }
}


static void GetRegion(cv::Mat& img, cv::Mat& dst, int lineValue, int fillValue)
{
    CV_Assert(img.type() == CV_8UC1);

    dst = cv::Mat::zeros(img.size(), img.type());
    for (int y = 0; y < img.rows; y++)
    {
        cv::Point left = cv::Point(-1, -1);
        cv::Point right = cv::Point(-1, -1);

        // 从左到右扫描
        for (int x = 0; x < img.cols; x++)
        {
            int value = img.at<uchar>(y, x);
            if (value == lineValue)
            {
                left.x = x;
                left.y = y;
                break;
            }
        }

        // 从右边到左边扫描
        for (int x = img.cols - 1; x >= 0; x--)
        {
            int value = img.at<uchar>(y, x);
            if (value == lineValue)
            {
                right.x = x;
                right.y = y;
                break;
            }
        }

        // 表明没有检测到,直接就是下一行
        if ((left.x < 0) && (left.y < 0) && (right.x < 0) && (right.y < 0))
        {
            continue;
        }

        if ((left.x >= 0) && (left.y >= 0) && (right.x >= 0) && (right.y >= 0) && (left!=right))
        {
            cv::line(dst, left, right, fillValue, 1/*thickness*/);
        }
        else if ((left == right) && (left.x >= 0) && (left.y >= 0))
        {
            // 只有一个点
            dst.at<uchar>(left.y, left.x) = fillValue;
        }
        else
        {
            // TODO
        }
    } // Row
}


static bool RotatedRectIntersection(cv::RotatedRect r1, cv::RotatedRect r2, cv::Mat& dst, int w, int h)
{
    dst = cv::Mat::zeros(h, w, CV_8UC1);

    const int LINE_VALUE = 255;
    const int REGION_VALUE = 255;
    const int FILL_VALUE = 20;

    cv::Mat rrImg1 = cv::Mat::zeros(h, w, CV_8UC1);
    cv::Mat rrImg2 = cv::Mat::zeros(h, w, CV_8UC1);

    DrawRotatedRect(rrImg1, r1, LINE_VALUE);
    DrawRotatedRect(rrImg2, r2, LINE_VALUE);

    cv::Mat region1;
    cv::Mat region2;
    GetRegion(rrImg1, region1, LINE_VALUE, FILL_VALUE);
    GetRegion(rrImg2, region2, LINE_VALUE, FILL_VALUE);

    int cnt = 0;    // 统计交点数目
    for (int y = 0; y < region1.rows; y++)
    {
        for (int x = 0; x < region1.cols; x++)
        {
            int v1 = region1.at<uchar>(y, x);
            int v2 = region2.at<uchar>(y, x);
            if ((v1 == FILL_VALUE) && (v2 == FILL_VALUE))
            {
                cnt++;
                dst.at<uchar>(y, x) = 255;
            }
        }
    }

    // 返回是否有交点
    if (cnt > 0)    return true;
    return false;

}


void test_rotated_rect_intersection()
{
    int w = 500;
    int h = 300;
    cv::RotatedRect rr1 = cv::RotatedRect(cv::Point2f(30, 40), cv::Size2f(20, 30), 45);
    cv::RotatedRect rr2 = cv::RotatedRect(cv::Point2f(25, 30), cv::Size2f(25, 40), 120);


    cv::Mat dst;
    bool flag = RotatedRectIntersection(rr1, rr2, dst, w, h);

    DrawRotatedRect(dst, rr1, 255);
    DrawRotatedRect(dst, rr2, 255);

    cv::imshow("dst", dst);
    std::cout << flag << std::endl;
    cv::waitKey(0);
}


int main(int argc, char** argv)
{
    void test_rotated_rect_intersection();
    test_rotated_rect_intersection();

    cv::waitKey(0);
    return 0;
}

结果图如下所示:
代码运行结果

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值