Skip to content

Commit 8a77cfa

Browse files
CopilotBorda
andauthored
Fix: extended_metrics raises clear ValueError when IoU=0.50 absent from iouThrs (#75)
* Initial plan * Fix extended_metrics ValueError when IoU=0.50 absent from iouThrs; add tests Co-authored-by: Borda <6035284+Borda@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Borda <6035284+Borda@users.noreply.github.com>
1 parent f7a49fc commit 8a77cfa

2 files changed

Lines changed: 64 additions & 1 deletion

File tree

faster_coco_eval/core/faster_eval_api.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,13 @@ def extended_metrics(self):
235235
iou_thrs, rec_thrs = self.params.iouThrs, self.params.recThrs
236236

237237
# Indices for IoU=0.50, first area, and last max dets
238-
iou50_idx, area_idx, maxdet_idx = (np.argwhere(np.isclose(iou_thrs, 0.50)).item(), 0, -1)
238+
_iou50_hits = np.where(np.isclose(iou_thrs, 0.50))[0]
239+
if len(_iou50_hits) == 0:
240+
raise ValueError(
241+
"extended_metrics requires IoU threshold 0.50, "
242+
f"but it is not present in params.iouThrs={iou_thrs.tolist()}."
243+
)
244+
iou50_idx, area_idx, maxdet_idx = (int(_iou50_hits[0]), 0, -1)
239245
P = self.eval["precision"]
240246
S = self.eval["scores"]
241247

tests/test_simple_extra.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import numpy as np
44
import pytest
55

6+
from faster_coco_eval import COCO, COCOeval_faster
67
from faster_coco_eval.extra.extra import ExtraEval
78

89

@@ -165,3 +166,59 @@ def test_fn_image_ann_map_with_fns():
165166
assert len(fn_map) == 2
166167
assert fn_map[1] == {1, 2}
167168
assert fn_map[2] == {4}
169+
170+
171+
def _make_coco_eval(iou_thrs=None):
172+
"""Helper: build a minimal COCOeval_faster with optional custom iouThrs."""
173+
image_id = 1
174+
SIZE = 200
175+
bbox = [0.0, 0.0, float(SIZE), float(SIZE)]
176+
177+
coco_gt = COCO()
178+
coco_gt.dataset = {
179+
"images": [{"id": image_id, "width": 1000, "height": 1000}],
180+
"annotations": [
181+
{
182+
"id": 1,
183+
"image_id": image_id,
184+
"category_id": 1,
185+
"bbox": bbox,
186+
"area": SIZE * SIZE,
187+
"iscrowd": 0,
188+
}
189+
],
190+
"categories": [{"id": 1, "name": "cat1"}],
191+
}
192+
coco_gt.createIndex()
193+
194+
pred_bbox = [10.0, 10.0, float(SIZE - 20), float(SIZE - 20)]
195+
coco_dt = coco_gt.loadRes([
196+
{"image_id": image_id, "category_id": 1, "bbox": pred_bbox, "score": 0.9}
197+
])
198+
199+
coco_eval = COCOeval_faster(coco_gt, coco_dt, iouType="bbox")
200+
if iou_thrs is not None:
201+
coco_eval.params.iouThrs = np.array(iou_thrs)
202+
coco_eval.evaluate()
203+
coco_eval.accumulate()
204+
coco_eval.summarize()
205+
return coco_eval
206+
207+
208+
def test_extended_metrics_raises_when_iou50_missing():
209+
"""extended_metrics must raise ValueError when 0.50 is absent from iouThrs."""
210+
coco_eval = _make_coco_eval(iou_thrs=[0.55, 0.65, 0.75, 0.85, 0.95])
211+
with pytest.raises(ValueError, match="0.50"):
212+
_ = coco_eval.extended_metrics
213+
214+
215+
def test_extended_metrics_works_with_iou50():
216+
"""extended_metrics must succeed when 0.50 is present in iouThrs."""
217+
# Default iouThrs includes 0.50
218+
coco_eval = _make_coco_eval()
219+
220+
result = coco_eval.extended_metrics
221+
assert "map" in result
222+
assert "precision" in result
223+
assert "recall" in result
224+
assert "class_map" in result

0 commit comments

Comments
 (0)