1
1
import pytest
2
2
import numpy as np
3
- import cv2
3
+ import logging
4
4
from bbox_visualizer import bbox_visualizer
5
5
6
6
@pytest .fixture
@@ -18,6 +18,28 @@ def sample_label():
18
18
"""Create a sample label for testing."""
19
19
return "test"
20
20
21
+ def test_check_and_modify_bbox (sample_image ):
22
+ """Test bbox validation and modification."""
23
+ # Test negative coordinates
24
+ bbox = [- 10 , - 10 , 50 , 50 ]
25
+ result = bbox_visualizer .check_and_modify_bbox (bbox , sample_image .shape )
26
+ assert result [0 ] >= 0 and result [1 ] >= 0
27
+
28
+ # Test coordinates exceeding image size
29
+ bbox = [10 , 10 , 200 , 200 ]
30
+ result = bbox_visualizer .check_and_modify_bbox (bbox , sample_image .shape )
31
+ assert result [2 ] <= sample_image .shape [1 ]
32
+ assert result [3 ] <= sample_image .shape [0 ]
33
+
34
+ # Test with margin
35
+ bbox = [- 10 , - 10 , 200 , 200 ]
36
+ margin = 5
37
+ result = bbox_visualizer .check_and_modify_bbox (bbox , sample_image .shape , margin )
38
+ assert result [0 ] == margin
39
+ assert result [1 ] == margin
40
+ assert result [2 ] == sample_image .shape [1 ] - margin
41
+ assert result [3 ] == sample_image .shape [0 ] - margin
42
+
21
43
def test_draw_rectangle_basic (sample_image , sample_bbox ):
22
44
"""Test basic rectangle drawing functionality."""
23
45
result = bbox_visualizer .draw_rectangle (sample_image , sample_bbox )
@@ -35,32 +57,155 @@ def test_draw_rectangle_opaque(sample_image, sample_bbox):
35
57
assert result .shape == sample_image .shape
36
58
assert np .sum (result ) > 0
37
59
38
- def test_add_label (sample_image , sample_bbox , sample_label ):
60
+ def test_add_label (sample_image , sample_bbox , sample_label , caplog ):
39
61
"""Test adding label to bounding box."""
62
+ # Test normal case with top=True and enough space
63
+ bbox_with_space = [10 , 30 , 50 , 70 ] # Plenty of space above and below
40
64
result = bbox_visualizer .add_label (
41
- sample_image , sample_label , sample_bbox
65
+ sample_image , sample_label , bbox_with_space , top = True
66
+ )
67
+ assert isinstance (result , np .ndarray )
68
+ assert result .shape == sample_image .shape
69
+ assert np .sum (result ) > 0
70
+
71
+ # Test normal case with top=False and enough space
72
+ result = bbox_visualizer .add_label (
73
+ sample_image , sample_label , bbox_with_space , top = False
42
74
)
43
75
assert isinstance (result , np .ndarray )
44
76
assert result .shape == sample_image .shape
45
77
assert np .sum (result ) > 0
78
+
79
+ # Test with draw_bg=False for both top and bottom positions
80
+ result = bbox_visualizer .add_label (
81
+ sample_image , sample_label , bbox_with_space , draw_bg = False , top = True
82
+ )
83
+ assert isinstance (result , np .ndarray )
84
+ assert result .shape == sample_image .shape
85
+ assert np .sum (result ) > 0
86
+
87
+ result = bbox_visualizer .add_label (
88
+ sample_image , sample_label , bbox_with_space , draw_bg = False , top = False
89
+ )
90
+ assert isinstance (result , np .ndarray )
91
+ assert result .shape == sample_image .shape
92
+ assert np .sum (result ) > 0
93
+
94
+ # Test label at top when there's not enough space
95
+ bbox_at_top = [10 , 5 , 50 , 20 ] # Very close to top of image
96
+ result = bbox_visualizer .add_label (
97
+ sample_image , sample_label , bbox_at_top , top = True
98
+ )
99
+ assert isinstance (result , np .ndarray )
100
+ assert result .shape == sample_image .shape
101
+
102
+ # Test label at bottom when there's not enough space
103
+ bbox_at_bottom = [10 , 80 , 50 , 99 ] # Very close to bottom of image
104
+ result = bbox_visualizer .add_label (
105
+ sample_image , sample_label , bbox_at_bottom , top = False
106
+ )
107
+ assert isinstance (result , np .ndarray )
108
+ assert result .shape == sample_image .shape
46
109
47
- def test_add_T_label (sample_image , sample_bbox , sample_label ):
110
+ def test_add_T_label (sample_image , sample_bbox , sample_label , caplog ):
48
111
"""Test adding T-label to bounding box."""
112
+ # Test normal case with enough space and background
113
+ bbox_with_space = [40 , 80 , 60 , 95 ] # Plenty of space above (at least 50 pixels)
49
114
result = bbox_visualizer .add_T_label (
50
- sample_image , sample_label , sample_bbox
115
+ sample_image , sample_label , bbox_with_space ,
116
+ draw_bg = True , text_bg_color = (255 , 0 , 0 ), # Red background to ensure visibility
117
+ size = 1 , thickness = 2 # Explicit size and thickness
51
118
)
52
119
assert isinstance (result , np .ndarray )
53
120
assert result .shape == sample_image .shape
54
121
assert np .sum (result ) > 0
122
+
123
+ # Test with draw_bg=False
124
+ result = bbox_visualizer .add_T_label (
125
+ sample_image , sample_label , bbox_with_space ,
126
+ draw_bg = False , text_color = (0 , 255 , 0 ), # Green text to ensure visibility
127
+ size = 1 , thickness = 2 # Explicit size and thickness
128
+ )
129
+ assert isinstance (result , np .ndarray )
130
+ assert result .shape == sample_image .shape
131
+ assert np .sum (result ) > 0
132
+
133
+ # Test with custom size and thickness
134
+ result = bbox_visualizer .add_T_label (
135
+ sample_image , sample_label , bbox_with_space ,
136
+ size = 2 , thickness = 3 , text_bg_color = (0 , 0 , 255 ), # Blue background
137
+ draw_bg = True # Explicit background drawing
138
+ )
139
+ assert isinstance (result , np .ndarray )
140
+ assert result .shape == sample_image .shape
141
+ assert np .sum (result ) > 0
142
+
143
+ # Test with a long label to ensure text width calculation
144
+ long_label = "This is a very long label"
145
+ result = bbox_visualizer .add_T_label (
146
+ sample_image , long_label , bbox_with_space ,
147
+ draw_bg = True , text_bg_color = (255 , 255 , 0 ), # Yellow background
148
+ size = 1 , thickness = 2 # Explicit size and thickness
149
+ )
150
+ assert isinstance (result , np .ndarray )
151
+ assert result .shape == sample_image .shape
152
+ assert np .sum (result ) > 0
153
+
154
+ # Test with a bbox that has enough vertical space but is close to image edges
155
+ bbox_near_edge = [5 , 80 , 25 , 95 ] # Close to left edge but plenty of space above
156
+ result = bbox_visualizer .add_T_label (
157
+ sample_image , sample_label , bbox_near_edge ,
158
+ draw_bg = True , text_bg_color = (255 , 0 , 255 ), # Magenta background
159
+ size = 1 , thickness = 2 # Explicit size and thickness
160
+ )
161
+ assert isinstance (result , np .ndarray )
162
+ assert result .shape == sample_image .shape
163
+ assert np .sum (result ) > 0
164
+
165
+ # Test fallback when label would go out of frame at top
166
+ bbox_at_top = [10 , 5 , 50 , 20 ] # Very close to top of image
167
+ caplog .clear ()
168
+ with caplog .at_level (logging .WARNING ):
169
+ result = bbox_visualizer .add_T_label (
170
+ sample_image , sample_label , bbox_at_top ,
171
+ draw_bg = True , text_bg_color = (128 , 128 , 128 ) # Gray background
172
+ )
173
+ assert "Labelling style 'T' going out of frame. Falling back to normal labeling." in caplog .text
174
+ assert isinstance (result , np .ndarray )
175
+ assert result .shape == sample_image .shape
176
+
177
+ # Test fallback when label would go out of frame on the right side
178
+ bbox_at_right = [80 , 30 , 99 , 50 ] # Very close to right edge of image
179
+ caplog .clear ()
180
+ with caplog .at_level (logging .WARNING ):
181
+ result = bbox_visualizer .add_T_label (
182
+ sample_image , sample_label , bbox_at_right ,
183
+ draw_bg = True , text_bg_color = (128 , 128 , 128 ) # Gray background
184
+ )
185
+ assert "Labelling style 'T' going out of frame. Falling back to normal labeling." in caplog .text
186
+ assert isinstance (result , np .ndarray )
187
+ assert result .shape == sample_image .shape
55
188
56
- def test_draw_flag_with_label (sample_image , sample_bbox , sample_label ):
189
+ def test_draw_flag_with_label (sample_image , sample_bbox , sample_label , caplog ):
57
190
"""Test drawing flag with label."""
191
+ # Test normal case
58
192
result = bbox_visualizer .draw_flag_with_label (
59
193
sample_image , sample_label , sample_bbox
60
194
)
61
195
assert isinstance (result , np .ndarray )
62
196
assert result .shape == sample_image .shape
63
197
assert np .sum (result ) > 0
198
+
199
+ # Test fallback when flag would go out of frame
200
+ bbox_at_top = [10 , 0 , 50 , 10 ] # At the very top of image
201
+ caplog .clear () # Clear any previous log messages
202
+ with caplog .at_level (logging .WARNING ):
203
+ result = bbox_visualizer .draw_flag_with_label (
204
+ sample_image , sample_label , bbox_at_top
205
+ )
206
+ assert "Labelling style 'Flag' going out of frame. Falling back to normal labeling." in caplog .text
207
+ assert isinstance (result , np .ndarray )
208
+ assert result .shape == sample_image .shape
64
209
65
210
def test_draw_multiple_rectangles (sample_image ):
66
211
"""Test drawing multiple rectangles."""
@@ -87,7 +232,6 @@ def test_add_multiple_T_labels(sample_image):
87
232
"""Test adding multiple T-labels."""
88
233
bboxes = [[10 , 10 , 30 , 30 ], [40 , 40 , 60 , 60 ]]
89
234
labels = ["obj1" , "obj2" ]
90
- # Note: The function internally sets size=1 and thickness=2
91
235
result = bbox_visualizer .add_multiple_T_labels (
92
236
sample_image , labels , bboxes
93
237
)
@@ -99,7 +243,6 @@ def test_draw_multiple_flags_with_labels(sample_image):
99
243
"""Test drawing multiple flags with labels."""
100
244
bboxes = [[10 , 10 , 30 , 30 ], [40 , 40 , 60 , 60 ]]
101
245
labels = ["obj1" , "obj2" ]
102
- # Note: The function internally sets size=1 and thickness=2
103
246
result = bbox_visualizer .draw_multiple_flags_with_labels (
104
247
sample_image , labels , bboxes
105
248
)
@@ -109,12 +252,17 @@ def test_draw_multiple_flags_with_labels(sample_image):
109
252
110
253
def test_invalid_bbox_values (sample_image ):
111
254
"""Test handling of invalid bbox values."""
112
- # Testing with invalid bbox coordinates (negative values)
113
- invalid_bbox = [- 10 , - 10 , 20 , 20 ]
255
+ # Test with coordinates outside image boundaries
256
+ invalid_bbox = [- 10 , - 10 , 150 , 150 ]
114
257
result = bbox_visualizer .draw_rectangle (sample_image , invalid_bbox )
115
- # The function should handle invalid coordinates by clipping them
116
258
assert isinstance (result , np .ndarray )
117
259
assert result .shape == sample_image .shape
260
+ # Check that bbox was clipped to image boundaries
261
+ modified_bbox = bbox_visualizer .check_and_modify_bbox (invalid_bbox , sample_image .shape )
262
+ assert modified_bbox [0 ] >= 0
263
+ assert modified_bbox [1 ] >= 0
264
+ assert modified_bbox [2 ] <= sample_image .shape [1 ]
265
+ assert modified_bbox [3 ] <= sample_image .shape [0 ]
118
266
119
267
def test_empty_inputs ():
120
268
"""Test handling of empty inputs for multiple object functions."""
0 commit comments