feat: florence2_hires — mask-select index parser + tests
This commit is contained in:
@@ -62,3 +62,52 @@ def compute_target_dims(src_w, src_h, target_megapixels):
|
||||
new_w = max(64, min(4096, int(round(src_w * scale)) // 8 * 8))
|
||||
new_h = max(64, min(4096, int(round(src_h * scale)) // 8 * 8))
|
||||
return new_w, new_h
|
||||
|
||||
|
||||
def parse_mask_select_indices(user_input, detected_count):
|
||||
"""Parse user's output_mask_select string against detected region count.
|
||||
|
||||
Args:
|
||||
user_input: string from UI; "" = use all, "0" = first, "0,2" = specific indices.
|
||||
detected_count: how many regions Florence2 actually returned.
|
||||
|
||||
Returns:
|
||||
Tuple (indices: list[int], mode: str) where mode is one of:
|
||||
- "all": use all detected regions (caller should union)
|
||||
- "select": use the listed indices
|
||||
- "no_detection": no valid selection possible (caller should treat as miss)
|
||||
"""
|
||||
if detected_count <= 0:
|
||||
return [], "no_detection"
|
||||
|
||||
stripped = (user_input or "").strip()
|
||||
if not stripped:
|
||||
return [], "all"
|
||||
|
||||
raw_tokens = [t.strip() for t in stripped.split(",") if t.strip()]
|
||||
if not raw_tokens:
|
||||
return [], "all"
|
||||
|
||||
parsed = []
|
||||
for tok in raw_tokens:
|
||||
try:
|
||||
n = int(tok)
|
||||
except ValueError:
|
||||
return [], "no_detection"
|
||||
if n < 0:
|
||||
return [], "no_detection"
|
||||
if n < detected_count:
|
||||
parsed.append(n)
|
||||
# OOR indices silently dropped
|
||||
|
||||
if not parsed:
|
||||
return [], "no_detection"
|
||||
|
||||
# Stable dedupe preserving order
|
||||
seen = set()
|
||||
out = []
|
||||
for n in parsed:
|
||||
if n not in seen:
|
||||
seen.add(n)
|
||||
out.append(n)
|
||||
return out, "select"
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
"""Tests for parse_mask_select_indices() — converts user string to (indices, mode)."""
|
||||
import pytest
|
||||
|
||||
from florence2_hires import parse_mask_select_indices
|
||||
|
||||
|
||||
def test_empty_string_means_all():
|
||||
"""Empty string -> mode='all', indices=[]."""
|
||||
indices, mode = parse_mask_select_indices("", detected_count=3)
|
||||
assert mode == "all"
|
||||
assert indices == []
|
||||
|
||||
|
||||
def test_whitespace_only_means_all():
|
||||
indices, mode = parse_mask_select_indices(" ", detected_count=3)
|
||||
assert mode == "all"
|
||||
|
||||
|
||||
def test_single_index():
|
||||
indices, mode = parse_mask_select_indices("0", detected_count=3)
|
||||
assert mode == "select"
|
||||
assert indices == [0]
|
||||
|
||||
|
||||
def test_multiple_indices():
|
||||
indices, mode = parse_mask_select_indices("0,2", detected_count=3)
|
||||
assert mode == "select"
|
||||
assert indices == [0, 2]
|
||||
|
||||
|
||||
def test_spaces_between_indices():
|
||||
indices, mode = parse_mask_select_indices("0, 1 , 2", detected_count=3)
|
||||
assert mode == "select"
|
||||
assert indices == [0, 1, 2]
|
||||
|
||||
|
||||
def test_out_of_range_index_returns_no_detection():
|
||||
"""Index >= detected_count -> mode='no_detection' (don't crash)."""
|
||||
indices, mode = parse_mask_select_indices("5", detected_count=3)
|
||||
assert mode == "no_detection"
|
||||
|
||||
|
||||
def test_some_in_range_some_out_keeps_in_range():
|
||||
"""Partial OOR -> keep the valid ones."""
|
||||
indices, mode = parse_mask_select_indices("0,5,1", detected_count=3)
|
||||
assert mode == "select"
|
||||
assert indices == [0, 1]
|
||||
|
||||
|
||||
def test_negative_index_treated_as_invalid():
|
||||
indices, mode = parse_mask_select_indices("-1", detected_count=3)
|
||||
assert mode == "no_detection"
|
||||
|
||||
|
||||
def test_garbage_input_returns_no_detection():
|
||||
indices, mode = parse_mask_select_indices("foo", detected_count=3)
|
||||
assert mode == "no_detection"
|
||||
|
||||
|
||||
def test_zero_detected_with_empty_request():
|
||||
"""Empty request + no detections -> no_detection."""
|
||||
indices, mode = parse_mask_select_indices("", detected_count=0)
|
||||
assert mode == "no_detection"
|
||||
Reference in New Issue
Block a user