Skip to content

Commit 45a22d5

Browse files
committed
dev&test(extractor):ROI unique key inverse
1 parent df9a181 commit 45a22d5

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

src/ZooProcess_lib/ROI.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import dataclasses
2+
import re
23

34
from numpy import ndarray
45

@@ -25,3 +26,21 @@ def unique_visible_key(roi: ROI) -> str:
2526
height, width = roi.mask.shape[:2]
2627
keys = [hex(m)[2:].upper() for m in [roi.x, roi.y, width, height]]
2728
return f"x{keys[0]}y{keys[1]}w{keys[2]}h{keys[3]}"
29+
30+
31+
def box_from_key(key: str) -> tuple[int, int, int, int]:
32+
"""
33+
Inverse of unique_visible_key. Extracts the bounding box coordinates from a key string.
34+
35+
Args:
36+
key: A string in the format "x{hex_x}y{hex_y}w{hex_width}h{hex_height}"
37+
38+
Returns:
39+
A tuple of (x, y, width, height) as integers
40+
"""
41+
pattern = r"x([0-9A-F]+)y([0-9A-F]+)w([0-9A-F]+)h([0-9A-F]+)"
42+
match = re.match(pattern, key)
43+
if not match:
44+
raise ValueError(f"Invalid key format: {key}")
45+
x_hex, y_hex, width_hex, height_hex = match.groups()
46+
return int(x_hex, 16), int(y_hex, 16), int(width_hex, 16), int(height_hex, 16)

tests/test_roi.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import numpy as np
2+
import pytest
3+
4+
from ZooProcess_lib.ROI import ROI, unique_visible_key, box_from_key
5+
6+
7+
def test_unique_visible_key():
8+
"""Test that unique_visible_key generates the expected string format."""
9+
# Create a simple ROI
10+
mask = np.ones((40, 30), dtype=np.uint8) # height=40, width=30
11+
roi = ROI(x=10, y=20, mask=mask)
12+
13+
# Generate the key
14+
key = unique_visible_key(roi)
15+
16+
# Check the format and values
17+
assert key == "xAy14w1Eh28" # 10 in hex is A, 20 is 14, 30 is 1E, 40 is 28
18+
19+
20+
def test_box_from_key():
21+
"""Test that box_from_key correctly parses the key string."""
22+
# Test with a simple key
23+
key = "xAy14w1Eh28"
24+
x, y, width, height = box_from_key(key)
25+
26+
assert x == 10
27+
assert y == 20
28+
assert width == 30
29+
assert height == 40
30+
31+
32+
def test_roundtrip_conversion():
33+
"""Test that converting from ROI to key and back gives the original values."""
34+
# Create a simple ROI
35+
mask = np.ones((40, 30), dtype=np.uint8) # height=40, width=30
36+
roi = ROI(x=10, y=20, mask=mask)
37+
38+
# Convert to key and back
39+
key = unique_visible_key(roi)
40+
x, y, width, height = box_from_key(key)
41+
42+
# Check that we got the original values back
43+
assert x == roi.x
44+
assert y == roi.y
45+
assert width == roi.mask.shape[1]
46+
assert height == roi.mask.shape[0]
47+
48+
49+
def test_box_from_key_with_large_values():
50+
"""Test that box_from_key works with large hexadecimal values."""
51+
# Test with large values
52+
key = "x1ABCy2DEFw3456h789A"
53+
x, y, width, height = box_from_key(key)
54+
55+
assert x == 0x1ABC
56+
assert y == 0x2DEF
57+
assert width == 0x3456
58+
assert height == 0x789A
59+
60+
61+
def test_box_from_key_with_zero_values():
62+
"""Test that box_from_key works with zero values."""
63+
# Test with zero values
64+
key = "x0y0w0h0"
65+
x, y, width, height = box_from_key(key)
66+
67+
assert x == 0
68+
assert y == 0
69+
assert width == 0
70+
assert height == 0

0 commit comments

Comments
 (0)