jebin2's picture
nec c
c59b15b
raw
history blame
2.85 kB
def remove_duplicate_boxes(boxes, compare_single=None, iou_threshold=0.7):
"""
Removes duplicate or highly overlapping boxes, keeping the larger one.
:param boxes: List of (x1, y1, x2, y2) boxes.
:param compare_single: Optional single box to compare against the list.
:param iou_threshold: IOU threshold to consider as duplicate.
:return:
- If compare_single is None: deduplicated list of boxes.
- If compare_single is provided: tuple (is_duplicate, updated_box_or_none)
"""
def compute_iou(boxA, boxB):
xA = max(boxA[0], boxB[0])
yA = max(boxA[1], boxB[1])
xB = min(boxA[2], boxB[2])
yB = min(boxA[3], boxB[3])
interArea = max(0, xB - xA) * max(0, yB - yA)
if interArea == 0:
return 0.0
boxAArea = (boxA[2] - boxA[0]) * (boxA[3] - boxA[1])
boxBArea = (boxB[2] - boxB[0]) * (boxB[3] - boxB[1])
return interArea / float(boxAArea + boxBArea - interArea)
def compute_area(box):
return (box[2] - box[0]) * (box[3] - box[1])
# Single comparison mode
if compare_single is not None:
single_area = compute_area(compare_single)
for existing_box in boxes:
iou = compute_iou(compare_single, existing_box)
if iou > iou_threshold:
existing_area = compute_area(existing_box)
if single_area > existing_area:
return True, compare_single # Keep new (larger) box
else:
return True, None # Existing box is better, discard new
return False, compare_single # No overlap found, keep it
# Bulk deduplication mode
unique_boxes = []
for box in boxes:
box_area = compute_area(box)
replaced_existing = False
# Check against existing unique boxes
for i, ubox in enumerate(unique_boxes):
if compute_iou(box, ubox) > iou_threshold:
ubox_area = compute_area(ubox)
# If current box is larger, replace the existing one
if box_area > ubox_area:
unique_boxes[i] = box
replaced_existing = True
# If existing box is larger or equal, ignore current box
break
# If no overlap found, add the box
if not replaced_existing and not any(compute_iou(box, ubox) > iou_threshold for ubox in unique_boxes):
unique_boxes.append(box)
print(f"βœ… Found {abs(len(unique_boxes) - len(boxes))} duplicates")
return unique_boxes
def count_panels_inside(target_box, other_boxes):
x1a, y1a, x2a, y2a = target_box
count = 0
for x1b, y1b, x2b, y2b in other_boxes:
if x1a <= x1b and y1a <= y1b and x2a >= x2b and y2a >= y2b:
count += 1
return count