171 lines
4.7 KiB
Python
171 lines
4.7 KiB
Python
"""
|
|
Tests for expand_bbox function with uniform pixel padding.
|
|
|
|
Verifies that bbox expansion adds uniform padding on all sides,
|
|
clamps to image boundaries, and returns integer tuples.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from shared.bbox import expand_bbox
|
|
from shared.bbox.scale_strategy import UNIFORM_PAD
|
|
|
|
|
|
class TestExpandBboxUniformPadding:
|
|
"""Tests for uniform padding on all sides."""
|
|
|
|
def test_adds_uniform_pad_on_all_sides(self):
|
|
"""Verify default pad is applied equally on all four sides."""
|
|
bbox = (100, 200, 300, 250)
|
|
|
|
result = expand_bbox(
|
|
bbox=bbox,
|
|
image_width=1000,
|
|
image_height=1000,
|
|
)
|
|
|
|
assert result == (
|
|
100 - UNIFORM_PAD,
|
|
200 - UNIFORM_PAD,
|
|
300 + UNIFORM_PAD,
|
|
250 + UNIFORM_PAD,
|
|
)
|
|
|
|
def test_custom_pad_value(self):
|
|
"""Verify custom pad overrides default."""
|
|
bbox = (100, 200, 300, 250)
|
|
|
|
result = expand_bbox(
|
|
bbox=bbox,
|
|
image_width=1000,
|
|
image_height=1000,
|
|
pad=20,
|
|
)
|
|
|
|
assert result == (80, 180, 320, 270)
|
|
|
|
def test_zero_pad_returns_original(self):
|
|
"""Verify pad=0 returns original bbox as integers."""
|
|
bbox = (100, 200, 300, 250)
|
|
|
|
result = expand_bbox(
|
|
bbox=bbox,
|
|
image_width=1000,
|
|
image_height=1000,
|
|
pad=0,
|
|
)
|
|
|
|
assert result == (100, 200, 300, 250)
|
|
|
|
def test_all_field_types_get_same_padding(self):
|
|
"""Verify no field-specific expansion -- same result regardless of field."""
|
|
bbox = (100, 200, 300, 250)
|
|
|
|
result_a = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
result_b = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
|
|
assert result_a == result_b
|
|
|
|
|
|
class TestExpandBboxImageBoundaryClamping:
|
|
"""Tests for clamping to image boundaries."""
|
|
|
|
def test_clamps_x0_to_zero(self):
|
|
bbox = (5, 200, 100, 250)
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
|
|
assert result[0] == 0
|
|
|
|
def test_clamps_y0_to_zero(self):
|
|
bbox = (100, 3, 300, 50)
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
|
|
assert result[1] == 0
|
|
|
|
def test_clamps_x1_to_image_width(self):
|
|
bbox = (900, 200, 995, 250)
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
|
|
assert result[2] == 1000
|
|
|
|
def test_clamps_y1_to_image_height(self):
|
|
bbox = (100, 900, 300, 995)
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
|
|
assert result[3] == 1000
|
|
|
|
def test_corner_bbox_clamps_multiple_sides(self):
|
|
"""Bbox near top-left corner clamps both x0 and y0."""
|
|
bbox = (2, 3, 50, 60)
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
|
|
assert result[0] == 0
|
|
assert result[1] == 0
|
|
assert result[2] == 50 + UNIFORM_PAD
|
|
assert result[3] == 60 + UNIFORM_PAD
|
|
|
|
|
|
class TestExpandBboxReturnType:
|
|
"""Tests for return type and value format."""
|
|
|
|
def test_returns_tuple_of_four_ints(self):
|
|
bbox = (100.5, 200.3, 300.7, 250.9)
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
|
|
assert isinstance(result, tuple)
|
|
assert len(result) == 4
|
|
assert all(isinstance(v, int) for v in result)
|
|
|
|
def test_float_bbox_floors_correctly(self):
|
|
"""Verify float coordinates are converted to int properly."""
|
|
bbox = (100.7, 200.3, 300.2, 250.8)
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000, pad=0)
|
|
|
|
# int() truncates toward zero
|
|
assert result == (100, 200, 300, 250)
|
|
|
|
def test_returns_valid_bbox_ordering(self):
|
|
"""Verify x0 < x1 and y0 < y1."""
|
|
bbox = (100, 200, 300, 250)
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
|
|
x0, y0, x1, y1 = result
|
|
assert x0 < x1
|
|
assert y0 < y1
|
|
|
|
|
|
class TestExpandBboxEdgeCases:
|
|
"""Tests for edge cases."""
|
|
|
|
def test_small_bbox_with_large_pad(self):
|
|
"""Pad larger than bbox still works correctly."""
|
|
bbox = (100, 200, 105, 203) # 5x3 pixel bbox
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000, pad=50)
|
|
|
|
assert result == (50, 150, 155, 253)
|
|
|
|
def test_bbox_at_origin(self):
|
|
bbox = (0, 0, 50, 30)
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
|
|
assert result[0] == 0
|
|
assert result[1] == 0
|
|
|
|
def test_bbox_at_image_edge(self):
|
|
bbox = (950, 970, 1000, 1000)
|
|
|
|
result = expand_bbox(bbox=bbox, image_width=1000, image_height=1000)
|
|
|
|
assert result[2] == 1000
|
|
assert result[3] == 1000
|