点击上方↑↑↑“OpenCV学堂”关注我
神存在于细节之中!
函数说明与基本操作
图象处理中最常见的就是截取图象的一部分区域区域进行处理,这部分区域简称ROI,最常见的ROI区域就是矩形,当然还有很多不规则的ROI区域。对矩形ROI区域位置,OpenCV中有个数据结构cv::Rect来表示。cv::Rect的成员变量与函数支持说明:
Rect.x 表示左上角点x的坐标
Rect.y 表示左上角点y的坐标
Rect.width 表示矩形的宽度
Rect.height 表示矩形的高度
Rect.area() 表示矩形的面积
Rect.size() 表示矩形的大小
Rect.tl() 表示矩形左上角点的坐标
Rect.br() 表示矩形右下角点的坐标
Rect.contains() 判定一个点是否在矩形区域内,这个尼玛太有用啦!
Rect.empty() 判定矩形是否为空
上述这部分的代码演示如下:
// 矩形操作
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);
运行结果如下:
各种神奇的矩形操作
直接平移:
把一个坐标点加到矩形上,可以直接平移矩形,代码演示如下
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 << "平移前: "<" 平移后:"<< box7.tl() << std::endl;
cv::rectangle(image, box7, cv::Scalar(255, 0, 255), 2, 8, 0);
判定矩形相等:
对两个矩形,可以直接进行比较,代码演示如下:
std::cout << "box1 == box7: "<< std::to_string(box1 == box7) << " box2 == box7: " << std::to_string(box2 == box7) << std::endl;
计算并交比,生成外接矩形:
对两个矩形可以计算交集得矩形框大小、也可以计算并集得矩形框大小。代码演示如下:
// 获取中心点
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);
排序矩形框,根据矩形框面积与坐标点
对得到不同矩框可以根据面积进行排序,得到不同排序方式得矩形,代码演示如下:
// 升序,基于左上角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 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.area: " << box.area()<<std::endl;
}
cv::imshow("image", image);
cv::waitKey(0);
运行效果如下:
OpenCV4系统化学习
推荐阅读
OpenCV4.8+YOLOv8对象检测C++推理演示
ZXING+OpenCV打造开源条码检测应用
攻略 | 学习深度学习只需要三个月的好方法
三行代码实现 TensorRT8.6 C++ 深度学习模型部署
实战 | YOLOv8+OpenCV 实现DM码定位检测与解析
对象检测边界框损失 – 从IOU到ProbIOU
初学者必看 | 学习深度学习的五个误区