| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- from magic_pdf.config.drop_reason import DropReason
- from magic_pdf.libs.boxbase import _is_in, _is_part_overlap
- def _remove_overlap_between_bbox(bbox1, bbox2):
- if _is_part_overlap(bbox1, bbox2):
- ix0, iy0, ix1, iy1 = bbox1
- x0, y0, x1, y1 = bbox2
- diff_x = min(x1, ix1) - max(x0, ix0)
- diff_y = min(y1, iy1) - max(y0, iy0)
- if diff_y > diff_x:
- if x1 >= ix1:
- mid = (x0 + ix1) // 2
- ix1 = min(mid - 0.25, ix1)
- x0 = max(mid + 0.25, x0)
- else:
- mid = (ix0 + x1) // 2
- ix0 = max(mid + 0.25, ix0)
- x1 = min(mid - 0.25, x1)
- else:
- if y1 >= iy1:
- mid = (y0 + iy1) // 2
- y0 = max(mid + 0.25, y0)
- iy1 = min(iy1, mid - 0.25)
- else:
- mid = (iy0 + y1) // 2
- y1 = min(y1, mid - 0.25)
- iy0 = max(mid + 0.25, iy0)
- if ix1 > ix0 and iy1 > iy0 and y1 > y0 and x1 > x0:
- bbox1 = [ix0, iy0, ix1, iy1]
- bbox2 = [x0, y0, x1, y1]
- return bbox1, bbox2, None
- else:
- return bbox1, bbox2, DropReason.NEGATIVE_BBOX_AREA
- else:
- return bbox1, bbox2, None
- def _remove_overlap_between_bboxes(arr):
- drop_reasons = []
- N = len(arr)
- keeps = [True] * N
- res = [None] * N
- for i in range(N):
- for j in range(N):
- if i == j:
- continue
- if _is_in(arr[i]['bbox'], arr[j]['bbox']):
- keeps[i] = False
- for idx, v in enumerate(arr):
- if not keeps[idx]:
- continue
- for i in range(N):
- if res[i] is None:
- continue
- bbox1, bbox2, drop_reason = _remove_overlap_between_bbox(
- v['bbox'], res[i]['bbox']
- )
- if drop_reason is None:
- v['bbox'] = bbox1
- res[i]['bbox'] = bbox2
- else:
- if v['score'] > res[i]['score']:
- keeps[i] = False
- res[i] = None
- else:
- keeps[idx] = False
- drop_reasons.append(drop_reason)
- if keeps[idx]:
- res[idx] = v
- return res, drop_reasons
- def remove_overlap_between_bbox_for_span(spans):
- arr = [{'bbox': span['bbox'], 'score': span.get('score', 0.1)} for span in spans]
- res, drop_reasons = _remove_overlap_between_bboxes(arr)
- ret = []
- for i in range(len(res)):
- if res[i] is None:
- continue
- spans[i]['bbox'] = res[i]['bbox']
- ret.append(spans[i])
- return ret, drop_reasons
- def remove_overlap_between_bbox_for_block(all_bboxes):
- arr = [{'bbox': bbox[:4], 'score': bbox[-1]} for bbox in all_bboxes]
- res, drop_reasons = _remove_overlap_between_bboxes(arr)
- ret = []
- for i in range(len(res)):
- if res[i] is None:
- continue
- all_bboxes[i][:4] = res[i]['bbox']
- ret.append(all_bboxes[i])
- return ret, drop_reasons
|