feat: per-class max box fraction (REQ-188)
- labeling/preview/autolabel: max_box_frac + per-class max_box_fracs ceiling filter (0=none, 1=off) before NMS, mirrors min_box_frac - exemplar review-assist: ceiling before max_detections truncation; ExemplarLabelRequest + filter panel 'Max box size' slider - ClassParamsTable: MaxBox column; copy line now REQ-186 amended order: class <name> conf <v> iou <v> minbox <v> maxbox <v> container - docs: design/ui-spec/tasks updated (incl. stale 4-slider narrative)
This commit is contained in:
1 parent
dee58e4ae5
commit
d3a6aa49b6
13 files changed
+90
-25
No files matched your search
+21
-2
@@ -112,19 +112,23 @@ def label_image(
|
||||
threshold: float,
|
||||
iou_threshold: float = 0.8,
|
||||
min_box_frac: float = 0.0,
|
||||
max_box_frac: float = 1.0,
|
||||
exemplar_index: int = -1,
|
||||
exemplars: Optional[List[dict]] = None,
|
||||
thresholds: Optional[List[float]] = None,
|
||||
iou_by_class: Optional[Dict[int, float]] = None,
|
||||
min_box_fracs: Optional[List[float]] = None,
|
||||
max_box_fracs: Optional[List[float]] = None,
|
||||
container_ids: Optional[Set[int]] = None,
|
||||
) -> ImageResult:
|
||||
"""Detect every prompt in one image and return the surviving instances.
|
||||
|
||||
When `exemplars` are given, the prompt at `exemplar_index` also carries them
|
||||
as drawn box exemplars (REQ-172); every other prompt runs on text alone.
|
||||
`thresholds`, `iou_by_class` and `min_box_fracs` are per-prompt overrides
|
||||
aligned with `prompts` (REQ-181); classes without one use the global values.
|
||||
`thresholds`, `iou_by_class`, `min_box_fracs` and `max_box_fracs` are
|
||||
per-prompt overrides aligned with `prompts` (REQ-181); classes without one
|
||||
use the global values. `max_box_frac(s)` is the per-class size ceiling,
|
||||
1.0 = off (REQ-188).
|
||||
`container_ids` are prompt indices marked container (REQ-184) — the caller
|
||||
maps them, because detections still carry prompt-index class ids here."""
|
||||
try:
|
||||
@@ -160,6 +164,21 @@ def label_image(
|
||||
if (d.box[2] - d.box[0]) * (d.box[3] - d.box[1]) >= floor
|
||||
]
|
||||
|
||||
if max_box_fracs is not None:
|
||||
def _keep_max(det) -> bool:
|
||||
frac = max_box_fracs[det.class_id] if det.class_id < len(max_box_fracs) else max_box_frac
|
||||
if frac >= 1 or frac <= 0:
|
||||
return True
|
||||
ceiling = width * height * frac
|
||||
return (det.box[2] - det.box[0]) * (det.box[3] - det.box[1]) <= ceiling
|
||||
detections = [d for d in detections if _keep_max(d)]
|
||||
elif 0 < max_box_frac < 1:
|
||||
ceiling = width * height * max_box_frac
|
||||
detections = [
|
||||
d for d in detections
|
||||
if (d.box[2] - d.box[0]) * (d.box[3] - d.box[1]) <= ceiling
|
||||
]
|
||||
|
||||
return ImageResult(image_path, rel_path, width, height,
|
||||
deduplicate(detections, iou_threshold, iou_by_class=iou_by_class,
|
||||
container_ids=container_ids))
|
||||
Reference in new issue
Block a user