2D四点矩形的空间排序,及重叠矩形合并

目标

对用四点表示的矩形组按从上到下,从左到右进行排序,并将重叠矩形合一。
例如

bboxs=[
        [[ 916, 1440],
        [ 987, 1440],
        [ 987, 1466],
        [ 916, 1466]],

       [[ 741, 1440],
        [ 826, 1440],
        [ 826, 1466],
        [ 741, 1466]],

       [[ 708, 1444],
        [ 748, 1437],
        [ 752, 1462],
        [ 712, 1468]],

       [[129, 2],
        [158, 2],
        [158, 28],
        [129, 28]],

       [[62, 0],
        [138, 0],
        [138, 30],
        [62, 30]],

       [[1, 0],
        [72, 0],
        [72, 30],
        [1, 30]]
    ]

代码

    ## 以从上往下,从左往右的顺序对box进行排序,依据每个box的左上点坐标
    def order_and_merge(boxes, y_thresh=2):
        boxes=boxes.tolist()
        boxess = copy.deepcopy(boxes)
        result_bbox = []
        # 依据每个矩形左上角坐标,从上往下排序
        for i in range(len(boxes)):
            boxesss = np.array(boxess)
            index_max = np.argmin(boxesss[:, :, 1][:, 0])
            result_bbox.append(boxess.pop(index_max))

        y_list = np.array(result_bbox)[:, :, 1][:, 0].tolist()
        x_list = np.array(result_bbox)[:, :, 0][:, 0].tolist()
        # print(y_list,x_list)
        # 统计y的类型数,及各类型出现的次数
        num, type_and_num = 1, []
        for i in range(len(y_list) - 1):
            if abs(y_list[i + 1] - y_list[i]) <= y_thresh:
                num += 1
            else:
                type_and_num.append(num)
                num = 1
            if (i + 1) == (len(y_list) - 1):
                type_and_num.append(num)
        # 对每排box进行排序排序
        index_count, x_, tmp, tmp_x = 0, [], [], 0
        for num in type_and_num:
            x_ = x_list[index_count:index_count + num]  # 0--num-1
            # 单独对一行进行排序 并 合并重合的box
            while 1:
                flag = 0
                for i in range(num - 1):
                    if x_[i] > x_[i + 1]:
                        tmp_x = x_[i + 1]
                        x_[i + 1] = x_[i]
                        x_[i] = tmp_x

                        tmp = copy.deepcopy(result_bbox[index_count + i + 1])
                        result_bbox[index_count + i + 1] = copy.deepcopy(result_bbox[index_count + i])
                        result_bbox[index_count + i] = copy.deepcopy(tmp)
                        flag += 1

                if flag == 0:
                    break

            # 对排序后的每行进行合并
            for i in range(num - 1):

                i += index_count
                l_l = min(result_bbox[i][0][0], result_bbox[i][3][0])
                l_r = max(result_bbox[i][1][0], result_bbox[i][2][0])
                r_l = min(result_bbox[i + 1][0][0], result_bbox[i + 1][3][0])
                r_r = max(result_bbox[i + 1][1][0], result_bbox[i + 1][2][0])
                up = max(result_bbox[i][0][1], result_bbox[i][1][1],
                         result_bbox[i + 1][0][1], result_bbox[i + 1][1][1])
                down = max(result_bbox[i][2][1], result_bbox[i][3][1],
                           result_bbox[i + 1][2][1], result_bbox[i + 1][3][1])
                if l_r > r_l:
                    result_bbox[i + 1] = [[l_l, up], [r_r, up], [r_r, down], [l_l, down]]
                    result_bbox[i] = 0
            index_count += num

        result = []
        for i in range(len(result_bbox)):
            if result_bbox[i] != 0:
                result.append(result_bbox[i])

        return np.array(result)
  if __name__=="__main__":
    bboxs=[
        [[ 916, 1440],
        [ 987, 1440],
        [ 987, 1466],
        [ 916, 1466]],

       [[ 741, 1440],
        [ 826, 1440],
        [ 826, 1466],
        [ 741, 1466]],

       [[ 708, 1444],
        [ 748, 1437],
        [ 752, 1462],
        [ 712, 1468]],

       [[129, 2],
        [158, 2],
        [158, 28],
        [129, 28]],

       [[62, 0],
        [138, 0],
        [138, 30],
        [62, 30]],

       [[1, 0],
        [72, 0],
        [72, 30],
        [1, 30]]
    ]
    print(np.array(bboxs).tolist())
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值