opencv进行rect检测时,当检测到多个rect,组成rect vector之后,有些rect是由一个区域误分割得到的,

可以按照某种规格将这些rect合并为一个rect。比如按照x,y,width,height特性。

可以先按照x坐标或者y坐标排序。

//按照X坐标排序
bool BOCR::rect_rank_x(vector<Rect> &vec_rects) {
Rect vec_temp;
for (int l = 1; l < vec_rects.size(); l++) {
for (int m = vec_rects.size() - 1; m >= l; m--) {
if (vec_rects[m].x < vec_rects[m - 1].x) {
vec_temp = vec_rects[m - 1];
vec_rects[m - 1] = vec_rects[m];
vec_rects[m] = vec_temp;
}
}
}
return true;
}
//按照X坐标排序
bool BOCR::rect_rank_y(vector<Rect> &vec_rects) {
Rect vec_temp;
for (int l = 1; l < vec_rects.size(); l++) {
for (int m = vec_rects.size() - 1; m >= l; m--) {
if (vec_rects[m].y < vec_rects[m - 1].y) {
vec_temp = vec_rects[m - 1];
vec_rects[m - 1] = vec_rects[m];
vec_rects[m] = vec_temp;
}
}
}
return true;
} /*将rect上下合并
* 参数:vec_rects:输入的所有的rect集合;
* vec_rects_out:输出的上下合并后的所有的rect集合;
* x_dif:进行上下合并的x差值;y_dif:进行上下合并的y差值;
* width:进行上下合并的width最大值;height:进行上下合并的height最大值;
width_rect:合并后的rect的width的值大于width_rect为满足条件
*/
bool BOCR::rect_combine_uplow(vector<Rect> &vec_rects,
vector<Rect>&vec_rects_out, int x_dif, int y_dif, int width, int height,
int width_rect) {
rect_rank_y(vec_rects);
//将上下部分分裂的,合并
int num_rect = vec_rects.size();
for (int j = 0; j < num_rect; j++) {
if (vec_rects[j].width > 0) {
Rect r;
for (int p = 0; p < num_rect; p++) {
if ((vec_rects[p].width > 0) && (p > j || p < j)) {
if ((((abs(vec_rects[p].x - vec_rects[j].x) < x_dif)
|| (abs(
vec_rects[p].x + vec_rects[p].width
- vec_rects[j].x
- vec_rects[j].width) < x_dif))
&& ((abs(
vec_rects[p].y
- (vec_rects[j].y
+ vec_rects[j].height))
< y_dif)
|| (abs(
vec_rects[j].y
- (vec_rects[p].y
+ vec_rects[p].height))
< y_dif))
&& (vec_rects[p].height < height)
&& (vec_rects[j].height < height)
&& (vec_rects[p].width < width)
&& (vec_rects[j].width < width))) { r.x = min(vec_rects[j].x, vec_rects[p].x);
r.y = min(vec_rects[j].y, vec_rects[p].y);
r.width = max(
vec_rects[p].x + vec_rects[p].width
- vec_rects[j].x,
vec_rects[j].x + vec_rects[j].width
- vec_rects[p].x);
r.height = max(
vec_rects[j].y + vec_rects[j].height
- vec_rects[p].y,
vec_rects[p].y + vec_rects[p].height
- vec_rects[j].y);
if (vec_rects[p].y < vec_rects[j].y) {
vec_rects[p].width = 0;
vec_rects[p].x = 0;
vec_rects[p].height = 0;
vec_rects[p].y = 0;
vec_rects[j] = r;
} else {
vec_rects[j].width = 0;
vec_rects[j].x = 0;
vec_rects[j].height = 0;
vec_rects[j].y = 0;
vec_rects[p] = r;
} }
}
}
}
} for (int j = 0; j < num_rect; j++) {
if (vec_rects[j].width > width_rect) {
vec_rects_out.push_back(vec_rects[j]);
}
}
return true;
} /*将rect左右合并
* 参数:
* show:输入图像;
* vec_rects:输入的所有的rect集合;
* vec_rects_out:输出的左右合并后的所有的rect集合;
* x_dif:进行左右合并的x差值;y_dif:进行左右合并的y差值;
* width:进行左右合并的width最大值;height:进行左右合并的height最大值;
* rate1:rect的长宽比最小值1;rate2:rect的长宽比最小值2;
* width_rect:合并后的rect的width的值大于width_rect为满足条件
*/
bool BOCR::rect_combine_leftright(Mat & show, vector<Rect> &vec_rects,
vector<Rect>&vec_rects_out, int x_dif, int y_dif, int width, int height,
double rate1, double rate2, int width_rect) {
int num = vec_rects.size();
for (int j = 0; j < num - 1; j++) {
if (vec_rects[j].width > 0) {
for (int q = j + 1; q < num; q++) {
if (vec_rects[q].width > 0) {
Rect r;
if ((max(vec_rects[q].x - x_dif, 0)
< min(vec_rects[j].x + vec_rects[j].width,
show.cols))
&& ((abs(vec_rects[q].y - vec_rects[j].y) < y_dif)
|| (abs(
min(
vec_rects[q].y
+ vec_rects[q].height,
show.rows)
- min(
vec_rects[j].y
+ vec_rects[j].height,
show.rows)) < y_dif))
&& (vec_rects[q].width < width)
&& (vec_rects[j].width < width)
&& (((vec_rects[q].height
/ (double) vec_rects[q].width > rate1)
&& (vec_rects[j].height
/ (double) vec_rects[j].width
> rate2))
|| ((vec_rects[j].height
/ (double) vec_rects[j].width
> rate1)
&& (vec_rects[q].height
/ (double) vec_rects[q].width
> rate2)))) {
if ((vec_rects[j].x + vec_rects[j].width
> show.cols / 10 * 8.5)
&& (vec_rects[q].x > show.cols / 10 * 8.5)
&& abs(vec_rects[j].width - vec_rects[q].width)
< 4
&& abs(
vec_rects[j].height
- vec_rects[q].height) < 3) {
;
} else {
r.x = vec_rects[j].x;
r.y = min(vec_rects[j].y, vec_rects[q].y);
r.width = vec_rects[q].x + vec_rects[q].width
- vec_rects[j].x;
r.height = max(vec_rects[j].y + vec_rects[j].height,
vec_rects[q].y + vec_rects[q].height) - r.y;
vec_rects[q].width = 0;
vec_rects[q].x = 0;
vec_rects[j] = r;
}
}
}
}
}
}
for (int j = 0; j < num; j++) {
if (vec_rects[j].width > width_rect) {
vec_rects_out.push_back(vec_rects[j]);
}
}
return true;
}
————————————————
版权声明:本文为CSDN博主「等待破茧」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/boon_228/article/details/51491789

图像处理opencv-Rect 排序、合并[转]的更多相关文章

  1. Python 图像处理 OpenCV (3):图像属性、图像感兴趣 ROI 区域及通道处理

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 图像属性 图像 ...

  2. Python 图像处理 OpenCV (16):图像直方图

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  3. 排序合并连接(sort merge join)的原理

    排序合并连接(sort merge join)的原理 排序合并连接(sort merge join)的原理     排序合并连接(sort merge join)       访问次数:两张表都只会访 ...

  4. oracle表连接------&gt;排序合并连接(Merge Sort Join)

    排序合并连接 (Sort Merge Join)是一种两个表在做连接时用排序操作(Sort)和合并操作(Merge)来得到连接结果集的连接方法. 对于排序合并连接的优缺点及适用场景例如以下: a,通常 ...

  5. oracle 表连接 - sort merge joins 排序合并连接

    https://blog.csdn.net/dataminer_2007/article/details/41907581一. sort merge joins连接(排序合并连接) 原理 指的是两个表 ...

  6. Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 普通操作 1. 读取像素 读取像素可以通过行坐标和列坐标来进行访问,灰度图像直接返回灰度值,彩色图像则返回B.G.R三个分量. 需 ...

  7. Python 图像处理 OpenCV (4):图像算数运算以及修改颜色空间

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  8. Python 图像处理 OpenCV (5):图像的几何变换

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  9. Python 图像处理 OpenCV (6):图像的阈值处理

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  10. Python 图像处理 OpenCV (7):图像平滑(滤波)处理

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

随机推荐

  1. [PE]结构分析与代码实现

    PE结构浅析 知识导向: 程序最开始是存放在磁盘上的,运行程序首先需要申请4GB的内存,将程序从磁盘copy到内存,但不是直接复制,而是进行拉伸处理. 这也就是为什么会有一个文件中地址和一个Virtu ...

  2. Linux基础命令---host域名查询工具

    host host是一个常用的DNS查询工具,经常用来查询域名.检查域名解析是否正确. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora.   1.语法       ...

  3. docker创建tomcat容器无法正常访问

    记一次创建tomcat docker容器后访问是404,进入到tomcat docker容器后发现webapps是空的 1.挂载 docker run -v localConfigFile:/cont ...

  4. redis入门到精通系列(二):redis操作的两个实践案例

    在前面一篇博客中我们已经学完了redis的五种数据类型操作,回顾一下,五种操作类型分别为:字符串类型(string).列表类型(list).散列类型(hash).集合类型(set).有序集合类型(so ...

  5. 数据源(Data Source

    数据源(Data Source)顾名思义,数据的来源,是提供某种所需要数据的器件或原始媒体.在数据源中存储了所有建立数据库连接的信息.就像通过指定文件名称可以在文件系统中找到文件一样,通过提供正确的数 ...

  6. 使用CORS处理跨域请求

    package com.leyou.gateway.config;import org.springframework.context.annotation.Bean;import org.sprin ...

  7. java异常处理中throws和throw的使用

    异常介绍: 运行时异常.非运行时异常 在编写可能会抛出异常的方法时,它们都必须声明为有异常. 一.throws关键字 1.声明方法可能抛出的异常: 2.写在方法名后面: 3.可声明抛出多个异常,异常名 ...

  8. 【Windows】github无法访问/hosts文件只能另存为txt

    因为我的github访问不了了,搜索解决方案为修改host文件 https://blog.csdn.net/curry10086/article/details/106800184/ 在hosts文件 ...

  9. 【Matlab】线性调频信号LFM 仿真

    [知识点] 生成序列 i = a:step:b 举例: i = 1:1:9 画图(子图) subplot(m,n,p)或者subplot(m n p) 总结起来就是,画一个m行n列的图. p表示在第p ...

  10. 网络协议之:还在用HTTP代理?弱爆了!快试试SOCKS5

    目录 简介 为什么要使用SOCKS SOCKS5 SOCKS5的使用 总结 简介 存在即是合理,SOCKS5的出现是为了解决SOCKS4中不支持身份认证的大问题而出现的,毕竟大家对网络中的安全越来越重 ...