|
| 1 | +from magic_pdf.libs.boxbase import _is_part_overlap, _is_in |
| 2 | + |
| 3 | +def get_center_point(bbox): |
| 4 | + """ |
| 5 | + 根据边界框坐标信息,计算出该边界框的中心点坐标。 |
| 6 | + Args: |
| 7 | + bbox (list): 边界框坐标信息,包含四个元素,分别为左上角x坐标、左上角y坐标、右下角x坐标、右下角y坐标。 |
| 8 | + Returns: |
| 9 | + list: 中心点坐标信息,包含两个元素,分别为x坐标和y坐标。 |
| 10 | + """ |
| 11 | + return [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2] |
| 12 | + |
| 13 | + |
| 14 | +def get_area(bbox): |
| 15 | + """ |
| 16 | + 根据边界框坐标信息,计算出该边界框的面积。 |
| 17 | + Args: |
| 18 | + bbox (list): 边界框坐标信息,包含四个元素,分别为左上角x坐标、左上角y坐标、右下角x坐标、右下角y坐标。 |
| 19 | + Returns: |
| 20 | + float: 该边界框的面积。 |
| 21 | + """ |
| 22 | + return (bbox[2] - bbox[0]) * (bbox[3] - bbox[1]) |
| 23 | + |
| 24 | + |
| 25 | +def adjust_layouts(layout_bboxes): |
| 26 | + # 遍历所有布局框 |
| 27 | + for i in range(len(layout_bboxes)): |
| 28 | + # 遍历当前布局框之后的布局框 |
| 29 | + for j in range(i + 1, len(layout_bboxes)): |
| 30 | + # 判断两个布局框是否重叠 |
| 31 | + if _is_part_overlap(layout_bboxes[i], layout_bboxes[j]): |
| 32 | + # 计算每个布局框的中心点坐标和面积 |
| 33 | + center_i = get_center_point(layout_bboxes[i]["layout_bbox"]) |
| 34 | + area_i = get_area(layout_bboxes[i]["layout_bbox"]) |
| 35 | + |
| 36 | + center_j = get_center_point(layout_bboxes[j]["layout_bbox"]) |
| 37 | + area_j = get_area(layout_bboxes[j]["layout_bbox"]) |
| 38 | + |
| 39 | + # 计算横向和纵向的距离差 |
| 40 | + dx = abs(center_i[0] - center_j[0]) |
| 41 | + dy = abs(center_i[1] - center_j[1]) |
| 42 | + |
| 43 | + # 较大布局框和较小布局框的赋值 |
| 44 | + if area_i > area_j: |
| 45 | + larger_layout, smaller_layout = layout_bboxes[i], layout_bboxes[j] |
| 46 | + else: |
| 47 | + larger_layout, smaller_layout = layout_bboxes[j], layout_bboxes[i] |
| 48 | + |
| 49 | + # 根据距离差判断重叠方向并修正边界 |
| 50 | + if dx > dy: # 左右重叠 |
| 51 | + if larger_layout["layout_bbox"][0] < smaller_layout["layout_bbox"][2]: |
| 52 | + larger_layout["layout_bbox"][0] = smaller_layout["layout_bbox"][2] |
| 53 | + else: |
| 54 | + larger_layout["layout_bbox"][2] = smaller_layout["layout_bbox"][0] |
| 55 | + else: # 上下重叠 |
| 56 | + if larger_layout["layout_bbox"][1] < smaller_layout["layout_bbox"][3]: |
| 57 | + larger_layout["layout_bbox"][1] = smaller_layout["layout_bbox"][3] |
| 58 | + else: |
| 59 | + larger_layout["layout_bbox"][3] = smaller_layout["layout_bbox"][1] |
| 60 | + |
| 61 | + # 返回排序调整后的布局边界框列表 |
| 62 | + return layout_bboxes |
| 63 | + |
| 64 | + |
| 65 | + |
| 66 | + |
| 67 | +def layout_detect(layout_info): |
| 68 | + """ |
| 69 | + 对输入的布局信息进行解析,提取出每个子布局的边界框,并对所有子布局进行排序调整。 |
| 70 | +
|
| 71 | + Args: |
| 72 | + layout_info (list): 包含子布局信息的列表,每个子布局信息为字典类型,包含'poly'字段,表示子布局的边界框坐标信息。 |
| 73 | +
|
| 74 | + Returns: |
| 75 | + list: 经过排序调整后的所有子布局边界框信息的列表,每个边界框信息为字典类型,包含'layout_bbox'字段,表示边界框的坐标信息。 |
| 76 | +
|
| 77 | + """ |
| 78 | + # 初始化布局边界框列表 |
| 79 | + layout_bboxes = [] |
| 80 | + # 遍历每个子布局 |
| 81 | + for sub_layout in layout_info: |
| 82 | + # 提取子布局的边界框坐标信息 |
| 83 | + x0, y0, _, _, x1, y1, _, _ = sub_layout['poly'] |
| 84 | + # 创建子布局的边界框字典 |
| 85 | + layout_bbox = { |
| 86 | + "layout_bbox": [x0, y0, x1, y1], |
| 87 | + } |
| 88 | + # 将子布局的边界框添加到列表中 |
| 89 | + layout_bboxes.append(layout_bbox) |
| 90 | + |
| 91 | + # 初始化新的布局边界框列表 |
| 92 | + new_layout_bboxes = [] |
| 93 | + # 遍历每个布局边界框 |
| 94 | + for i in range(len(layout_bboxes)): |
| 95 | + # 初始化标记变量,用于判断当前边界框是否需要保留 |
| 96 | + keep = True |
| 97 | + # 获取当前边界框的坐标信息 |
| 98 | + box_i = layout_bboxes[i]["layout_bbox"] |
| 99 | + |
| 100 | + # 遍历其他边界框 |
| 101 | + for j in range(len(layout_bboxes)): |
| 102 | + # 排除当前边界框自身 |
| 103 | + if i != j: |
| 104 | + # 获取其他边界框的坐标信息 |
| 105 | + box_j = layout_bboxes[j]["layout_bbox"] |
| 106 | + # 检测box_i是否被box_j包含 |
| 107 | + if _is_in(box_i, box_j): |
| 108 | + # 如果当前边界框被其他边界框包含,则标记为不需要保留 |
| 109 | + keep = False |
| 110 | + # 跳出内层循环 |
| 111 | + break |
| 112 | + |
| 113 | + # 如果当前边界框需要保留,则添加到新的布局边界框列表中 |
| 114 | + if keep: |
| 115 | + new_layout_bboxes.append(layout_bboxes[i]) |
| 116 | + |
| 117 | + # 对新的布局边界框列表进行排序调整 |
| 118 | + layout_bboxes = adjust_layouts(new_layout_bboxes) |
| 119 | + |
| 120 | + # 返回排序调整后的布局边界框列表 |
| 121 | + return layout_bboxes |
| 122 | + |
| 123 | + |
0 commit comments