前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >奇门遁甲| OpenCV中矩形框的各种神操作

奇门遁甲| OpenCV中矩形框的各种神操作

作者头像
OpenCV学堂
发布2022-03-03 16:24:26
发布2022-03-03 16:24:26
1.5K00
代码可运行
举报
运行总次数:0
代码可运行

函数说明与基本操作

图象处理中最常见的就是截取图象的一部分区域区域进行处理,这部分区域简称ROI,最常见的ROI区域就是矩形,当然还有很多不规则的ROI区域。对矩形ROI区域位置,OpenCV中有个数据结构cv::Rect来表示。cv::Rect的成员变量与函数支持说明:

代码语言:javascript
代码运行次数:0
运行
复制
Rect.x 表示左上角点x的坐标
Rect.y 表示左上角点y的坐标
Rect.width 表示矩形的宽度
Rect.height 表示矩形的高度
Rect.area() 表示矩形的面积
Rect.size() 表示矩形的大小
Rect.tl() 表示矩形左上角点的坐标
Rect.br() 表示矩形右下角点的坐标
Rect.contains() 判定一个点是否在矩形区域内,这个尼玛太有用啦!
Rect.empty() 判定矩形是否为空

上述这部分的代码演示如下:

代码语言:javascript
代码运行次数:0
运行
复制
// 矩形操作
cv::Mat image = cv::imread("D:/images/1024_mask.png");
cv::Mat result = image.clone();
// 绘制矩形框
cv::Rect r1(18, 20, 350, 70);
cv::rectangle(result, r1, cv::Scalar(0, 255, 0), 2, 8, 0);
// 绘制两个点
cv::circle(result, r1.tl(), 3, cv::Scalar(0, 255, 255), 3, 8, 0);
cv::circle(result, r1.br(), 3, cv::Scalar(0, 255, 255), 3, 8, 0);
// 判定一个点是否在矩形内
cv::Point pt1(10, 15);
cv::Point pt2(45, 45);
std::cout << "pt1 in r1: " << r1.contains(pt1) << " pt2 in r1: " << r1.contains(pt2) << std::endl;
std::cout << "r1 area: " << r1.area() << " r1 size: " << r1.size() << std::endl;

cv::imshow("result", result);
cv::waitKey(0);

运行结果如下:

各种神奇的矩形操作

直接平移:

把一个坐标点加到矩形上,可以直接平移矩形,代码演示如下

代码语言:javascript
代码运行次数:0
运行
复制
cv::Rect box1(18, 20, 350, 70);
cv::rectangle(image, box1, cv::Scalar(0, 255, 0), 2, 8, 0);

cv::Rect box2(60, 150, 350, 70);
cv::rectangle(image, box2, cv::Scalar(0, 255, 0), 2, 8, 0);

cv::Rect box3(125, 280, 350, 70);
cv::rectangle(image, box3, cv::Scalar(0, 255, 0), 2, 8, 0);

cv::Rect box6(28, 40, 350, 70);
cv::rectangle(image, box3, cv::Scalar(0, 255, 0), 2, 8, 0);

// 平移从box1 + pt
cv::Point pt(42, 130);
cv::Rect box7 = box1 + pt;
std::cout << "平移前: "<<box1.tl() << " 平移后:"<< box7.tl() << std::endl;
cv::rectangle(image, box7, cv::Scalar(255, 0, 255), 2, 8, 0);

判定矩形相等:

对两个矩形,可以直接进行比较,代码演示如下:

代码语言:javascript
代码运行次数:0
运行
复制
std::cout << "box1 == box7: "<< std::to_string(box1 == box7) << " box2 == box7: " << std::to_string(box2 == box7) << std::endl;

计算并交比,生成外接矩形:

对两个矩形可以计算交集得矩形框大小、也可以计算并集得矩形框大小。代码演示如下:

代码语言:javascript
代码运行次数:0
运行
复制
// 获取中心点
int cx = static_cast<int>(box7.x + box7.width / 2);
int cy = static_cast<int>(box7.y + box7.height / 2);
std::cout << "cx: " << cx << " cy: " << cy << std::endl;

// 计算并交框
Rect box4 = box1 & box6;  // 交  
Rect box5 = box2 | box3; // 并
std::cout << box5.tl() << std::endl;
cv::rectangle(image, box4, cv::Scalar(0, 255, 255), 2, 8, 0);
cv::rectangle(image, box5, cv::Scalar(0, 255, 255), 2, 8, 0);

排序矩形框,根据矩形框面积与坐标点

对得到不同矩框可以根据面积进行排序,得到不同排序方式得矩形,代码演示如下:

代码语言:javascript
代码运行次数:0
运行
复制
// 升序,基于左上角x坐标排序
static bool compareRect_x(cv::Rect box1, cv::Rect box2) {
    return box1.x <= box2.x;
}

// 升序,基于面积排序
static bool compareRect_area(cv::Rect box1, cv::Rect box2) {
    return box1.area() <= box2.area();
}

// 排序矩形
std::vector<cv::Rect> boxes;
boxes.push_back(box1);
boxes.push_back(box2);
boxes.push_back(box3);
boxes.push_back(box4);
boxes.push_back(box5);
boxes.push_back(box6);
boxes.push_back(box7);
std::sort(boxes.begin(), boxes.end(), compareRect_area);
for (cv::Rect box : boxes) {
    std::cout << "sorted rect: "<<box.tl() << " box.area: " << box.area()<<std::endl;
}

cv::imshow("image", image);
cv::waitKey(0);

运行效果如下:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档