Files
2026-07-13 12:46:08 +08:00

352 lines
12 KiB
Python

from __future__ import print_function, division, absolute_import
import warnings
import sys
# unittest only added in 3.4 self.subTest()
if sys.version_info[0] < 3 or sys.version_info[1] < 4:
import unittest2 as unittest
else:
import unittest
# unittest.mock is not available in 2.7 (though unittest2 might contain it?)
try:
import unittest.mock as mock
except ImportError:
import mock
import numpy as np
import imgaug as ia
import imgaug.data as iadata
from imgaug.data import _quokka_normalize_extract, _compute_resized_shape
class Test__quokka_normalize_extract(unittest.TestCase):
def test_string_square(self):
observed = _quokka_normalize_extract("square")
assert isinstance(observed, ia.BoundingBox)
assert observed.x1 == 0
assert observed.y1 == 0
assert observed.x2 == 643
assert observed.y2 == 643
def test_tuple(self):
observed = _quokka_normalize_extract((1, 1, 644, 642))
assert isinstance(observed, ia.BoundingBox)
assert observed.x1 == 1
assert observed.y1 == 1
assert observed.x2 == 644
assert observed.y2 == 642
def test_boundingbox(self):
observed = _quokka_normalize_extract(ia.BoundingBox(x1=1, y1=1, x2=644, y2=642))
assert isinstance(observed, ia.BoundingBox)
assert observed.x1 == 1
assert observed.y1 == 1
assert observed.x2 == 644
assert observed.y2 == 642
def test_boundingboxesonimage(self):
observed = _quokka_normalize_extract(
ia.BoundingBoxesOnImage([
ia.BoundingBox(x1=1, y1=1, x2=644, y2=642)
],
shape=(643, 960, 3)
)
)
assert isinstance(observed, ia.BoundingBox)
assert observed.x1 == 1
assert observed.y1 == 1
assert observed.x2 == 644
assert observed.y2 == 642
def test_wrong_input_type(self):
got_exception = False
try:
_ = _quokka_normalize_extract(False)
except Exception as exc:
assert "Expected 'square' or tuple" in str(exc)
got_exception = True
assert got_exception
class Test__compute_resized_shape(unittest.TestCase):
def test_to_shape_is_tuple_of_ints_2d(self):
from_shape = (10, 15, 3)
to_shape = (20, 30)
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == (20, 30, 3)
def test_to_shape_is_tuple_of_ints_3d(self):
from_shape = (10, 15, 3)
to_shape = (20, 30, 3)
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == (20, 30, 3)
def test_to_shape_is_tuple_of_floats(self):
from_shape = (10, 15, 3)
to_shape = (2.0, 3.0)
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == (20, 45, 3)
def test_to_shape_is_float_and_int(self):
# tuple of int and float
from_shape = (10, 15, 3)
to_shape = (2.0, 25)
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == (20, 25, 3)
def test_to_shape_is_int_and_float(self):
from_shape = (10, 17, 3)
to_shape = (15, 2.0)
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == (15, 34, 3)
def test_to_shape_is_none(self):
from_shape = (10, 10, 3)
to_shape = None
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == from_shape
def test_to_shape_is_int_and_none(self):
from_shape = (10, 15, 3)
to_shape = (2.0, None)
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == (20, 15, 3)
def test_to_shape_is_none_and_int(self):
from_shape = (10, 15, 3)
to_shape = (None, 25)
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == (10, 25, 3)
def test_to_shape_is_single_int(self):
from_shape = (10, 15, 3)
to_shape = 20
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == (20, 20, 3)
def test_to_shape_is_float(self):
from_shape = (10, 15, 3)
to_shape = 2.0
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == (20, 30, 3)
def test_from_shape_and_to_shape_are_arrays(self):
# from/to shape as arrays
from_shape = (10, 10, 3)
to_shape = (20, 30, 3)
observed = _compute_resized_shape(
np.zeros(from_shape),
np.zeros(to_shape)
)
assert observed == to_shape
def test_from_shape_is_2d_and_to_shape_is_2d(self):
# from_shape is 2D
from_shape = (10, 15)
to_shape = (20, 30)
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == to_shape
def test_from_shape_is_2d_and_to_shape_is_3d(self):
from_shape = (10, 15)
to_shape = (20, 30, 3)
observed = _compute_resized_shape(from_shape, to_shape)
assert observed == (20, 30, 3)
# we are intentionally a bit looser here with atol=0.1, because
# apparently on some systems there are small differences in what
# exactly is loaded, see issue #414
class Test_quokka(unittest.TestCase):
def test_no_parameters(self):
img = iadata.quokka()
assert img.shape == (643, 960, 3)
assert np.allclose(
np.average(img, axis=(0, 1)),
[107.93576659, 118.18765066, 122.99378564],
rtol=0, atol=0.1
)
def test_extract_square(self):
img = iadata.quokka(extract="square")
assert img.shape == (643, 643, 3)
assert np.allclose(
np.average(img, axis=(0, 1)),
[111.25929196, 121.19431175, 125.71316898],
rtol=0, atol=0.1
)
def test_size_tuple_of_ints(self):
img = iadata.quokka(size=(642, 959))
assert img.shape == (642, 959, 3)
assert np.allclose(
np.average(img, axis=(0, 1)),
[107.84615822, 118.09832412, 122.90446467],
rtol=0, atol=0.1
)
# we are intentionally a bit looser here with atol=0.1, because apparently
# on some systems there are small differences in what exactly is loaded,
# see issue #414
class Test_quokka_square(unittest.TestCase):
def test_standard_call(self):
img = iadata.quokka_square()
assert img.shape == (643, 643, 3)
assert np.allclose(
np.average(img, axis=(0, 1)),
[111.25929196, 121.19431175, 125.71316898],
rtol=0, atol=0.1
)
# we are intentionally a bit looser here with atol=0.1, because apparently
# on some systems there are small differences in what exactly is loaded,
# see issue #414
class Test_quokka_heatmap(unittest.TestCase):
def test_no_parameters(self):
hm = iadata.quokka_heatmap()
assert hm.shape == (643, 960, 3)
assert hm.arr_0to1.shape == (643, 960, 1)
assert np.allclose(
np.average(hm.arr_0to1),
0.57618505,
rtol=0,
atol=1e-3
)
def test_extract_square(self):
hm = iadata.quokka_heatmap(extract="square")
assert hm.shape == (643, 643, 3)
assert hm.arr_0to1.shape == (643, 643, 1)
# TODO this value is 0.48026073 in python 2.7, while 0.48026952 in
# 3.7 -- why?
assert np.allclose(
np.average(hm.arr_0to1),
0.48026952,
rtol=0,
atol=1e-3
)
def test_size_tuple_of_ints(self):
hm = iadata.quokka_heatmap(size=(642, 959))
assert hm.shape == (642, 959, 3)
assert hm.arr_0to1.shape == (642, 959, 1)
assert np.allclose(
np.average(hm.arr_0to1),
0.5762454,
rtol=0,
atol=1e-3
)
class Test_quokka_segmentation_map(unittest.TestCase):
def test_no_parameters(self):
segmap = iadata.quokka_segmentation_map()
assert segmap.shape == (643, 960, 3)
assert segmap.arr.shape == (643, 960, 1)
assert np.allclose(np.average(segmap.arr), 0.3016427, rtol=0, atol=1e-3)
def test_extract_square(self):
segmap = iadata.quokka_segmentation_map(extract="square")
assert segmap.shape == (643, 643, 3)
assert segmap.arr.shape == (643, 643, 1)
assert np.allclose(np.average(segmap.arr), 0.450353, rtol=0, atol=1e-3)
def test_size_is_tuple_of_ints(self):
segmap = iadata.quokka_segmentation_map(size=(642, 959))
assert segmap.shape == (642, 959, 3)
assert segmap.arr.shape == (642, 959, 1)
assert np.allclose(np.average(segmap.arr), 0.30160266, rtol=0, atol=1e-3)
class Test_quokka_keypoints(unittest.TestCase):
def test_non_parameters(self):
kpsoi = iadata.quokka_keypoints()
assert len(kpsoi.keypoints) > 0
assert np.allclose(kpsoi.keypoints[0].x, 163.0)
assert np.allclose(kpsoi.keypoints[0].y, 78.0)
assert kpsoi.shape == (643, 960, 3)
def test_non_square_vs_square(self):
kpsoi = iadata.quokka_keypoints()
img = iadata.quokka()
patches = []
for kp in kpsoi.keypoints:
bb = ia.BoundingBox(x1=kp.x-1, x2=kp.x+2, y1=kp.y-1, y2=kp.y+2)
patches.append(bb.extract_from_image(img))
img_square = iadata.quokka(extract="square")
kpsoi_square = iadata.quokka_keypoints(extract="square")
assert len(kpsoi.keypoints) == len(kpsoi_square.keypoints)
assert kpsoi_square.shape == (643, 643, 3)
for kp, patch in zip(kpsoi_square.keypoints, patches):
bb = ia.BoundingBox(x1=kp.x-1, x2=kp.x+2, y1=kp.y-1, y2=kp.y+2)
patch_square = bb.extract_from_image(img_square)
assert np.average(
np.abs(
patch.astype(np.float32)
- patch_square.astype(np.float32)
)
) < 1.0
def test_size_is_tuple_of_ints(self):
kpsoi = iadata.quokka_keypoints()
kpsoi_resized = iadata.quokka_keypoints(size=(642, 959))
assert kpsoi_resized.shape == (642, 959, 3)
assert len(kpsoi.keypoints) == len(kpsoi_resized.keypoints)
for kp, kp_resized in zip(kpsoi.keypoints, kpsoi_resized.keypoints):
d = np.sqrt(
(kp.x - kp_resized.x) ** 2
+ (kp.y - kp_resized.y) ** 2
)
assert d < 1.0
class Test_quokka_bounding_boxes(unittest.TestCase):
def test_no_parameters(self):
bbsoi = iadata.quokka_bounding_boxes()
assert len(bbsoi.bounding_boxes) > 0
bb0 = bbsoi.bounding_boxes[0]
assert np.allclose(bb0.x1, 148.0)
assert np.allclose(bb0.y1, 50.0)
assert np.allclose(bb0.x2, 550.0)
assert np.allclose(bb0.y2, 642.0)
assert bbsoi.shape == (643, 960, 3)
def test_non_square_vs_square(self):
bbsoi = iadata.quokka_bounding_boxes()
img = iadata.quokka()
patches = []
for bb in bbsoi.bounding_boxes:
patches.append(bb.extract_from_image(img))
img_square = iadata.quokka(extract="square")
bbsoi_square = iadata.quokka_bounding_boxes(extract="square")
assert len(bbsoi.bounding_boxes) == len(bbsoi_square.bounding_boxes)
assert bbsoi_square.shape == (643, 643, 3)
for bb, patch in zip(bbsoi_square.bounding_boxes, patches):
patch_square = bb.extract_from_image(img_square)
assert np.average(
np.abs(
patch.astype(np.float32)
- patch_square.astype(np.float32)
)
) < 1.0
def test_size_is_tuple_of_ints(self):
bbsoi = iadata.quokka_bounding_boxes()
bbsoi_resized = iadata.quokka_bounding_boxes(size=(642, 959))
assert bbsoi_resized.shape == (642, 959, 3)
assert len(bbsoi.bounding_boxes) == len(bbsoi_resized.bounding_boxes)
for bb, bb_resized in zip(bbsoi.bounding_boxes,
bbsoi_resized.bounding_boxes):
d = np.sqrt(
(bb.center_x - bb_resized.center_x) ** 2
+ (bb.center_y - bb_resized.center_y) ** 2
)
assert d < 1.0