Spaces:
Running
Running
| 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 |