图像处理opencv-Rect 排序、合并[转]

 

 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
posted @ 2019-09-19 14:59  Xu_Lin  阅读(1112)  评论(0编辑  收藏  举报