2762 lines
101 KiB
Python
2762 lines
101 KiB
Python
from __future__ import print_function, division, absolute_import
|
|
|
|
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
|
|
from imgaug.testutils import reseed, wrap_shift_deprecation, assertWarns
|
|
from imgaug.augmentables.lines import LineString, LineStringsOnImage
|
|
from imgaug.augmentables.kps import Keypoint
|
|
from imgaug.augmentables.heatmaps import HeatmapsOnImage
|
|
|
|
|
|
class TestLineString_project_(unittest.TestCase):
|
|
@property
|
|
def _is_inplace(self):
|
|
return True
|
|
|
|
def _func(self, ls, from_shape, to_shape):
|
|
return ls.project_(from_shape, to_shape)
|
|
|
|
def test_project_to_2x_image_size(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls_proj = self._func(ls, (10, 10), (20, 20))
|
|
assert np.allclose(ls_proj.coords, [(0, 0), (2, 0), (4, 2)])
|
|
|
|
def test_project_to_2x_image_width(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls_proj = self._func(ls, (10, 10), (10, 20))
|
|
assert np.allclose(ls_proj.coords, [(0, 0), (2, 0), (4, 1)])
|
|
|
|
def test_project_to_2x_image_height(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls_proj = self._func(ls, (10, 10), (20, 10))
|
|
assert np.allclose(ls_proj.coords, [(0, 0), (1, 0), (2, 2)])
|
|
|
|
def test_inplaceness(self):
|
|
ls = ia.LineString([(0, 0), (1, 0)])
|
|
ls2 = self._func(ls, (10, 10), (10, 10))
|
|
if self._is_inplace:
|
|
assert ls is ls2
|
|
else:
|
|
assert ls is not ls2
|
|
|
|
|
|
class TestLineString_project(TestLineString_project_):
|
|
@property
|
|
def _is_inplace(self):
|
|
return False
|
|
|
|
def _func(self, ls, from_shape, to_shape):
|
|
return ls.project(from_shape, to_shape)
|
|
|
|
|
|
class TestLineString_shift_(unittest.TestCase):
|
|
@property
|
|
def _is_inplace(self):
|
|
return True
|
|
|
|
def _func(self, ls, *args, **kwargs):
|
|
def _func_impl():
|
|
return ls.shift_(*args, **kwargs)
|
|
|
|
return wrap_shift_deprecation(_func_impl, *args, **kwargs)
|
|
|
|
def test_shift_along_xy(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls_shift = self._func(ls.deepcopy(), x=1, y=2)
|
|
assert ls_shift.coords_almost_equals(
|
|
[(0+1, 0+2), (1+1, 0+2), (2+1, 1+2)])
|
|
|
|
def test_inplaceness(self):
|
|
ls = ia.LineString([(0, 0), (1, 0)])
|
|
ls2 = self._func(ls, y=0)
|
|
if self._is_inplace:
|
|
assert ls is ls2
|
|
else:
|
|
assert ls is not ls2
|
|
|
|
|
|
class TestLineString_shift(TestLineString_shift_):
|
|
@property
|
|
def _is_inplace(self):
|
|
return False
|
|
|
|
def _func(self, ls, *args, **kwargs):
|
|
def _func_impl():
|
|
return ls.shift(*args, **kwargs)
|
|
|
|
return wrap_shift_deprecation(_func_impl, *args, **kwargs)
|
|
|
|
def test_shift_by_positive_args(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
assert self._func(ls.deepcopy(), top=1).coords_almost_equals(
|
|
[(0, 1), (1, 1), (2, 2)])
|
|
assert self._func(ls.deepcopy(), right=1).coords_almost_equals(
|
|
[(-1, 0), (0, 0), (1, 1)])
|
|
assert self._func(ls.deepcopy(), bottom=1).coords_almost_equals(
|
|
[(0, -1), (1, -1), (2, 0)])
|
|
assert self._func(ls.deepcopy(), left=1).coords_almost_equals(
|
|
[(1, 0), (2, 0), (3, 1)])
|
|
|
|
def test_shift_by_negative_values(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
assert self._func(ls.deepcopy(), top=-1).coords_almost_equals(
|
|
[(0, -1), (1, -1), (2, 0)])
|
|
assert self._func(ls.deepcopy(), right=-1).coords_almost_equals(
|
|
[(1, 0), (2, 0), (3, 1)])
|
|
assert self._func(ls.deepcopy(), bottom=-1).coords_almost_equals(
|
|
[(0, 1), (1, 1), (2, 2)])
|
|
assert self._func(ls.deepcopy(), left=-1).coords_almost_equals(
|
|
[(-1, 0), (0, 0), (1, 1)])
|
|
|
|
def test_shift_by_positive_values_all_arguments_provided(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
assert self._func(
|
|
ls.deepcopy(), top=1, right=2, bottom=3, left=4
|
|
).coords_almost_equals(
|
|
[(0-2+4, 0+1-3), (1-2+4, 0+1-3), (2-2+4, 1+1-3)])
|
|
|
|
def test_shift_of_empty_line_string(self):
|
|
ls = LineString([])
|
|
assert self._func(
|
|
ls.deepcopy(), top=1, right=2, bottom=3, left=4
|
|
).coords_almost_equals([])
|
|
|
|
|
|
class TestLineString(unittest.TestCase):
|
|
def setUp(self):
|
|
reseed()
|
|
|
|
def test___init___float32_array_as_coords(self):
|
|
ls = LineString(np.float32([[0, 0], [1, 2]]))
|
|
assert np.allclose(ls.coords, np.float32([[0, 0], [1, 2]]))
|
|
assert ls.label is None
|
|
|
|
def test___init___list_of_tuples_as_coords(self):
|
|
ls = LineString([(0, 0), (1, 2)])
|
|
assert np.allclose(ls.coords, np.float32([[0, 0], [1, 2]]))
|
|
assert ls.label is None
|
|
|
|
def test___init___empty_list_as_coords(self):
|
|
ls = LineString([])
|
|
assert ls.coords.shape == (0, 2)
|
|
assert ls.label is None
|
|
|
|
def test___init___label_set(self):
|
|
ls = LineString([], label="test")
|
|
assert ls.coords.shape == (0, 2)
|
|
assert ls.label == "test"
|
|
|
|
def test_length_with_triangle(self):
|
|
ls = LineString(np.float32([[0, 0], [1, 0], [1, 1]]))
|
|
assert np.isclose(ls.length, 2.0)
|
|
|
|
def test_length_with_realworld_line_string(self):
|
|
ls = LineString(np.float32([[0, 0], [1, 2], [4, 5]]))
|
|
assert np.isclose(ls.length,
|
|
np.sqrt(1**2 + 2**2) + np.sqrt(3**2 + 3**2))
|
|
|
|
def test_length_with_single_point(self):
|
|
ls = LineString([(0, 0)])
|
|
assert np.isclose(ls.length, 0.0)
|
|
|
|
def test_length_with_zero_points(self):
|
|
ls = LineString([])
|
|
assert np.isclose(ls.length, 0.0)
|
|
|
|
def test_xx_three_points(self):
|
|
ls = LineString(np.float32([[0, 0], [1, 0], [2, 1]]))
|
|
assert np.allclose(ls.xx, np.float32([0, 1, 2]))
|
|
|
|
def test_xx_no_points(self):
|
|
ls = LineString([])
|
|
assert np.allclose(ls.xx, np.zeros((0,), dtype=np.float32))
|
|
|
|
def test_yy_three_points(self):
|
|
ls = LineString(np.float32([[0, 0], [0, 1], [0, 2]]))
|
|
assert np.allclose(ls.yy, np.float32([0, 1, 2]))
|
|
|
|
def test_yy_no_points(self):
|
|
ls = LineString([])
|
|
assert np.allclose(ls.yy, np.zeros((0,), dtype=np.float32))
|
|
|
|
def test_xx_int_three_points(self):
|
|
ls = LineString(np.float32([[0, 0], [1.4, 0], [2.6, 1]]))
|
|
assert ls.xx_int.dtype.name == "int32"
|
|
assert np.array_equal(ls.xx_int, np.int32([0, 1, 3]))
|
|
|
|
def test_xx_int_no_points(self):
|
|
ls = LineString([])
|
|
assert ls.xx_int.dtype.name == "int32"
|
|
assert np.array_equal(ls.xx_int, np.zeros((0,), dtype=np.int32))
|
|
|
|
def test_yy_int_three_points(self):
|
|
ls = LineString(np.float32([[0, 0], [0, 1.4], [1, 2.6]]))
|
|
assert ls.yy_int.dtype.name == "int32"
|
|
assert np.array_equal(ls.yy_int, np.int32([0, 1, 3]))
|
|
|
|
def test_yy_int_no_points(self):
|
|
ls = LineString([])
|
|
assert ls.yy_int.dtype.name == "int32"
|
|
assert np.array_equal(ls.yy_int, np.zeros((0,), dtype=np.int32))
|
|
|
|
def test_height_three_points(self):
|
|
ls = LineString(np.float32([[0, 0], [0, 1.4], [1, 2.6]]))
|
|
assert np.isclose(ls.height, 2.6)
|
|
|
|
def test_height_no_points(self):
|
|
ls = LineString([])
|
|
assert np.isclose(ls.height, 0.0)
|
|
|
|
def test_width_three_points(self):
|
|
ls = LineString(np.float32([[0, 0], [1.4, 0], [2.6, 1]]))
|
|
assert np.isclose(ls.width, 2.6)
|
|
|
|
def test_width_no_points(self):
|
|
ls = LineString([])
|
|
assert np.isclose(ls.width, 0.0)
|
|
|
|
def test_get_pointwise_inside_image_mask_with_single_point_tuple(self):
|
|
ls = LineString([(0, 0), (1.4, 0), (2.6, 1)])
|
|
mask = ls.get_pointwise_inside_image_mask((2, 2))
|
|
assert np.array_equal(mask, [True, True, False])
|
|
|
|
def test_get_pointwise_inside_image_mask_with_array(self):
|
|
ls = LineString([(0, 0), (1.4, 0), (2.6, 1)])
|
|
mask = ls.get_pointwise_inside_image_mask(
|
|
np.zeros((2, 2), dtype=np.uint8))
|
|
assert np.array_equal(mask, [True, True, False])
|
|
|
|
def test_get_pointwise_inside_image_mask_with_single_point_ls(self):
|
|
ls = LineString([(0, 0)])
|
|
mask = ls.get_pointwise_inside_image_mask((2, 2))
|
|
assert np.array_equal(mask, [True])
|
|
|
|
def test_get_pointwise_inside_image_mask_with_zero_points_ls(self):
|
|
ls = LineString([])
|
|
mask = ls.get_pointwise_inside_image_mask((2, 2))
|
|
assert mask.shape == (0,)
|
|
|
|
def test_compute_neighbour_distances_three_points(self):
|
|
ls = LineString([(0, 0), (1.4, 0), (2.6, 1)])
|
|
dists = ls.compute_neighbour_distances()
|
|
assert np.allclose(dists, [np.sqrt(1.4**2), np.sqrt(1.2**2+1**2)])
|
|
|
|
def test_compute_neighbour_distances_two_points(self):
|
|
ls = LineString([(0, 0), (1.4, 0)])
|
|
dists = ls.compute_neighbour_distances()
|
|
assert np.allclose(dists, [np.sqrt(1.4**2)])
|
|
|
|
def test_compute_neighbour_distances_single_point(self):
|
|
ls = LineString([(0, 0)])
|
|
dists = ls.compute_neighbour_distances()
|
|
assert dists.shape == (0,)
|
|
|
|
def test_compute_neighbour_distances_zero_points(self):
|
|
ls = LineString([])
|
|
dists = ls.compute_neighbour_distances()
|
|
assert dists.shape == (0,)
|
|
|
|
def test_compute_pointwise_distances_to_point_at_origin(self):
|
|
ls = LineString([(0, 0), (5, 0), (5, 5)])
|
|
dists = ls.compute_pointwise_distances((0, 0))
|
|
assert np.allclose(dists, [0,
|
|
5,
|
|
np.sqrt(5**2 + 5**2)])
|
|
|
|
def test_compute_pointwise_distances_to_point_at_x1_y1(self):
|
|
ls = LineString([(0, 0), (5, 0), (5, 5)])
|
|
dists = ls.compute_pointwise_distances((1, 1))
|
|
assert np.allclose(dists, [np.sqrt(1**2 + 1**2),
|
|
np.sqrt(4**2 + 1**2),
|
|
np.sqrt(4**2 + 4**2)])
|
|
|
|
def test_compute_pointwise_distances_from_empty_line_string(self):
|
|
ls = LineString([])
|
|
dists = ls.compute_pointwise_distances((1, 1))
|
|
assert dists == []
|
|
|
|
def test_compute_pointwise_distances_to_keypoint_at_origin(self):
|
|
ls = LineString([(0, 0), (5, 0), (5, 5)])
|
|
dists = ls.compute_pointwise_distances(Keypoint(x=0, y=0))
|
|
assert np.allclose(dists, [0, 5, np.sqrt(5**2 + 5**2)])
|
|
|
|
def test_compute_pointwise_distances_to_keypoint_at_x1_y1(self):
|
|
ls = LineString([(0, 0), (5, 0), (5, 5)])
|
|
dists = ls.compute_pointwise_distances(Keypoint(x=1, y=1))
|
|
assert np.allclose(dists, [np.sqrt(1**2 + 1**2),
|
|
np.sqrt(4**2 + 1**2),
|
|
np.sqrt(4**2 + 4**2)])
|
|
|
|
def test_compute_pointwise_distances_to_other_line_string_at_origin(self):
|
|
# line string
|
|
ls = LineString([(0, 0), (5, 0), (5, 5)])
|
|
other = LineString([(0, 0)])
|
|
dists = ls.compute_pointwise_distances(other)
|
|
assert np.allclose(dists, [0,
|
|
5,
|
|
np.sqrt(5**2 + 5**2)])
|
|
|
|
def test_compute_pointwise_distances_to_other_line_string_at_x1_y1(self):
|
|
ls = LineString([(0, 0), (5, 0), (5, 5)])
|
|
other = LineString([(1, 1)])
|
|
dists = ls.compute_pointwise_distances(other)
|
|
assert np.allclose(dists, [np.sqrt(1**2 + 1**2),
|
|
np.sqrt(4**2 + 1**2),
|
|
np.sqrt(4**2 + 4**2)])
|
|
|
|
def test_compute_pointwise_distances_to_other_line_string_two_points(self):
|
|
ls = LineString([(0, 0), (5, 0), (5, 5)])
|
|
other = LineString([(0, -1), (5, -1)])
|
|
dists = ls.compute_pointwise_distances(other)
|
|
assert np.allclose(dists, [np.sqrt(0**2 + 1**2),
|
|
np.sqrt(0**2 + 1**2),
|
|
np.sqrt(0**2 + 6**2)])
|
|
|
|
def test_compute_pointwise_distances_to_other_empty_line_string(self):
|
|
ls = LineString([(0, 0), (5, 0), (5, 5)])
|
|
other = LineString([])
|
|
dists = ls.compute_pointwise_distances(other, default=False)
|
|
assert dists is False
|
|
|
|
def test_compute_distance_from_three_point_line_string(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
points = [(0, 0), (1, 0), (0, 1), (-0.5, -0.6)]
|
|
expecteds = [0, 0, 1, np.sqrt(0.5**2 + 0.6**2)]
|
|
|
|
for point, expected in zip(points, expecteds):
|
|
with self.subTest(point=point):
|
|
assert np.isclose(ls.compute_distance(point), expected)
|
|
|
|
def test_compute_distance_from_single_point_line_string(self):
|
|
ls = LineString([(0, 0)])
|
|
points = [(0, 0), (-0.5, -0.6)]
|
|
expecteds = [0, np.sqrt(0.5**2 + 0.6**2)]
|
|
|
|
for point, expected in zip(points, expecteds):
|
|
with self.subTest(point=point):
|
|
assert np.isclose(ls.compute_distance(point), expected)
|
|
|
|
def test_compute_distance_from_empty_line_string_no_default(self):
|
|
ls = LineString([])
|
|
assert ls.compute_distance((0, 0)) is None
|
|
|
|
def test_compute_distance_from_empty_line_string_with_default(self):
|
|
ls = LineString([])
|
|
assert ls.compute_distance((0, 0), default=-1) == -1
|
|
|
|
def test_compute_distance_to_keypoint(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
assert np.isclose(ls.compute_distance(ia.Keypoint(x=0, y=1)), 1)
|
|
|
|
def test_compute_distance_to_line_string(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
points = [
|
|
[(0, 0)],
|
|
[(0, 1)],
|
|
[(0, 0), (0, 1)],
|
|
[(-1, -1), (-1, 1)]
|
|
]
|
|
expecteds = [0, 1, 0, 1]
|
|
|
|
for point, expected in zip(points, expecteds):
|
|
with self.subTest(point=point):
|
|
assert np.isclose(ls.compute_distance(LineString(point)),
|
|
expected)
|
|
|
|
def test_compute_distance_to_invalid_datatype(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
with self.assertRaises(ValueError):
|
|
assert ls.compute_distance("foo")
|
|
|
|
def test_contains_tuple(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
points = [(100, 0), (0, 0), (1, 0), (2, 1), (0+1e-8, 0), (0-1, 0)]
|
|
expecteds = [False, True, True, True, True, False]
|
|
|
|
for point, expected in zip(points, expecteds):
|
|
with self.subTest(point=point):
|
|
assert ls.contains(point) is expected
|
|
|
|
def test_contains_tuple_max_distance(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
points = [(0+1e-8, 0), (0-1, 0)]
|
|
max_distances = [0, 2]
|
|
expecteds = [False, True]
|
|
|
|
for point, max_distance, expected in zip(points, max_distances,
|
|
expecteds):
|
|
with self.subTest(point=point, max_distance=max_distance):
|
|
assert (
|
|
ls.contains(point, max_distance=max_distance)
|
|
is expected
|
|
)
|
|
|
|
def test_contains_keypoint(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
points = [(100, 0), (0, 0), (1, 0), (2, 1), (0+1e-8, 0), (0-1, 0)]
|
|
expecteds = [False, True, True, True, True, False]
|
|
|
|
for point, expected in zip(points, expecteds):
|
|
with self.subTest(point=point):
|
|
assert (
|
|
ls.contains(Keypoint(x=point[0], y=point[1]))
|
|
is expected
|
|
)
|
|
|
|
def test_contains_with_single_point_line_string(self):
|
|
ls = LineString([(0, 0)])
|
|
assert ls.contains((0, 0))
|
|
assert not ls.contains((1, 0))
|
|
|
|
def test_contains_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
assert not ls.contains((0, 0))
|
|
assert not ls.contains((1, 0))
|
|
|
|
def test_project_empty_line_string_to_2x_image_size(self):
|
|
ls = LineString([])
|
|
ls_proj = ls.project((10, 10), (20, 20))
|
|
assert ls_proj.coords.shape == (0, 2)
|
|
|
|
def test_compute_out_of_image_fraction__no_points(self):
|
|
ls = LineString([])
|
|
image_shape = (100, 200, 3)
|
|
factor = ls.compute_out_of_image_fraction(image_shape)
|
|
assert np.isclose(factor, 0.0)
|
|
|
|
def test_compute_out_of_image_fraction__one_point(self):
|
|
ls = LineString([(1.0, 2.0)])
|
|
image_shape = (100, 200, 3)
|
|
factor = ls.compute_out_of_image_fraction(image_shape)
|
|
assert np.isclose(factor, 0.0)
|
|
|
|
def test_compute_out_of_image_fraction__one_point__ooi(self):
|
|
ls = LineString([(-10.0, -20.0)])
|
|
image_shape = (100, 200, 3)
|
|
factor = ls.compute_out_of_image_fraction(image_shape)
|
|
assert np.isclose(factor, 1.0)
|
|
|
|
def test_compute_out_of_image_fraction__two_points(self):
|
|
ls = LineString([(1.0, 2.0), (10.0, 20.0)])
|
|
image_shape = (100, 200, 3)
|
|
factor = ls.compute_out_of_image_fraction(image_shape)
|
|
assert np.isclose(factor, 0.0)
|
|
|
|
def test_compute_out_of_image_fraction__three_points_at_same_pos(self):
|
|
ls = LineString([(10.0, 20.0), (10.0, 20.0), (10.0, 20.0)])
|
|
image_shape = (100, 200, 3)
|
|
factor = ls.compute_out_of_image_fraction(image_shape)
|
|
assert len(ls.coords) == 3
|
|
assert np.isclose(factor, 0.0)
|
|
|
|
def test_compute_out_of_image_fraction__partially_ooi(self):
|
|
ls = LineString([(9.0, 1.0), (11.0, 1.0)])
|
|
image_shape = (10, 10, 3)
|
|
factor = ls.compute_out_of_image_fraction(image_shape)
|
|
assert np.isclose(factor, 0.5, atol=1e-3)
|
|
|
|
def test_compute_out_of_image_fraction__leaves_image_multiple_times(self):
|
|
ls = LineString([(9.0, 1.0), (11.0, 1.0), (11.0, 3.0),
|
|
(9.0, 3.0), (9.0, 5.0), (11.0, 5.0)])
|
|
image_shape = (10, 10, 3)
|
|
factor = ls.compute_out_of_image_fraction(image_shape)
|
|
assert np.isclose(factor, 0.5, atol=1e-3)
|
|
|
|
def test_compute_out_of_image_fraction__fully_ooi(self):
|
|
ls = LineString([(15.0, 15.0), (20.0, 15.0)])
|
|
image_shape = (10, 10, 3)
|
|
factor = ls.compute_out_of_image_fraction(image_shape)
|
|
assert np.isclose(factor, 1.0)
|
|
|
|
def test_is_fully_within_image_with_simple_line_string(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
assert ls.is_fully_within_image((10, 10))
|
|
assert ls.is_fully_within_image((2, 3))
|
|
assert not ls.is_fully_within_image((2, 2))
|
|
assert not ls.is_fully_within_image((1, 1))
|
|
|
|
def test_is_fully_within_image_with_negative_coords_line_string(self):
|
|
ls = LineString([(-1, 0), (1, 0), (2, 1)])
|
|
assert not ls.is_fully_within_image((10, 10))
|
|
assert not ls.is_fully_within_image((2, 3))
|
|
assert not ls.is_fully_within_image((2, 2))
|
|
assert not ls.is_fully_within_image((1, 1))
|
|
|
|
def test_is_fully_within_image_with_single_point_line_string(self):
|
|
ls = LineString([(0, 0)])
|
|
assert ls.is_fully_within_image((10, 10))
|
|
assert ls.is_fully_within_image((2, 3))
|
|
assert ls.is_fully_within_image((2, 2))
|
|
assert ls.is_fully_within_image((1, 1))
|
|
|
|
def test_is_fully_within_image_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
assert not ls.is_fully_within_image((10, 10))
|
|
assert not ls.is_fully_within_image((2, 3))
|
|
assert not ls.is_fully_within_image((2, 2))
|
|
assert not ls.is_fully_within_image((1, 1))
|
|
|
|
def test_is_fully_within_image_with_empty_line_string_default_set(self):
|
|
ls = LineString([])
|
|
assert ls.is_fully_within_image((10, 10), default=True)
|
|
assert ls.is_fully_within_image((2, 3), default=True)
|
|
assert ls.is_fully_within_image((2, 2), default=True)
|
|
assert ls.is_fully_within_image((1, 1), default=True)
|
|
assert ls.is_fully_within_image((10, 10), default=None) is None
|
|
|
|
def test_is_partly_within_image_with_simple_line_string(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
assert ls.is_partly_within_image((10, 10))
|
|
assert ls.is_partly_within_image((2, 3))
|
|
assert ls.is_partly_within_image((2, 2))
|
|
assert ls.is_partly_within_image((1, 1))
|
|
|
|
def test_is_partly_within_image_with_simple_line_string2(self):
|
|
ls = LineString([(1, 0), (2, 0), (3, 1)])
|
|
assert ls.is_partly_within_image((10, 10))
|
|
assert ls.is_partly_within_image((2, 3))
|
|
assert ls.is_partly_within_image((2, 2))
|
|
assert not ls.is_partly_within_image((1, 1))
|
|
|
|
def test_is_partly_within_image_with_ls_cutting_through_image(self):
|
|
# line string that cuts through the middle of the image,
|
|
# with both points outside of a BB (0, 0), (10, 10)
|
|
ls = LineString([(-1, 5), (11, 5)])
|
|
assert ls.is_partly_within_image((100, 100))
|
|
assert ls.is_partly_within_image((10, 12))
|
|
assert ls.is_partly_within_image((10, 10))
|
|
assert ls.is_partly_within_image((10, 1))
|
|
assert not ls.is_partly_within_image((1, 1))
|
|
|
|
def test_is_partly_within_image_with_line_string_around_rectangle(self):
|
|
# line string around inner rectangle of (-1, -1), (11, 11)
|
|
ls = LineString([(-1, -1), (11, -1), (11, 11), (-1, 11)])
|
|
assert ls.is_partly_within_image((100, 100))
|
|
assert ls.is_partly_within_image((12, 12))
|
|
assert not ls.is_partly_within_image((10, 10))
|
|
|
|
def test_is_partly_within_image_with_single_point_line_string(self):
|
|
ls = LineString([(11, 11)])
|
|
assert ls.is_partly_within_image((100, 100))
|
|
assert ls.is_partly_within_image((12, 12))
|
|
assert not ls.is_partly_within_image((10, 10))
|
|
|
|
def test_is_partly_within_image_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
assert not ls.is_partly_within_image((100, 100))
|
|
assert not ls.is_partly_within_image((10, 10))
|
|
assert ls.is_partly_within_image((100, 100), default=True)
|
|
assert ls.is_partly_within_image((10, 10), default=True)
|
|
assert ls.is_partly_within_image((100, 100), default=None) is None
|
|
assert ls.is_partly_within_image((10, 10), default=None) is None
|
|
|
|
def test_is_out_of_image_with_simple_line_string(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
assert not ls.is_out_of_image((10, 10))
|
|
assert ls.is_out_of_image((1, 1), fully=False, partly=True)
|
|
assert not ls.is_out_of_image((1, 1), fully=True, partly=False)
|
|
assert ls.is_out_of_image((1, 1), fully=True, partly=True)
|
|
assert not ls.is_out_of_image((1, 1), fully=False, partly=False)
|
|
|
|
def test_is_out_of_image_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
assert ls.is_out_of_image((10, 10))
|
|
assert not ls.is_out_of_image((10, 10), default=False)
|
|
assert ls.is_out_of_image((10, 10), default=None) is None
|
|
|
|
def test_clip_out_of_image_with_simple_line_string(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], ls)
|
|
|
|
lss_clipped = ls.clip_out_of_image((2, 2))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], ls)
|
|
|
|
lss_clipped = ls.clip_out_of_image((2, 1))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, 0), (1, 0)])
|
|
|
|
def test_clip_out_of_image_with_shifted_simple_line_string(self):
|
|
# same as above, all coords at x+5, y+5
|
|
ls = LineString([(5, 5), (6, 5), (7, 6)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], ls)
|
|
|
|
lss_clipped = ls.clip_out_of_image((4, 4))
|
|
assert len(lss_clipped) == 0
|
|
|
|
def test_clip_out_of_image_with_ls_partially_outside_image(self):
|
|
# line that leaves image plane and comes back
|
|
ls = LineString([(0, 0), (1, 0), (3, 0),
|
|
(3, 2), (1, 2), (0, 2)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], ls)
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 2))
|
|
assert len(lss_clipped) == 2
|
|
assert _coords_eq(lss_clipped[0], [(0, 0), (1, 0), (2, 0)])
|
|
assert _coords_eq(lss_clipped[1], [(2, 2), (1, 2), (0, 2)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 1))
|
|
assert len(lss_clipped) == 2
|
|
assert _coords_eq(lss_clipped[0], [(0, 0), (1, 0)])
|
|
assert _coords_eq(lss_clipped[1], [(1, 2), (0, 2)])
|
|
|
|
def test_clip_out_of_image_with_ls_partially_ooi_less_points(self):
|
|
# same as above, but removing first and last point
|
|
# so that only one point before and after out of image part remain
|
|
ls = LineString([(1, 0), (3, 0),
|
|
(3, 2), (1, 2)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], ls)
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 2))
|
|
assert len(lss_clipped) == 2
|
|
assert _coords_eq(lss_clipped[0], [(1, 0), (2, 0)])
|
|
assert _coords_eq(lss_clipped[1], [(2, 2), (1, 2)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 1))
|
|
assert len(lss_clipped) == 0
|
|
|
|
def test_clip_out_of_image_when_only_one_point_remains(self):
|
|
# same as above, but only one point out of image remains
|
|
ls = LineString([(1, 0), (3, 0),
|
|
(1, 2)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], ls)
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 2))
|
|
assert len(lss_clipped) == 2
|
|
assert _coords_eq(lss_clipped[0], [(1, 0), (2, 0)])
|
|
assert _coords_eq(lss_clipped[1], [(2, 1), (1, 2)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 1))
|
|
assert len(lss_clipped) == 0
|
|
|
|
def test_clip_out_of_image_with_ls_leaving_image_multiple_times(self):
|
|
# line string that leaves image, comes back, then leaves again, then
|
|
# comes back again
|
|
ls = LineString([(1, 0), (3, 0), # leaves
|
|
(3, 1), (1, 1), # comes back
|
|
(1, 2), (3, 2), # leaves
|
|
(3, 3), (1, 3)]) # comes back
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], ls)
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 2))
|
|
assert len(lss_clipped) == 3 # from above: 1s line, 2nd+3rd, 4th
|
|
assert _coords_eq(lss_clipped[0], [(1, 0), (2, 0)])
|
|
assert _coords_eq(lss_clipped[1], [(2, 1), (1, 1), (1, 2), (2, 2)])
|
|
assert _coords_eq(lss_clipped[2], [(2, 3), (1, 3)])
|
|
|
|
def test_clip_out_of_image_with_ls_that_enters_image_from_outside(self):
|
|
# line string that starts out of image and ends within the image plane
|
|
for y in [1, 0]:
|
|
with self.subTest(y=y):
|
|
# one point inside image
|
|
ls = LineString([(-10, y), (3, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, y), (3, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((2, 1))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, y), (1, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((1, 1))
|
|
if y == 1:
|
|
assert len(lss_clipped) == 0
|
|
else:
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, y), (1, y)])
|
|
|
|
# two points inside image
|
|
ls = LineString([(-10, y), (3, y), (5, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, y), (3, y), (5, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 4))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, y), (3, y), (4, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((2, 1))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, y), (1, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((1, 1))
|
|
if y == 1:
|
|
assert len(lss_clipped) == 0
|
|
else:
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, y), (1, y)])
|
|
|
|
def test_clip_out_of_image_with_ls_that_leaves_image_from_inside(self):
|
|
# line string that starts within the image plane and ends outside
|
|
for y in [1, 0]:
|
|
with self.subTest(y=y):
|
|
# one point inside image
|
|
ls = LineString([(2, y), (5, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(2, y), (5, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 4))
|
|
assert _coords_eq(lss_clipped[0], [(2, y), (4, y)])
|
|
|
|
# two points inside image
|
|
ls = LineString([(1, y), (2, y), (5, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(1, y), (2, y), (5, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 4))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(1, y), (2, y), (4, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((2, 1))
|
|
assert len(lss_clipped) == 0
|
|
|
|
# two points outside image
|
|
ls = LineString([(2, y), (5, y), (6, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(2, y), (5, y), (6, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 4))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(2, y), (4, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((2, 1))
|
|
assert len(lss_clipped) == 0
|
|
|
|
def test_clip_out_of_image_with_ls_that_cuts_through_image(self):
|
|
# line string that cuts through the image plane in the center
|
|
for y in [1, 0]:
|
|
ls = LineString([(-5, y), (5, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, y), (5, y)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((4, 4))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, y), (4, y)])
|
|
|
|
def test_clip_out_of_image_with_ls_that_runs_through_diagonal_corners(self):
|
|
# line string that cuts through the image plane from the bottom left
|
|
# corner to the top right corner
|
|
ls = LineString([(-5, -5), (5, 5)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, 0), (5, 5)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((4, 4))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, 0), (4, 4)])
|
|
|
|
def test_clip_out_of_image_with_ls_that_overlaps_with_image_edge(self):
|
|
# line string that overlaps with the bottom edge
|
|
ls = LineString([(1, 0), (4, 0)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], ls)
|
|
|
|
lss_clipped = ls.clip_out_of_image((3, 3))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(1, 0), (3, 0)])
|
|
|
|
def test_clip_out_of_image_with_ls_that_overlaps_with_image_edge2(self):
|
|
# same as above, multiple points on line
|
|
ls = LineString([(1, 0), (4, 0), (5, 0), (6, 0), (7, 0)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], ls)
|
|
|
|
lss_clipped = ls.clip_out_of_image((5, 5))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(1, 0), (4, 0), (5, 0)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((5, 4))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(1, 0), (4, 0)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((5, 2))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(1, 0), (2, 0)])
|
|
|
|
def test_clip_out_of_image_with_ls_that_overlaps_with_image_edge3(self):
|
|
# line string that starts outside the image, intersects with the
|
|
# bottom left corner and overlaps with the bottom border
|
|
ls = LineString([(-5, 0), (5, 0)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, 0), (5, 0)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 5))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, 0), (5, 0)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 4))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], [(0, 0), (4, 0)])
|
|
|
|
def test_clip_out_of_image_with_ls_that_contains_a_single_point(self):
|
|
# line string that contains a single point
|
|
ls = LineString([(2, 2)])
|
|
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 1
|
|
assert _coords_eq(lss_clipped[0], ls)
|
|
|
|
lss_clipped = ls.clip_out_of_image((1, 1))
|
|
assert len(lss_clipped) == 0
|
|
|
|
def test_clip_out_of_image_with_ls_that_is_empty(self):
|
|
# line string that is empty
|
|
ls = LineString([])
|
|
lss_clipped = ls.clip_out_of_image((10, 10))
|
|
assert len(lss_clipped) == 0
|
|
|
|
def test_clip_out_of_image_and_is_fully_within_image(self):
|
|
# combine clip + is_fully_within_image
|
|
sizes = [(200, 400), (400, 800), (800, 1600), (1600, 3200),
|
|
(3200, 6400)]
|
|
sizes = sizes + [(w, h) for h, w in sizes]
|
|
for h, w in sizes:
|
|
ls = LineString([(0, 10), (w, 10), (w, h), (w-10, h-10)])
|
|
lss_clipped = ls.clip_out_of_image((h, w))
|
|
assert len(lss_clipped) == 2
|
|
assert lss_clipped[0].is_fully_within_image((h, w))
|
|
assert lss_clipped[1].is_fully_within_image((h, w))
|
|
|
|
ls = LineString([(0, 10), (w+10, 10), (w+10, h-10), (w-10, h-10)])
|
|
lss_clipped = ls.clip_out_of_image((h, w))
|
|
assert len(lss_clipped) == 2
|
|
assert lss_clipped[0].is_fully_within_image((h, w))
|
|
assert lss_clipped[1].is_fully_within_image((h, w))
|
|
|
|
ls = LineString([(-10, 10), (w+10, 10), (w-10, h-10)])
|
|
lss_clipped = ls.clip_out_of_image((h, w))
|
|
assert len(lss_clipped) == 2
|
|
assert lss_clipped[0].is_fully_within_image((h, w))
|
|
assert lss_clipped[1].is_fully_within_image((h, w))
|
|
|
|
def test_draw_mask(self):
|
|
ls = LineString([(0, 1), (5, 1), (5, 5)])
|
|
|
|
arr = ls.draw_mask(
|
|
(10, 10), size_lines=1, size_points=0, raise_if_out_of_image=False)
|
|
|
|
assert np.all(arr[1, 0:5])
|
|
assert np.all(arr[1:5, 5])
|
|
assert not np.any(arr[0, :])
|
|
assert not np.any(arr[2:, 0:5])
|
|
|
|
def test_draw_mask_of_empty_line_string(self):
|
|
ls = LineString([])
|
|
|
|
arr = ls.draw_mask(
|
|
(10, 10), size_lines=1, raise_if_out_of_image=False)
|
|
|
|
assert not np.any(arr)
|
|
|
|
def test_draw_line_heatmap_array(self):
|
|
ls = LineString([(0, 1), (5, 1), (5, 5)])
|
|
|
|
arr = ls.draw_lines_heatmap_array(
|
|
(10, 10), alpha=0.5, size=1, raise_if_out_of_image=False)
|
|
|
|
assert _drawing_allclose(arr[1, 0:5], 0.5)
|
|
assert _drawing_allclose(arr[1:5, 5], 0.5)
|
|
assert _drawing_allclose(arr[0, :], 0.0)
|
|
assert _drawing_allclose(arr[2:, 0:5], 0.0)
|
|
|
|
def test_draw_line_heatmap_array_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
|
|
arr = ls.draw_lines_heatmap_array(
|
|
(10, 10), alpha=0.5, size=1, raise_if_out_of_image=False)
|
|
|
|
assert _drawing_allclose(arr, 0.0)
|
|
|
|
def test_draw_points_heatmap_array(self):
|
|
ls = LineString([(0, 1), (5, 1), (5, 5)])
|
|
|
|
arr = ls.draw_points_heatmap_array(
|
|
(10, 10), alpha=0.5, size=1, raise_if_out_of_image=False)
|
|
|
|
assert _drawing_allclose(arr[1, 0], 0.5)
|
|
assert _drawing_allclose(arr[1, 5], 0.5)
|
|
assert _drawing_allclose(arr[5, 5], 0.5)
|
|
assert _drawing_allclose(arr[0, :], 0.0)
|
|
assert _drawing_allclose(arr[2:, 0:5], 0.0)
|
|
|
|
def test_draw_points_heatmap_array_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
|
|
arr = ls.draw_points_heatmap_array(
|
|
(10, 10), alpha=0.5, size=1, raise_if_out_of_image=False)
|
|
|
|
assert _drawing_allclose(arr, 0.0)
|
|
|
|
def test_draw_heatmap_array_calls_other_drawing_functions(self):
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
module_name = "imgaug.augmentables.lines."
|
|
line_fname = "%sLineString.draw_lines_heatmap_array" % (module_name,)
|
|
points_fname = "%sLineString.draw_points_heatmap_array" % (module_name,)
|
|
with mock.patch(line_fname, return_value=1) as mock_line, \
|
|
mock.patch(points_fname, return_value=2) as mock_points:
|
|
_arr = ls.draw_heatmap_array(
|
|
(10, 10),
|
|
alpha_lines=0.9, alpha_points=0.8,
|
|
size_lines=3, size_points=5,
|
|
antialiased=True,
|
|
raise_if_out_of_image=True)
|
|
|
|
assert mock_line.call_count == 1
|
|
assert mock_points.call_count == 1
|
|
|
|
assert mock_line.call_args_list[0][0][0] == (10, 10)
|
|
assert np.isclose(mock_line.call_args_list[0][1]["alpha"], 0.9)
|
|
assert mock_line.call_args_list[0][1]["size"] == 3
|
|
assert mock_line.call_args_list[0][1]["antialiased"] is True
|
|
assert mock_line.call_args_list[0][1]["raise_if_out_of_image"] \
|
|
is True
|
|
|
|
assert mock_points.call_args_list[0][0][0] == (10, 10)
|
|
assert np.isclose(mock_points.call_args_list[0][1]["alpha"], 0.8)
|
|
assert mock_points.call_args_list[0][1]["size"] == 5
|
|
assert mock_points.call_args_list[0][1]["raise_if_out_of_image"] \
|
|
is True
|
|
|
|
def test_draw_heatmap_array_without_mocking(self):
|
|
ls = LineString([(0, 1), (5, 1), (5, 5)])
|
|
|
|
arr = ls.draw_heatmap_array((10, 10),
|
|
alpha_lines=0.9, alpha_points=0.5,
|
|
size_lines=1, size_points=3,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False)
|
|
|
|
assert _drawing_allclose(arr[1, 0:5], 0.9)
|
|
assert _drawing_allclose(arr[1, 0:5], 0.9)
|
|
assert _drawing_allclose(arr[1, 0:5], 0.9)
|
|
assert _drawing_allclose(arr[2:5, 5], 0.9)
|
|
assert _drawing_allclose(arr[2:5, 5], 0.9)
|
|
assert _drawing_allclose(arr[2:5, 5], 0.9)
|
|
|
|
assert _drawing_allclose(arr[0, 0:2], 0.5)
|
|
assert _drawing_allclose(arr[2, 0:2], 0.5)
|
|
|
|
assert _drawing_allclose(arr[0, 4:6 + 1], 0.5)
|
|
assert _drawing_allclose(arr[2, 4], 0.5)
|
|
assert _drawing_allclose(arr[2, 6], 0.5)
|
|
|
|
assert _drawing_allclose(arr[4, 4], 0.5)
|
|
assert _drawing_allclose(arr[4, 6], 0.5)
|
|
assert _drawing_allclose(arr[6, 4:6 + 1], 0.5)
|
|
|
|
assert _drawing_allclose(arr[0, 3], 0.0)
|
|
assert _drawing_allclose(arr[7:, :], 0.0)
|
|
|
|
def test_draw_heatmap_array_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
|
|
arr = ls.draw_heatmap_array((10, 10))
|
|
|
|
assert arr.shape == (10, 10)
|
|
assert np.sum(arr) == 0
|
|
|
|
def test_draw_line_on_image_with_image_of_zeros(self):
|
|
# image of 0s
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
img = ls.draw_lines_on_image(
|
|
np.zeros((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=1.0, size=1,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img[0, :, :] == 0)
|
|
assert np.all(img[1, :, 0] == 10)
|
|
assert np.all(img[1, :, 1] == 200)
|
|
assert np.all(img[1, :, 2] == 20)
|
|
assert np.all(img[2, :, :] == 0)
|
|
|
|
def test_draw_line_on_image_with_2d_image_of_zeros(self):
|
|
# image of 0s, 2D input image
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
img = ls.draw_lines_on_image(
|
|
np.zeros((3, 10), dtype=np.uint8),
|
|
color=200,
|
|
alpha=1.0, size=1,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img[0, :] == 0)
|
|
assert np.all(img[1, :] == 200)
|
|
assert np.all(img[2, :] == 0)
|
|
|
|
def test_draw_line_on_image_of_ones(self):
|
|
# image of 1s
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
img = ls.draw_lines_on_image(
|
|
np.ones((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=1.0, size=1,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img[0, :, :] == 1)
|
|
assert np.all(img[1, :, 0] == 10)
|
|
assert np.all(img[1, :, 1] == 200)
|
|
assert np.all(img[1, :, 2] == 20)
|
|
assert np.all(img[2, :, :] == 1)
|
|
|
|
def test_draw_line_on_image_alpha_at_50_percent(self):
|
|
# alpha=0.5
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
img = ls.draw_lines_on_image(
|
|
np.zeros((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=0.5, size=1,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img[0, :, :] == 0)
|
|
assert np.all(img[1, :, 0] == 5)
|
|
assert np.all(img[1, :, 1] == 100)
|
|
assert np.all(img[1, :, 2] == 10)
|
|
assert np.all(img[2, :, :] == 0)
|
|
|
|
def test_draw_line_on_image_alpha_at_50_percent_with_background(self):
|
|
# alpha=0.5 with background
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
img = ls.draw_lines_on_image(
|
|
10 + np.zeros((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=0.5, size=1,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img[0, :, :] == 10)
|
|
assert np.all(img[1, :, 0] == 5+5)
|
|
assert np.all(img[1, :, 1] == 5+100)
|
|
assert np.all(img[1, :, 2] == 5+10)
|
|
assert np.all(img[2, :, :] == 10)
|
|
|
|
def test_draw_line_on_image_with_size_3(self):
|
|
# size=3
|
|
ls = LineString([(0, 5), (9, 5)])
|
|
|
|
img = ls.draw_lines_on_image(
|
|
np.zeros((10, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=1.0, size=3,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img[5-1:5+1+1, :, 0] == 10)
|
|
assert np.all(img[5-1:5+1+1, :, 1] == 200)
|
|
assert np.all(img[5-1:5+1+1, :, 2] == 20)
|
|
assert np.all(img[:5-1, :, :] == 0)
|
|
assert np.all(img[5+1+1:, :, :] == 0)
|
|
|
|
def test_draw_line_on_image_with_2d_image_and_size_3(self):
|
|
# size=3, 2D input image
|
|
ls = LineString([(0, 5), (9, 5)])
|
|
|
|
img = ls.draw_lines_on_image(
|
|
np.zeros((10, 10), dtype=np.uint8),
|
|
color=200,
|
|
alpha=1.0, size=3,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img[5-1:5+1+1, :] == 200)
|
|
assert np.all(img[:5-1, :] == 0)
|
|
assert np.all(img[5+1+1:, :] == 0)
|
|
|
|
def test_draw_line_on_image_with_size_3_and_antialiasing(self):
|
|
# size=3, antialiasing
|
|
ls = LineString([(0, 0), (9, 9)])
|
|
|
|
img = ls.draw_lines_on_image(
|
|
np.zeros((10, 10, 3), dtype=np.uint8),
|
|
color=(100, 100, 100),
|
|
alpha=1.0, size=3,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False
|
|
)
|
|
img_aa = ls.draw_lines_on_image(
|
|
np.zeros((10, 10, 3), dtype=np.uint8),
|
|
color=(100, 100, 100),
|
|
alpha=1.0, size=3,
|
|
antialiased=True,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert img_aa.dtype.name == "uint8"
|
|
assert np.sum(img) > 5 * 3 * 100
|
|
assert np.sum(img_aa) > 5 * 3 * 100
|
|
assert not np.array_equal(img, img_aa)
|
|
assert np.all(img[:3, -3:, :] == 0)
|
|
assert np.all(img_aa[:3, -3:, :] == 0)
|
|
assert np.all(img[-3:, :3, :] == 0)
|
|
assert np.all(img_aa[-3:, :3, :] == 0)
|
|
|
|
def test_draw_line_on_image_with_line_partially_outside_image(self):
|
|
# line partially outside if image
|
|
ls = LineString([(-1, 1), (9, 1)])
|
|
|
|
img = ls.draw_lines_on_image(
|
|
np.zeros((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=1.0, size=1,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img[0, :, :] == 0)
|
|
assert np.all(img[1, :, 0] == 10)
|
|
assert np.all(img[1, :, 1] == 200)
|
|
assert np.all(img[1, :, 2] == 20)
|
|
assert np.all(img[2, :, :] == 0)
|
|
|
|
def test_draw_line_on_image_with_line_fully_outside_image(self):
|
|
# line fully outside if image
|
|
ls = LineString([(-10, 1), (-9, 1)])
|
|
|
|
img = ls.draw_lines_on_image(
|
|
np.zeros((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=1.0, size=1,
|
|
antialiased=False,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img == 0)
|
|
|
|
def test_draw_line_on_image_with_line_fully_ooi_and_raise_true(self):
|
|
# raise_if_out_of_image=True
|
|
ls = LineString([(0-5, 5), (-1, 5)])
|
|
|
|
with self.assertRaises(Exception) as context:
|
|
_img = ls.draw_lines_on_image(
|
|
np.zeros((10, 10, 3), dtype=np.uint8),
|
|
color=(100, 100, 100),
|
|
alpha=1.0, size=3,
|
|
antialiased=False,
|
|
raise_if_out_of_image=True
|
|
)
|
|
|
|
assert "Cannot draw line string " in str(context.exception)
|
|
|
|
def test_draw_line_on_image_with_line_part_inside_img_and_raise_true(self):
|
|
# raise_if_out_of_image=True BUT line is partially inside image
|
|
# (no point is inside image though)
|
|
ls = LineString([(-1, 5), (11, 5)])
|
|
|
|
_img = ls.draw_lines_on_image(
|
|
np.zeros((10, 10, 3), dtype=np.uint8),
|
|
color=(100, 100, 100),
|
|
alpha=1.0, size=3,
|
|
antialiased=False,
|
|
raise_if_out_of_image=True
|
|
)
|
|
|
|
def test_draw_points_on_image_with_image_of_zeros(self):
|
|
# iamge of 0s
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
img = ls.draw_points_on_image(
|
|
np.zeros((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 255, 20),
|
|
alpha=1.0, size=3,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img[0:2, 0:2, 0] == 10)
|
|
assert np.all(img[0:2, 0:2, 1] == 255)
|
|
assert np.all(img[0:2, 0:2, 2] == 20)
|
|
assert np.all(img[0:2, -2:, 0] == 10)
|
|
assert np.all(img[0:2, -2:, 1] == 255)
|
|
assert np.all(img[0:2, -2:, 2] == 20)
|
|
assert np.all(img[:, 2:-2, :] == 0)
|
|
|
|
def test_draw_points_on_image_with_image_of_ones(self):
|
|
# image of 1s
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
img = ls.draw_points_on_image(
|
|
np.ones((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=1.0, size=3,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert img.dtype.name == "uint8"
|
|
assert np.all(img[0:2, 0:2, 0] == 10)
|
|
assert np.all(img[0:2, 0:2, 1] == 200)
|
|
assert np.all(img[0:2, 0:2, 2] == 20)
|
|
assert np.all(img[0:2, -2:, 0] == 10)
|
|
assert np.all(img[0:2, -2:, 1] == 200)
|
|
assert np.all(img[0:2, -2:, 2] == 20)
|
|
assert np.all(img[:, 2:-2, :] == 1)
|
|
|
|
def test_draw_points_on_image_with_alpha_50_percent(self):
|
|
# alpha=0.5
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
img = ls.draw_points_on_image(
|
|
np.zeros((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=0.5, size=3,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert np.all(img[0:2, 0:2, 0] == 5)
|
|
assert np.all(img[0:2, 0:2, 1] == 100)
|
|
assert np.all(img[0:2, 0:2, 2] == 10)
|
|
assert np.all(img[0:2, -2:, 0] == 5)
|
|
assert np.all(img[0:2, -2:, 1] == 100)
|
|
assert np.all(img[0:2, -2:, 2] == 10)
|
|
assert np.all(img[:, 2:-2, :] == 0)
|
|
|
|
def test_draw_points_on_image_with_size_one(self):
|
|
# size=1
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
img = ls.draw_points_on_image(
|
|
np.zeros((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=1.0, size=1,
|
|
raise_if_out_of_image=False
|
|
)
|
|
|
|
assert np.all(img[0, :, :] == 0)
|
|
assert np.all(img[2, :, :] == 0)
|
|
|
|
assert np.all(img[1, 0, 0] == 10)
|
|
assert np.all(img[1, 0, 1] == 200)
|
|
assert np.all(img[1, 0, 2] == 20)
|
|
|
|
assert np.all(img[1, -1, 0] == 10)
|
|
assert np.all(img[1, -1, 1] == 200)
|
|
assert np.all(img[1, -1, 2] == 20)
|
|
|
|
def test_draw_points_on_image_with_ls_ooi_and_raise_true(self):
|
|
with self.assertRaises(Exception) as context:
|
|
ls = LineString([(0-5, 1), (9+5, 1)])
|
|
_img = ls.draw_points_on_image(
|
|
np.zeros((3, 10, 3), dtype=np.uint8),
|
|
color=(10, 200, 20),
|
|
alpha=0.5, size=1,
|
|
raise_if_out_of_image=True
|
|
)
|
|
|
|
assert "Cannot draw keypoint " in str(context.exception)
|
|
|
|
def test_draw_on_image_with_mocking(self):
|
|
ls = LineString([(0, 1), (9, 1)])
|
|
|
|
module_name = "imgaug.augmentables.lines."
|
|
line_fname = "%sLineString.draw_lines_on_image" % (module_name,)
|
|
points_fname = "%sLineString.draw_points_on_image" % (module_name,)
|
|
with mock.patch(line_fname, return_value=1) as mock_line, \
|
|
mock.patch(points_fname, return_value=2) as mock_points:
|
|
_image = ls.draw_on_image(
|
|
np.zeros((10, 10, 3), dtype=np.uint8),
|
|
color=(1, 2, 3), color_lines=(4, 5, 6), color_points=(7, 8, 9),
|
|
alpha=1.0, alpha_lines=0.9, alpha_points=0.8,
|
|
size=1, size_lines=3, size_points=5,
|
|
antialiased=False,
|
|
raise_if_out_of_image=True)
|
|
|
|
assert mock_line.call_count == 1
|
|
assert mock_points.call_count == 1
|
|
|
|
assert mock_line.call_args_list[0][0][0].shape == (10, 10, 3)
|
|
assert mock_line.call_args_list[0][1]["color"][0] == 4
|
|
assert mock_line.call_args_list[0][1]["color"][1] == 5
|
|
assert mock_line.call_args_list[0][1]["color"][2] == 6
|
|
assert np.isclose(mock_line.call_args_list[0][1]["alpha"], 0.9)
|
|
assert mock_line.call_args_list[0][1]["size"] == 3
|
|
assert mock_line.call_args_list[0][1]["antialiased"] is False
|
|
assert mock_line.call_args_list[0][1]["raise_if_out_of_image"] \
|
|
is True
|
|
|
|
assert mock_points.call_args_list[0][0][0] == 1 # mock_line result
|
|
assert mock_points.call_args_list[0][1]["color"][0] == 7
|
|
assert mock_points.call_args_list[0][1]["color"][1] == 8
|
|
assert mock_points.call_args_list[0][1]["color"][2] == 9
|
|
assert np.isclose(mock_points.call_args_list[0][1]["alpha"], 0.8)
|
|
assert mock_points.call_args_list[0][1]["size"] == 5
|
|
assert mock_points.call_args_list[0][1]["raise_if_out_of_image"] \
|
|
is True
|
|
|
|
def test_draw_on_image_without_mocking(self):
|
|
ls = LineString([(0, 1), (5, 1), (5, 5)])
|
|
|
|
img = ls.draw_on_image(np.zeros((10, 10, 3), dtype=np.uint8),
|
|
color=(200, 120, 40), alpha=0.5, size=1)
|
|
|
|
assert np.all(img[1, 0:5, 0] == 100)
|
|
assert np.all(img[1, 0:5, 1] == 60)
|
|
assert np.all(img[1, 0:5, 2] == 20)
|
|
assert np.all(img[1:5, 5, 0] == 100)
|
|
assert np.all(img[1:5, 5, 1] == 60)
|
|
assert np.all(img[1:5, 5, 2] == 20)
|
|
assert np.all(img[0:2+1, 0:2, 0] >= 50) # color_points is 0.5*color
|
|
assert np.all(img[0:2+1, 0:2, 1] >= 30)
|
|
assert np.all(img[0:2+1, 0:2, 2] >= 10)
|
|
assert np.all(img[0:2+1, 4:6+1, 0] >= 50)
|
|
assert np.all(img[0:2+1, 4:6+1, 1] >= 30)
|
|
assert np.all(img[0:2+1, 4:6+1, 2] >= 10)
|
|
assert np.all(img[4:6+1, 4:6+1, 0] >= 50)
|
|
assert np.all(img[4:6+1, 4:6+1, 1] >= 30)
|
|
assert np.all(img[4:6+1, 4:6+1, 2] >= 10)
|
|
assert np.all(img[0, 3, :] == 0)
|
|
assert np.all(img[7:, :, :] == 0)
|
|
|
|
def test_draw_on_image_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
|
|
img = ls.draw_on_image(np.zeros((10, 10, 3), dtype=np.uint8))
|
|
|
|
assert img.shape == (10, 10, 3)
|
|
assert np.sum(img) == 0
|
|
|
|
def test_extract_from_image_size_1_single_channel(self):
|
|
ls = LineString([(0, 5), (9, 5)])
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
|
|
extract = ls.extract_from_image(img, antialiased=False)
|
|
|
|
assert extract.shape == (1, 10, 1)
|
|
assert np.array_equal(extract, img[5:6, 0:10, :])
|
|
|
|
def test_extract_from_image_size_3_single_channel(self):
|
|
ls = LineString([(1, 5), (8, 5)])
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
|
|
extract = ls.extract_from_image(img, size=3, antialiased=False)
|
|
|
|
assert extract.shape == (3, 10, 1)
|
|
assert np.array_equal(extract, img[4:6+1, 0:10, :])
|
|
|
|
def test_extract_from_image_size_3_rgb(self):
|
|
# size=3, RGB image
|
|
ls = LineString([(1, 5), (8, 5)])
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
img_rgb = np.tile(img, (1, 1, 3))
|
|
img_rgb[..., 1] += 10
|
|
img_rgb[..., 2] += 20
|
|
|
|
extract = ls.extract_from_image(img_rgb, size=3, antialiased=False)
|
|
|
|
assert extract.shape == (3, 10, 3)
|
|
assert np.array_equal(extract, img_rgb[4:6+1, 0:10, :])
|
|
|
|
def test_extract_from_image_antialiased_true(self):
|
|
# weak antialiased=True test
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
ls = LineString([(1, 1), (9, 9)])
|
|
|
|
extract_aa = ls.extract_from_image(img, size=3, antialiased=True)
|
|
extract = ls.extract_from_image(img, size=3, antialiased=False)
|
|
|
|
assert extract_aa.shape == extract.shape
|
|
assert np.sum(extract_aa) > np.sum(extract)
|
|
|
|
def test_extract_from_image_pad_false(self):
|
|
# pad=False
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
ls = LineString([(-5, 5), (-3, 5)])
|
|
|
|
extract = ls.extract_from_image(img, size=1, antialiased=False,
|
|
pad=False, prevent_zero_size=True)
|
|
|
|
assert extract.shape == (1, 1, 1)
|
|
assert np.sum(extract) == 0
|
|
|
|
def test_extract_from_image_pad_false_and_prevent_zero_size_false(self):
|
|
# pad=False, prevent_zero_size=False
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
ls = LineString([(-5, 5), (-3, 5)])
|
|
|
|
extract = ls.extract_from_image(img, size=1, antialiased=False,
|
|
pad=False, prevent_zero_size=False)
|
|
|
|
assert extract.shape == (0, 0, 1)
|
|
|
|
def test_extract_from_image_pad_max(self):
|
|
# pad_max=1
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
ls = LineString([(-5, 5), (9, 5)])
|
|
|
|
extract = ls.extract_from_image(img, antialiased=False, pad=True,
|
|
pad_max=1)
|
|
|
|
assert extract.shape == (1, 11, 1)
|
|
assert np.array_equal(extract[:, 1:], img[5:6, 0:10, :])
|
|
assert np.all(extract[0, 0, :] == 0)
|
|
|
|
def test_extract_from_image_with_single_point_line_string(self):
|
|
# 1 coord
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
ls = LineString([(1, 1)])
|
|
|
|
extract = ls.extract_from_image(img)
|
|
|
|
assert extract.shape == (1, 1, 1)
|
|
assert np.sum(extract) == img[1:2, 1:2, :]
|
|
|
|
def test_extract_from_image_with_single_point_ls_negative_coords(self):
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
ls = LineString([(-10, -10)])
|
|
|
|
extract = ls.extract_from_image(img)
|
|
|
|
assert extract.shape == (1, 1, 1)
|
|
assert np.sum(extract) == 0
|
|
|
|
def test_extract_from_image_with_1_point_neg_coords_prevent_zero_size(self):
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
ls = LineString([(-10, -10)])
|
|
|
|
extract = ls.extract_from_image(img, prevent_zero_size=True)
|
|
|
|
assert extract.shape == (1, 1, 1)
|
|
assert np.sum(extract) == 0
|
|
|
|
def test_extract_from_image_with_empty_line_string(self):
|
|
# 0 coords
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
ls = LineString([])
|
|
|
|
extract = ls.extract_from_image(img)
|
|
|
|
assert extract.shape == (1, 1, 1)
|
|
assert np.sum(extract) == 0
|
|
|
|
def test_extract_from_image_with_empty_line_string_prevent_zero_size(self):
|
|
img = np.arange(10*10).reshape((10, 10, 1)).astype(np.uint8)
|
|
ls = LineString([])
|
|
|
|
extract = ls.extract_from_image(img, prevent_zero_size=False)
|
|
|
|
assert extract.shape == (0, 0, 1)
|
|
assert np.sum(extract) == 0
|
|
|
|
def test_concatenate_line_string_with_itself(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls_concat = ls.concatenate(ls)
|
|
assert ls_concat.coords_almost_equals([
|
|
(0, 0), (1, 0), (2, 1), (0, 0), (1, 0), (2, 1)
|
|
])
|
|
|
|
def test_concatenate_empty_line_string_with_itself(self):
|
|
ls = LineString([])
|
|
ls_concat = ls.concatenate(ls)
|
|
assert ls_concat.coords_almost_equals([])
|
|
|
|
def test_concatenate_empty_line_string_with_single_point_line_string(self):
|
|
ls = LineString([])
|
|
ls_concat = ls.concatenate(LineString([(0, 0)]))
|
|
assert ls_concat.coords_almost_equals([(0, 0)])
|
|
|
|
def test_concatenate_single_point_line_string_with_empty_line_string(self):
|
|
ls = LineString([(0, 0)])
|
|
ls_concat = ls.concatenate(LineString([]))
|
|
assert ls_concat.coords_almost_equals([(0, 0)])
|
|
|
|
def test_concatenate_empty_line_string_with_list_of_tuples(self):
|
|
ls = LineString([])
|
|
ls_concat = ls.concatenate([(0, 0)])
|
|
assert ls_concat.coords_almost_equals([(0, 0)])
|
|
|
|
def test_to_keypoints(self):
|
|
ls = LineString([(0, 0), (1, 0), (2, 1)])
|
|
observed = ls.to_keypoints()
|
|
assert all([isinstance(kp, ia.Keypoint) for kp in observed])
|
|
assert np.isclose(observed[0].x, 0)
|
|
assert np.isclose(observed[0].y, 0)
|
|
assert np.isclose(observed[1].x, 1)
|
|
assert np.isclose(observed[1].y, 0)
|
|
assert np.isclose(observed[2].x, 2)
|
|
assert np.isclose(observed[2].y, 1)
|
|
|
|
def test_to_keypoints_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
assert len(ls.to_keypoints()) == 0
|
|
|
|
def test_to_bounding_box(self):
|
|
ls = LineString([(0, 0), (1, 0), (1, 1)])
|
|
observed = ls.to_bounding_box()
|
|
assert isinstance(observed, ia.BoundingBox)
|
|
assert np.isclose(observed.x1, 0)
|
|
assert np.isclose(observed.y1, 0)
|
|
assert np.isclose(observed.x2, 1)
|
|
assert np.isclose(observed.y2, 1)
|
|
|
|
def test_to_bounding_box_with_single_point_line_string(self):
|
|
ls = LineString([(0, 0)])
|
|
observed = ls.to_bounding_box()
|
|
assert isinstance(observed, ia.BoundingBox)
|
|
assert np.isclose(observed.x1, 0)
|
|
assert np.isclose(observed.y1, 0)
|
|
assert np.isclose(observed.x2, 0)
|
|
assert np.isclose(observed.y2, 0)
|
|
|
|
def test_to_bounding_box_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
observed = ls.to_bounding_box()
|
|
assert observed is None
|
|
|
|
def test_to_polygon(self):
|
|
ls = LineString([(0, 0), (1, 0), (1, 1)])
|
|
observed = ls.to_polygon()
|
|
assert isinstance(observed, ia.Polygon)
|
|
assert np.allclose(observed.exterior, [(0, 0), (1, 0), (1, 1)])
|
|
|
|
def test_to_polygon_with_single_point_line_string(self):
|
|
ls = LineString([(0, 0)])
|
|
observed = ls.to_polygon()
|
|
assert isinstance(observed, ia.Polygon)
|
|
assert np.allclose(observed.exterior, [(0, 0)])
|
|
|
|
def test_to_polygon_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
observed = ls.to_polygon()
|
|
assert isinstance(observed, ia.Polygon)
|
|
assert len(observed.exterior) == 0
|
|
|
|
# TODO add antialiased=True test
|
|
def test_to_heatmap(self):
|
|
ls = LineString([(0, 5), (5, 5)])
|
|
observed = ls.to_heatmap((10, 10), antialiased=False)
|
|
assert isinstance(observed, HeatmapsOnImage)
|
|
assert observed.shape == (10, 10)
|
|
assert observed.arr_0to1.shape == (10, 10, 1)
|
|
assert np.allclose(observed.arr_0to1[0:5, :, :], 0.0)
|
|
assert np.allclose(observed.arr_0to1[5, 0:5, :], 1.0)
|
|
assert np.allclose(observed.arr_0to1[6:, :, :], 0.0)
|
|
|
|
def test_to_heatmap_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
observed = ls.to_heatmap((5, 5), antialiased=False)
|
|
assert observed.shape == (5, 5)
|
|
assert observed.arr_0to1.shape == (5, 5, 1)
|
|
assert np.allclose(observed.arr_0to1, 0.0)
|
|
|
|
# TODO change this after the segmap PR was merged
|
|
|
|
def test_segmentation_map(self):
|
|
from imgaug.augmentables.segmaps import SegmentationMapsOnImage
|
|
ls = LineString([(0, 5), (5, 5)])
|
|
observed = ls.to_segmentation_map((10, 10))
|
|
assert isinstance(observed, SegmentationMapsOnImage)
|
|
assert observed.shape == (10, 10)
|
|
assert observed.arr.shape == (10, 10, 1)
|
|
assert np.all(observed.arr[0:5, :, :] == 0)
|
|
assert np.all(observed.arr[5, 0:5, :] == 1)
|
|
assert np.all(observed.arr[6:, :, :] == 0)
|
|
|
|
ls = LineString([])
|
|
observed = ls.to_segmentation_map((5, 5))
|
|
assert observed.shape == (5, 5)
|
|
assert observed.arr.shape == (5, 5, 1)
|
|
assert np.all(observed.arr == 0)
|
|
|
|
def test_coords_almost_equals_with_3_point_ls_90deg_angle(self):
|
|
ls = LineString([(0, 0), (1, 0), (1, 1)])
|
|
assert ls.coords_almost_equals(ls)
|
|
assert ls.coords_almost_equals([(0, 0), (1, 0), (1, 1)])
|
|
assert not ls.shift(y=1).coords_almost_equals(ls)
|
|
assert ls.shift(y=1).coords_almost_equals(ls, max_distance=1.01)
|
|
assert ls.coords_almost_equals([(0, 0), (0.5, 0), (1, 0), (1, 1)])
|
|
|
|
def test_coords_almost_equals_with_4_point_ls_90deg_angle(self):
|
|
ls = LineString([(0, 0), (0.5, 0), (1, 0), (1, 1)])
|
|
assert ls.coords_almost_equals([(0, 0), (1, 0), (1, 1)])
|
|
|
|
def test_coords_almost_equals_with_1_point_ls(self):
|
|
ls = LineString([(0, 0)])
|
|
assert ls.coords_almost_equals([(0, 0)])
|
|
assert not ls.coords_almost_equals([(0+1, 0)])
|
|
assert ls.coords_almost_equals([(0+1, 0)], max_distance=1.01)
|
|
assert not ls.coords_almost_equals([])
|
|
|
|
def test_coords_almost_equals_with_empty_line_string(self):
|
|
ls = LineString([])
|
|
assert ls.coords_almost_equals([])
|
|
assert not ls.coords_almost_equals([(0, 0)])
|
|
|
|
def test_coords_almost_equals_with_two_rectangular_line_strings(self):
|
|
# two rectangles around height=10, width=10 image,
|
|
# both LS closed, second one has more points around the left edge
|
|
ls_a = LineString([(0, 0), (10, 0), (10, 10), (0, 10), (0, 0)])
|
|
ls_b = LineString([(0, 0), (10, 0), (10, 10), (0, 10),
|
|
(0, 5.01), (0, 5.0), (0, 4.99), (0, 0)])
|
|
assert ls_a.coords_almost_equals(ls_b)
|
|
|
|
def test_coords_almost_equals_different_ls_but_overlapping_points(self):
|
|
# almost the same as in above test
|
|
# two rectangles around height=10, width=10 image,
|
|
# both LS closed, second one has more points around the left edge
|
|
# AND around left edge the second line string suddenly has a line
|
|
# up to the right edge, which immediately returns back to the left
|
|
# edge
|
|
# All points overlap between the lines, i.e. this test fails if naively
|
|
# checking for overlapping points.
|
|
ls_a = LineString([(0, 0), (10, 0), (10, 10), (0, 10), (0, 0)])
|
|
ls_b = LineString([(0, 0), (10, 0), (10, 10), (0, 10),
|
|
(0, 5.01), (10, 5.0), (0, 4.99), (0, 0)])
|
|
assert not ls_a.coords_almost_equals(ls_b)
|
|
|
|
def test_almost_equals_three_point_ls_without_label(self):
|
|
ls = LineString([(0, 0), (1, 0), (1, 1)])
|
|
ls_shifted = ls.shift(y=1)
|
|
assert ls.almost_equals(ls)
|
|
assert not ls.almost_equals(ls_shifted)
|
|
assert ls.almost_equals(LineString([(0, 0), (1, 0), (1, 1)],
|
|
label=None))
|
|
assert not ls.almost_equals(LineString([(0, 0), (1, 0), (1, 1)],
|
|
label="foo"))
|
|
|
|
def test_almost_equals_three_point_ls_with_label(self):
|
|
ls = LineString([(0, 0), (1, 0), (1, 1)], label="foo")
|
|
assert not ls.almost_equals(LineString([(0, 0), (1, 0), (1, 1)],
|
|
label=None))
|
|
assert ls.almost_equals(LineString([(0, 0), (1, 0), (1, 1)],
|
|
label="foo"))
|
|
|
|
def test_almost_equals_empty_line_string(self):
|
|
ls = LineString([])
|
|
assert ls.almost_equals(LineString([]))
|
|
assert not ls.almost_equals(LineString([], label="foo"))
|
|
|
|
def test_almost_equals_empty_line_string_with_label(self):
|
|
ls = LineString([], label="foo")
|
|
assert not ls.almost_equals(LineString([]))
|
|
assert ls.almost_equals(LineString([], label="foo"))
|
|
|
|
def test_copy_with_various_line_strings(self):
|
|
coords = [
|
|
[(0, 0), (1, 0), (1, 1)],
|
|
[(0, 0), (1.5, 0), (1.6, 1)],
|
|
[(0, 0)],
|
|
[],
|
|
[(0, 0), (1, 0), (1, 1)]
|
|
]
|
|
labels = [None, None, None, None, "foo"]
|
|
|
|
for coords_i, label in zip(coords, labels):
|
|
with self.subTest(coords=coords_i, label=label):
|
|
ls = LineString(coords_i, label=label)
|
|
observed = ls.copy()
|
|
assert observed is not ls
|
|
assert observed.coords is ls.coords
|
|
assert observed.label is ls.label
|
|
|
|
def test_copy_with_coords_arg_set(self):
|
|
ls = LineString([(0, 0), (1, 0), (1, 1)])
|
|
observed = ls.copy(coords=[(0, 0)])
|
|
assert observed.coords_almost_equals([(0, 0)])
|
|
assert observed.label is None
|
|
|
|
def test_copy_with_label_arg_set(self):
|
|
ls = LineString([(0, 0), (1, 0), (1, 1)])
|
|
observed = ls.copy(label="bar")
|
|
assert observed.coords is ls.coords
|
|
assert observed.label == "bar"
|
|
|
|
def test_deepcopy_with_various_line_strings(self):
|
|
coords = [
|
|
[(0, 0), (1, 0), (1, 1)],
|
|
[(0, 0), (1.5, 0), (1.6, 1)],
|
|
[(0, 0)],
|
|
[],
|
|
[(0, 0), (1, 0), (1, 1)]
|
|
]
|
|
labels = [None, None, None, None, "foo"]
|
|
|
|
for coords_i, label in zip(coords, labels):
|
|
with self.subTest(coords=coords_i, label=label):
|
|
ls = LineString(coords_i, label=label)
|
|
observed = ls.deepcopy()
|
|
assert observed is not ls
|
|
assert observed.coords is not ls.coords
|
|
assert observed.label == ls.label
|
|
|
|
def test_deepcopy_with_coords_arg_set(self):
|
|
ls = LineString([(0, 0), (1, 0), (1, 1)])
|
|
observed = ls.deepcopy(coords=[(0, 0)])
|
|
assert observed.coords_almost_equals([(0, 0)])
|
|
assert observed.label is None
|
|
|
|
def test_deepcopy_with_label_arg_set(self):
|
|
ls = LineString([(0, 0), (1, 0), (1, 1)])
|
|
observed = ls.deepcopy(label="bar")
|
|
assert observed.coords is not ls.coords
|
|
assert observed.label == "bar"
|
|
|
|
def test_string_conversion(self):
|
|
coords = [
|
|
[(0, 0), (1, 0), (1, 1)],
|
|
[(0, 0), (1.5, 0), (1.6, 1)],
|
|
[(0, 0)],
|
|
[],
|
|
[(0, 0), (1, 0), (1, 1)]
|
|
]
|
|
labels = [None, None, None, None, "foo"]
|
|
|
|
for coords_i, label in zip(coords, labels):
|
|
with self.subTest(coords=coords_i, label=label):
|
|
ls = LineString(coords_i, label=label)
|
|
# __str__() is tested more thoroughly in other tests
|
|
assert ls.__repr__() == ls.__str__()
|
|
|
|
def test___getitem__(self):
|
|
cba = ia.LineString([(0, 1), (2, 3)])
|
|
assert np.allclose(cba[0], (0, 1))
|
|
assert np.allclose(cba[1], (2, 3))
|
|
|
|
def test___getitem___slice(self):
|
|
cba = ia.LineString([(0, 1), (2, 3), (4, 5)])
|
|
assert np.allclose(cba[1:], [(2, 3), (4, 5)])
|
|
|
|
def test___iter___two_points(self):
|
|
cba = LineString([(1, 2), (3, 4)])
|
|
for i, xy in enumerate(cba):
|
|
assert i in [0, 1]
|
|
if i == 0:
|
|
assert np.allclose(xy, (1, 2))
|
|
elif i == 1:
|
|
assert np.allclose(xy, (3, 4))
|
|
assert i == 1
|
|
|
|
def test___iter___zero_points(self):
|
|
cba = LineString([])
|
|
i = 0
|
|
for xy in cba:
|
|
i += 1
|
|
assert i == 0
|
|
|
|
def test___str__(self):
|
|
coords = [
|
|
[(0, 0), (1, 0), (1, 1)],
|
|
[(0, 0), (1.5, 0), (1.6, 1)],
|
|
[(0, 0)],
|
|
[],
|
|
[(0, 0), (1, 0), (1, 1)]
|
|
]
|
|
labels = [None, None, None, None, "foo"]
|
|
expecteds = [
|
|
"LineString([(0.00, 0.00), (1.00, 0.00), (1.00, 1.00)], "
|
|
"label=None)",
|
|
"LineString([(0.00, 0.00), (1.50, 0.00), (1.60, 1.00)], "
|
|
"label=None)",
|
|
"LineString([(0.00, 0.00)], label=None)",
|
|
"LineString([], label=None)",
|
|
"LineString([(0.00, 0.00), (1.00, 0.00), (1.00, 1.00)], "
|
|
"label=foo)"
|
|
]
|
|
|
|
for coords_i, label, expected in zip(coords, labels, expecteds):
|
|
with self.subTest(coords=coords_i, label=label):
|
|
ls = LineString(coords_i, label=label)
|
|
observed = ls.__str__()
|
|
assert observed == expected
|
|
|
|
|
|
class TestLineStringsOnImage_items_setter(unittest.TestCase):
|
|
def test_with_list_of_line_strings(self):
|
|
ls = [ia.LineString([(0, 0), (1, 0)]),
|
|
ia.LineString([(1, 1), (10, 0)])]
|
|
lsoi = ia.LineStringsOnImage([], shape=(10, 20, 3))
|
|
lsoi.items = ls
|
|
assert np.all([
|
|
(np.allclose(ls_i.coords, ls_j.coords))
|
|
for ls_i, ls_j
|
|
in zip(lsoi.line_strings, ls)
|
|
])
|
|
|
|
|
|
class TestLineStringsOnImage_on_(unittest.TestCase):
|
|
@property
|
|
def _is_inplace(self):
|
|
return True
|
|
|
|
def _func(self, lsoi, to_shape):
|
|
return lsoi.on_(to_shape)
|
|
|
|
def test_on_image_with_same_shape(self):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
lsoi_proj = self._func(lsoi, (100, 100, 3))
|
|
|
|
assert np.all([ls_a.coords_almost_equals(ls_b)
|
|
for ls_a, ls_b
|
|
in zip(lsoi.line_strings, lsoi_proj.line_strings)])
|
|
assert lsoi_proj.shape == (100, 100, 3)
|
|
|
|
def test_on_image_with_2x_size(self):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
lsoi_proj = self._func(lsoi, (200, 200, 3))
|
|
|
|
assert lsoi_proj.line_strings[0].coords_almost_equals(
|
|
[(0, 0), (1*2, 0), (2*2, 1*2)]
|
|
)
|
|
assert lsoi_proj.line_strings[1].coords_almost_equals(
|
|
[(10*2, 10*2)]
|
|
)
|
|
assert lsoi_proj.shape == (200, 200, 3)
|
|
|
|
def test_on_image_with_2x_size_and_empty_list_of_line_strings(self):
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
lsoi_proj = self._func(lsoi, (200, 200, 3))
|
|
|
|
assert len(lsoi_proj.line_strings) == 0
|
|
assert lsoi_proj.shape == (200, 200, 3)
|
|
|
|
def test_inplaceness(self):
|
|
ls = ia.LineString([(0, 0), (1, 0)])
|
|
lsoi = LineStringsOnImage([ls], shape=(10, 10, 3))
|
|
lsoi2 = self._func(lsoi, (10, 10))
|
|
if self._is_inplace:
|
|
assert lsoi is lsoi2
|
|
else:
|
|
assert lsoi is not lsoi2
|
|
|
|
|
|
class TestLineStringsOnImage_on(TestLineStringsOnImage_on_):
|
|
@property
|
|
def _is_inplace(self):
|
|
return False
|
|
|
|
def _func(self, lsoi, to_shape):
|
|
return lsoi.on(to_shape)
|
|
|
|
|
|
class TestLineStringsOnImage_remove_out_of_image_(unittest.TestCase):
|
|
@property
|
|
def _is_inplace(self):
|
|
return True
|
|
|
|
def _func(self, lsoi, fully=True, partly=False):
|
|
return lsoi.remove_out_of_image_(fully=fully, partly=partly)
|
|
|
|
def test_remove_out_of_image_with_two_line_strings(self):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi)
|
|
|
|
assert len(observed.line_strings) == 2
|
|
assert observed.line_strings[0] is ls1
|
|
assert observed.line_strings[1] is ls2
|
|
|
|
def test_remove_out_of_image_with_empty_list_of_line_strings(self):
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi)
|
|
|
|
assert len(observed.line_strings) == 0
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_remove_out_of_image_with_one_empty_line_string(self):
|
|
ls1 = LineString([])
|
|
lsoi = LineStringsOnImage([ls1], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi)
|
|
|
|
assert len(observed.line_strings) == 0
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_remove_out_of_image_with_one_line_string(self):
|
|
ls1 = LineString([(-10, -10), (5, 5)])
|
|
lsoi = LineStringsOnImage([ls1], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi)
|
|
|
|
assert len(observed.line_strings) == 1
|
|
assert observed.line_strings[0] is ls1
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_remove_out_of_image_remove_even_partial_oois(self):
|
|
ls1 = LineString([(-10, -10), (5, 5)])
|
|
lsoi = LineStringsOnImage([ls1], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi, partly=True, fully=True)
|
|
|
|
assert len(observed.line_strings) == 0
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_remove_out_of_image_with_one_single_point_line_strings(self):
|
|
ls1 = LineString([(-10, -10)])
|
|
lsoi = LineStringsOnImage([ls1], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi)
|
|
|
|
assert len(observed.line_strings) == 0
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_remove_out_of_image_partly_false_and_fully_false(self):
|
|
ls1 = LineString([(-10, -10)])
|
|
lsoi = LineStringsOnImage([ls1], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi, partly=False, fully=False)
|
|
|
|
assert len(observed.line_strings) == 1
|
|
assert observed.line_strings[0] is ls1
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_inplaceness(self):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
lsoi2 = self._func(lsoi)
|
|
|
|
if self._is_inplace:
|
|
assert lsoi is lsoi2
|
|
else:
|
|
assert lsoi is not lsoi2
|
|
|
|
|
|
class TestLineStringsOnImage_remove_out_of_image(
|
|
TestLineStringsOnImage_remove_out_of_image_):
|
|
@property
|
|
def _is_inplace(self):
|
|
return False
|
|
|
|
def _func(self, lsoi, fully=True, partly=False):
|
|
return lsoi.remove_out_of_image(fully=fully, partly=partly)
|
|
|
|
|
|
class TestLineStringsOnImage_clip_out_of_image_(unittest.TestCase):
|
|
@property
|
|
def _is_inplace(self):
|
|
return True
|
|
|
|
def _func(self, lsoi):
|
|
return lsoi.clip_out_of_image_()
|
|
|
|
def test_clip_out_of_image_with_two_simple_line_strings(self):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi)
|
|
|
|
expected = []
|
|
expected.extend(ls1.clip_out_of_image((100, 100, 3)))
|
|
expected.extend(ls2.clip_out_of_image((100, 100, 3)))
|
|
assert len(lsoi.line_strings) == len(expected)
|
|
for ls_obs, ls_exp in zip(observed.line_strings, expected):
|
|
assert ls_obs.coords_almost_equals(ls_exp)
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_clip_out_of_image_with_empty_list_of_line_strings(self):
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi)
|
|
|
|
assert len(observed.line_strings) == 0
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_clip_out_of_image_with_one_empty_line_string(self):
|
|
ls1 = LineString([])
|
|
lsoi = LineStringsOnImage([ls1], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi)
|
|
|
|
assert len(observed.line_strings) == 0
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_clip_out_of_image_with_single_point_ls_and_negative_coords(self):
|
|
ls1 = LineString([(-10, -10)])
|
|
lsoi = LineStringsOnImage([ls1], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi)
|
|
|
|
assert len(observed.line_strings) == 0
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_inplaceness(self):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
lsoi2 = self._func(lsoi)
|
|
|
|
if self._is_inplace:
|
|
assert lsoi is lsoi2
|
|
else:
|
|
assert lsoi is not lsoi2
|
|
|
|
|
|
class TestLineStringsOnImage_clip_out_of_image(
|
|
TestLineStringsOnImage_clip_out_of_image_):
|
|
@property
|
|
def _is_inplace(self):
|
|
return False
|
|
|
|
def _func(self, lsoi):
|
|
return lsoi.clip_out_of_image()
|
|
|
|
|
|
class TestLineStringsOnImage_shift_(unittest.TestCase):
|
|
@property
|
|
def _is_inplace(self):
|
|
return True
|
|
|
|
def _func(self, lsoi, *args, **kwargs):
|
|
def _func_impl():
|
|
return lsoi.shift_(*args, **kwargs)
|
|
|
|
if len(lsoi.line_strings) == 0:
|
|
return _func_impl()
|
|
return wrap_shift_deprecation(_func_impl, *args, **kwargs)
|
|
|
|
def test_shift_two_simple_line_strings_along_xy(self):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi.deepcopy(), x=1, y=2)
|
|
|
|
assert observed.line_strings[0].coords_almost_equals(
|
|
ls1.shift(x=1, y=2)
|
|
)
|
|
assert observed.line_strings[1].coords_almost_equals(
|
|
ls2.shift(x=1, y=2)
|
|
)
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_inplaceness(self):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
lsoi2 = self._func(lsoi, y=1)
|
|
|
|
if self._is_inplace:
|
|
assert lsoi is lsoi2
|
|
else:
|
|
assert lsoi is not lsoi2
|
|
|
|
|
|
class TestLineStringsOnImage_shift(TestLineStringsOnImage_shift_):
|
|
@property
|
|
def _is_inplace(self):
|
|
return False
|
|
|
|
def _func(self, lsoi, *args, **kwargs):
|
|
def _func_impl():
|
|
return lsoi.shift(*args, **kwargs)
|
|
|
|
return wrap_shift_deprecation(_func_impl, *args, **kwargs)
|
|
|
|
def test_shift_with_two_simple_line_strings(self):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi.deepcopy(), top=1, right=2, bottom=3, left=4)
|
|
|
|
assert observed.line_strings[0].coords_almost_equals([
|
|
(0 - 2 + 4, 0 + 1 - 3),
|
|
(1 - 2 + 4, 0 + 1 - 3),
|
|
(2 - 2 + 4, 1 + 1 - 3)
|
|
])
|
|
assert observed.line_strings[1].coords_almost_equals([
|
|
(10 - 2 + 4, 10 + 1 - 3)
|
|
])
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_shift_with_empty_list_of_line_strings(self):
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = self._func(lsoi, top=1, right=2, bottom=3, left=4)
|
|
|
|
assert len(observed.line_strings) == 0
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
|
|
# TODO test to_keypoints_on_image()
|
|
# test invert_to_keypoints_on_image()
|
|
# test to_xy_array()
|
|
# test fill_from_xy_array_()
|
|
class TestLineStringsOnImage(unittest.TestCase):
|
|
def setUp(self):
|
|
reseed()
|
|
|
|
def test___init__(self):
|
|
lsoi = LineStringsOnImage([
|
|
LineString([]),
|
|
LineString([(0, 0), (5, 0)])
|
|
], shape=(10, 10, 3))
|
|
assert len(lsoi.line_strings) == 2
|
|
assert lsoi.shape == (10, 10, 3)
|
|
|
|
def test___init___shape_is_array(self):
|
|
image = np.zeros((10, 10, 3), dtype=np.uint8)
|
|
with assertWarns(self, ia.DeprecationWarning):
|
|
lsoi = LineStringsOnImage([
|
|
LineString([]),
|
|
LineString([(0, 0), (5, 0)])
|
|
], shape=image)
|
|
assert len(lsoi.line_strings) == 2
|
|
assert lsoi.shape == (10, 10, 3)
|
|
|
|
def test___init___with_empty_list(self):
|
|
lsoi = LineStringsOnImage([], shape=(10, 10))
|
|
assert lsoi.line_strings == []
|
|
assert lsoi.shape == (10, 10)
|
|
|
|
def test_items(self):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
items = lsoi.items
|
|
|
|
assert items == [ls1, ls2]
|
|
|
|
def test_items_empty(self):
|
|
kpsoi = LineStringsOnImage([], shape=(40, 50, 3))
|
|
|
|
items = kpsoi.items
|
|
|
|
assert items == []
|
|
|
|
def test_empty_with_empty_list(self):
|
|
lsoi = LineStringsOnImage([], shape=(10, 10, 3))
|
|
assert lsoi.empty
|
|
|
|
def test_empty_with_list_of_empty_line_string(self):
|
|
lsoi = LineStringsOnImage([LineString([])], shape=(10, 10, 3))
|
|
assert not lsoi.empty
|
|
|
|
def test_empty_with_list_of_single_point_line_string(self):
|
|
lsoi = LineStringsOnImage([LineString([(0, 0)])], shape=(10, 10, 3))
|
|
assert not lsoi.empty
|
|
|
|
def test_from_xy_arrays_single_input_array_with_two_line_strings(self):
|
|
arrs = np.float32([
|
|
[(0, 0), (10, 10), (5, 10)],
|
|
[(5, 5), (15, 15), (10, 15)]
|
|
])
|
|
|
|
lsoi = LineStringsOnImage.from_xy_arrays(arrs, shape=(100, 100, 3))
|
|
|
|
assert len(lsoi.line_strings) == 2
|
|
assert lsoi.line_strings[0].coords_almost_equals(arrs[0])
|
|
assert lsoi.line_strings[1].coords_almost_equals(arrs[1])
|
|
|
|
def test_from_xy_arrays_with_list_of_two_line_string_arrays(self):
|
|
arrs = [
|
|
np.float32([(0, 0), (10, 10), (5, 10)]),
|
|
np.float32([(5, 5), (15, 15), (10, 15), (25, 25)])
|
|
]
|
|
|
|
lsoi = LineStringsOnImage.from_xy_arrays(arrs, shape=(100, 100, 3))
|
|
|
|
assert len(lsoi.line_strings) == 2
|
|
assert lsoi.line_strings[0].coords_almost_equals(arrs[0])
|
|
assert lsoi.line_strings[1].coords_almost_equals(arrs[1])
|
|
|
|
def test_from_xy_arrays_with_empty_3d_array_and_0_points_per_ls(self):
|
|
arrs = np.zeros((0, 0, 2), dtype=np.float32)
|
|
|
|
lsoi = LineStringsOnImage.from_xy_arrays(arrs, shape=(100, 100, 3))
|
|
|
|
assert len(lsoi.line_strings) == 0
|
|
|
|
def test_from_xy_arrays_with_empty_3d_array_and_5_points_per_ls(self):
|
|
arrs = np.zeros((0, 5, 2), dtype=np.float32)
|
|
|
|
lsoi = LineStringsOnImage.from_xy_arrays(arrs, shape=(100, 100, 3))
|
|
|
|
assert len(lsoi.line_strings) == 0
|
|
|
|
def test_to_xy_arrays_with_two_line_strings_of_same_length(self):
|
|
ls1 = LineString([(0, 0), (10, 10), (5, 10)])
|
|
ls2 = LineString([(5, 5), (15, 15), (10, 15)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
arrs = lsoi.to_xy_arrays()
|
|
|
|
assert isinstance(arrs, list)
|
|
assert len(arrs) == 2
|
|
assert arrs[0].dtype.name == "float32"
|
|
assert arrs[1].dtype.name == "float32"
|
|
assert np.allclose(arrs, [
|
|
[(0, 0), (10, 10), (5, 10)],
|
|
[(5, 5), (15, 15), (10, 15)]
|
|
])
|
|
|
|
def test_to_xy_arrays_with_two_line_strings_of_different_lengths(self):
|
|
ls1 = LineString([(0, 0), (10, 10), (5, 10)])
|
|
ls2 = LineString([(5, 5), (15, 15), (10, 15), (25, 25)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
arrs = lsoi.to_xy_arrays()
|
|
|
|
assert isinstance(arrs, list)
|
|
assert len(arrs) == 2
|
|
assert arrs[0].dtype.name == "float32"
|
|
assert arrs[1].dtype.name == "float32"
|
|
assert np.allclose(arrs[0], [(0, 0), (10, 10), (5, 10)])
|
|
assert np.allclose(arrs[1], [(5, 5), (15, 15), (10, 15), (25, 25)])
|
|
|
|
def test_to_xy_arrays_with_two_line_strings_one_of_them_empty(self):
|
|
ls1 = LineString([])
|
|
ls2 = LineString([(5, 5), (15, 15), (10, 15), (25, 25)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
arrs = lsoi.to_xy_arrays()
|
|
|
|
assert isinstance(arrs, list)
|
|
assert len(arrs) == 2
|
|
assert arrs[0].dtype.name == "float32"
|
|
assert arrs[1].dtype.name == "float32"
|
|
assert arrs[0].shape == (0, 2)
|
|
assert np.allclose(arrs[1], [(5, 5), (15, 15), (10, 15), (25, 25)])
|
|
|
|
def test_to_xy_arrays_with_two_empty_list_of_line_strings(self):
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
arrs = lsoi.to_xy_arrays()
|
|
|
|
assert isinstance(arrs, list)
|
|
assert len(arrs) == 0
|
|
|
|
def test_draw_on_image_with_default_settings(self):
|
|
ls1 = LineString([(0, 0), (10, 10), (5, 10)])
|
|
ls2 = LineString([(5, 5), (15, 15), (10, 15), (25, 25)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
img = np.zeros((100, 100, 3), dtype=np.uint8) + 1
|
|
|
|
observed = lsoi.draw_on_image(img)
|
|
|
|
expected = np.copy(img)
|
|
for ls in [ls1, ls2]:
|
|
expected = ls.draw_on_image(expected)
|
|
assert np.array_equal(observed, expected)
|
|
|
|
def test_draw_on_image_with_custom_settings(self):
|
|
ls1 = LineString([(0, 0), (10, 10), (5, 10)])
|
|
ls2 = LineString([(5, 5), (15, 15), (10, 15), (25, 25)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
img = np.zeros((100, 100, 3), dtype=np.uint8) + 1
|
|
|
|
observed = lsoi.draw_on_image(img,
|
|
color_lines=(0, 0, 255),
|
|
color_points=(255, 0, 0),
|
|
alpha_lines=0.5,
|
|
alpha_points=0.6,
|
|
antialiased=False)
|
|
|
|
expected = np.copy(img)
|
|
for ls in [ls1, ls2]:
|
|
expected = ls.draw_on_image(expected,
|
|
color_lines=(0, 0, 255),
|
|
color_points=(255, 0, 0),
|
|
alpha_lines=0.5,
|
|
alpha_points=0.6,
|
|
antialiased=False)
|
|
assert np.array_equal(observed, expected)
|
|
|
|
def test_draw_on_image_with_default_settings_one_ls_empty(self):
|
|
ls1 = LineString([])
|
|
ls2 = LineString([(5, 5), (15, 15), (10, 15), (25, 25)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
img = np.zeros((100, 100, 3), dtype=np.uint8) + 1
|
|
|
|
observed = lsoi.draw_on_image(img)
|
|
|
|
expected = np.copy(img)
|
|
for ls in [ls1, ls2]:
|
|
expected = ls.draw_on_image(expected)
|
|
assert np.array_equal(observed, expected)
|
|
|
|
def test_draw_on_image_with_default_settings_and_empty_list_of_ls(self):
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
img = np.zeros((100, 100, 3), dtype=np.uint8) + 1
|
|
|
|
observed = lsoi.draw_on_image(img)
|
|
|
|
expected = np.copy(img)
|
|
assert np.array_equal(observed, expected)
|
|
|
|
def test_remove_out_of_image_fraction_(self):
|
|
item1 = ia.LineString([(5, 1), (9, 1)])
|
|
item2 = ia.LineString([(5, 1), (15, 1)])
|
|
item3 = ia.LineString([(15, 1), (25, 1)])
|
|
cbaoi = ia.LineStringsOnImage([item1, item2, item3],
|
|
shape=(10, 10, 3))
|
|
|
|
cbaoi_reduced = cbaoi.remove_out_of_image_fraction_(0.6)
|
|
|
|
assert len(cbaoi_reduced.items) == 2
|
|
assert cbaoi_reduced.items == [item1, item2]
|
|
assert cbaoi_reduced is cbaoi
|
|
|
|
def test_remove_out_of_image_fraction(self):
|
|
item1 = ia.LineString([(5, 1), (9, 1)])
|
|
item2 = ia.LineString([(5, 1), (15, 1)])
|
|
item3 = ia.LineString([(15, 1), (25, 1)])
|
|
cbaoi = ia.LineStringsOnImage([item1, item2, item3],
|
|
shape=(10, 10, 3))
|
|
|
|
cbaoi_reduced = cbaoi.remove_out_of_image_fraction(0.6)
|
|
|
|
assert len(cbaoi_reduced.items) == 2
|
|
assert cbaoi_reduced.items == [item1, item2]
|
|
assert cbaoi_reduced is not cbaoi
|
|
|
|
def test_to_xy_array(self):
|
|
lsoi = ia.LineStringsOnImage(
|
|
[ia.LineString([(0, 0), (1, 2)]),
|
|
ia.LineString([(10, 20), (30, 40)])],
|
|
shape=(1, 2, 3))
|
|
|
|
xy_out = lsoi.to_xy_array()
|
|
|
|
expected = np.float32([
|
|
[0.0, 0.0],
|
|
[1.0, 2.0],
|
|
[10.0, 20.0],
|
|
[30.0, 40.0]
|
|
])
|
|
assert xy_out.shape == (4, 2)
|
|
assert np.allclose(xy_out, expected)
|
|
assert xy_out.dtype.name == "float32"
|
|
|
|
def test_to_xy_array__empty_object(self):
|
|
lsoi = ia.LineStringsOnImage(
|
|
[],
|
|
shape=(1, 2, 3))
|
|
|
|
xy_out = lsoi.to_xy_array()
|
|
|
|
assert xy_out.shape == (0, 2)
|
|
assert xy_out.dtype.name == "float32"
|
|
|
|
def test_fill_from_xy_array___empty_array(self):
|
|
xy = np.zeros((0, 2), dtype=np.float32)
|
|
lsoi = ia.LineStringsOnImage([], shape=(2, 2, 3))
|
|
|
|
lsoi = lsoi.fill_from_xy_array_(xy)
|
|
|
|
assert len(lsoi.line_strings) == 0
|
|
|
|
def test_fill_from_xy_array___empty_list(self):
|
|
xy = []
|
|
lsoi = ia.LineStringsOnImage([], shape=(2, 2, 3))
|
|
|
|
lsoi = lsoi.fill_from_xy_array_(xy)
|
|
|
|
assert len(lsoi.line_strings) == 0
|
|
|
|
def test_fill_from_xy_array___array_with_two_coords(self):
|
|
xy = np.array(
|
|
[(100, 101),
|
|
(102, 103),
|
|
(200, 201),
|
|
(202, 203)], dtype=np.float32)
|
|
lsoi = ia.LineStringsOnImage(
|
|
[ia.LineString([(0, 0), (1, 2)]),
|
|
ia.LineString([(10, 20), (30, 40)])],
|
|
shape=(2, 2, 3))
|
|
|
|
lsoi = lsoi.fill_from_xy_array_(xy)
|
|
|
|
assert len(lsoi.line_strings) == 2
|
|
assert np.allclose(
|
|
lsoi.line_strings[0].coords,
|
|
[(100, 101), (102, 103)])
|
|
assert np.allclose(
|
|
lsoi.line_strings[1].coords,
|
|
[(200, 201), (202, 203)])
|
|
|
|
def test_fill_from_xy_array___list_with_two_coords(self):
|
|
xy = [(100, 101),
|
|
(102, 103),
|
|
(200, 201),
|
|
(202, 203)]
|
|
lsoi = ia.LineStringsOnImage(
|
|
[ia.LineString([(0, 0), (1, 2)]),
|
|
ia.LineString([(10, 20), (30, 40)])],
|
|
shape=(2, 2, 3))
|
|
|
|
lsoi = lsoi.fill_from_xy_array_(xy)
|
|
|
|
assert len(lsoi.line_strings) == 2
|
|
assert np.allclose(
|
|
lsoi.line_strings[0].coords,
|
|
[(100, 101), (102, 103)])
|
|
assert np.allclose(
|
|
lsoi.line_strings[1].coords,
|
|
[(200, 201), (202, 203)])
|
|
|
|
def test_to_keypoints_on_image(self):
|
|
lsoi = ia.LineStringsOnImage(
|
|
[ia.LineString([(0, 0), (1, 2)]),
|
|
ia.LineString([(10, 20), (30, 40)])],
|
|
shape=(1, 2, 3))
|
|
|
|
kpsoi = lsoi.to_keypoints_on_image()
|
|
|
|
assert len(kpsoi.keypoints) == 2*2
|
|
assert kpsoi.keypoints[0].x == 0
|
|
assert kpsoi.keypoints[0].y == 0
|
|
assert kpsoi.keypoints[1].x == 1
|
|
assert kpsoi.keypoints[1].y == 2
|
|
assert kpsoi.keypoints[2].x == 10
|
|
assert kpsoi.keypoints[2].y == 20
|
|
assert kpsoi.keypoints[3].x == 30
|
|
assert kpsoi.keypoints[3].y == 40
|
|
|
|
def test_to_keypoints_on_image__empty_instance(self):
|
|
lsoi = ia.LineStringsOnImage([], shape=(1, 2, 3))
|
|
|
|
kpsoi = lsoi.to_keypoints_on_image()
|
|
|
|
assert len(kpsoi.keypoints) == 0
|
|
|
|
def test_invert_to_keypoints_on_image_(self):
|
|
lsoi = ia.LineStringsOnImage(
|
|
[ia.LineString([(0, 0), (1, 2)]),
|
|
ia.LineString([(10, 20), (30, 40)])],
|
|
shape=(1, 2, 3))
|
|
kpsoi = ia.KeypointsOnImage(
|
|
[ia.Keypoint(100, 101), ia.Keypoint(102, 103),
|
|
ia.Keypoint(110, 120), ia.Keypoint(130, 140)],
|
|
shape=(10, 20, 30))
|
|
|
|
lsoi_inv = lsoi.invert_to_keypoints_on_image_(kpsoi)
|
|
|
|
assert len(lsoi_inv.line_strings) == 2
|
|
assert lsoi_inv.shape == (10, 20, 30)
|
|
assert np.allclose(
|
|
lsoi.line_strings[0].coords,
|
|
[(100, 101), (102, 103)])
|
|
assert np.allclose(
|
|
lsoi.line_strings[1].coords,
|
|
[(110, 120), (130, 140)])
|
|
|
|
def test_invert_to_keypoints_on_image___empty_instance(self):
|
|
lsoi = ia.LineStringsOnImage([], shape=(1, 2, 3))
|
|
kpsoi = ia.KeypointsOnImage([], shape=(10, 20, 30))
|
|
|
|
lsoi_inv = lsoi.invert_to_keypoints_on_image_(kpsoi)
|
|
|
|
assert len(lsoi_inv.line_strings) == 0
|
|
assert lsoi_inv.shape == (10, 20, 30)
|
|
|
|
def test_copy_with_two_line_strings(self):
|
|
# basic test, without labels
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.copy()
|
|
|
|
assert observed.line_strings[0] is ls1
|
|
assert observed.line_strings[1] is ls2
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_copy_with_two_line_strings_and_labels(self):
|
|
# basic test, with labels
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)], label="foo")
|
|
ls2 = LineString([(10, 10)], label="bar")
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.copy()
|
|
|
|
assert observed.line_strings[0] is ls1
|
|
assert observed.line_strings[1] is ls2
|
|
assert observed.line_strings[0].label == "foo"
|
|
assert observed.line_strings[1].label == "bar"
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_copy_with_empty_list_of_line_strings(self):
|
|
# LSOI is empty
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.copy()
|
|
|
|
assert observed.line_strings == []
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_copy_and_replace_line_strings_attribute(self):
|
|
# provide line_strings
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.copy(line_strings=[ls1, ls2], shape=(200, 201, 3))
|
|
|
|
assert observed.line_strings[0] is ls1
|
|
assert observed.line_strings[1] is ls2
|
|
assert observed.shape == (200, 201, 3)
|
|
|
|
def test_copy_and_replace_line_strings_attribute_with_labeled_ls(self):
|
|
# provide line_strings, with labels
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)], label="foo")
|
|
ls2 = LineString([(10, 10)], label="bar")
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.copy(line_strings=[ls1, ls2], shape=(200, 201, 3))
|
|
|
|
assert observed.line_strings[0] is ls1
|
|
assert observed.line_strings[1] is ls2
|
|
assert observed.line_strings[0].label == "foo"
|
|
assert observed.line_strings[1].label == "bar"
|
|
assert observed.shape == (200, 201, 3)
|
|
|
|
def test_copy_and_replace_line_strings_attribute_with_empty_list(self):
|
|
# provide empty list of line_strings
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.copy(line_strings=[], shape=(200, 201, 3))
|
|
|
|
assert observed.line_strings == []
|
|
assert observed.shape == (200, 201, 3)
|
|
|
|
def test_deepcopy_with_two_line_strings(self):
|
|
# basic test, without labels
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.deepcopy()
|
|
|
|
assert observed.line_strings[0] is not ls1
|
|
assert observed.line_strings[1] is not ls2
|
|
assert observed.line_strings[0].coords_almost_equals(ls1)
|
|
assert observed.line_strings[1].coords_almost_equals(ls2)
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_deepcopy_with_two_line_strings_and_labels(self):
|
|
# basic test, with labels
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)], label="foo")
|
|
ls2 = LineString([(10, 10)], label="bar")
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.deepcopy()
|
|
|
|
assert observed.line_strings[0] is not ls1
|
|
assert observed.line_strings[1] is not ls2
|
|
assert observed.line_strings[0].coords_almost_equals(ls1)
|
|
assert observed.line_strings[1].coords_almost_equals(ls2)
|
|
assert observed.line_strings[0].label == "foo"
|
|
assert observed.line_strings[1].label == "bar"
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_deepcopy_with_empty_list_of_line_strings(self):
|
|
# LSOI is empty
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.deepcopy()
|
|
|
|
assert observed.line_strings == []
|
|
assert observed.shape == (100, 100, 3)
|
|
|
|
def test_deepcopy_and_replace_line_strings_attribute(self):
|
|
# provide line_strings
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.deepcopy(line_strings=[ls1, ls2], shape=(200, 201, 3))
|
|
|
|
# line strings provided via line_strings are also deepcopied
|
|
assert observed.line_strings[0].coords_almost_equals(ls1)
|
|
assert observed.line_strings[1].coords_almost_equals(ls2)
|
|
assert observed.shape == (200, 201, 3)
|
|
|
|
def test_deepcopy_and_replace_line_strings_attribute_with_labeled_ls(self):
|
|
# provide line_strings, with labels
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)], label="foo")
|
|
ls2 = LineString([(10, 10)], label="bar")
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.deepcopy(line_strings=[ls1, ls2], shape=(200, 201, 3))
|
|
|
|
# line strings provided via line_strings are also deepcopied
|
|
assert observed.line_strings[0].coords_almost_equals(ls1)
|
|
assert observed.line_strings[1].coords_almost_equals(ls2)
|
|
assert observed.line_strings[0].label == "foo"
|
|
assert observed.line_strings[1].label == "bar"
|
|
assert observed.shape == (200, 201, 3)
|
|
|
|
def test_deepcopy_and_replace_line_strings_attribute_with_empty_list(self):
|
|
# provide empty list of line_strings
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = lsoi.deepcopy(line_strings=[], shape=(200, 201, 3))
|
|
|
|
assert observed.line_strings == []
|
|
assert observed.shape == (200, 201, 3)
|
|
|
|
def test___getitem__(self):
|
|
cbas = [
|
|
ia.LineString([(0, 0), (1, 0), (1, 1)]),
|
|
ia.LineString([(1, 1), (2, 1), (2, 2)])
|
|
]
|
|
cbasoi = ia.LineStringsOnImage(cbas, shape=(3, 4, 3))
|
|
|
|
assert cbasoi[0] is cbas[0]
|
|
assert cbasoi[1] is cbas[1]
|
|
assert cbasoi[0:2] == cbas
|
|
|
|
def test___iter__(self):
|
|
cbas = [ia.LineString([(0, 0), (1, 1)]),
|
|
ia.LineString([(1, 2), (3, 4)])]
|
|
cbasoi = ia.LineStringsOnImage(cbas, shape=(40, 50, 3))
|
|
|
|
for i, cba in enumerate(cbasoi):
|
|
assert cba is cbas[i]
|
|
|
|
def test___iter___empty(self):
|
|
cbasoi = ia.LineStringsOnImage([], shape=(40, 50, 3))
|
|
i = 0
|
|
for _cba in cbasoi:
|
|
i += 1
|
|
assert i == 0
|
|
|
|
def test___len__(self):
|
|
cbas = [ia.LineString([(0, 0), (1, 1)]),
|
|
ia.LineString([(1, 2), (3, 4)])]
|
|
cbasoi = ia.LineStringsOnImage(cbas, shape=(40, 50, 3))
|
|
assert len(cbasoi) == 2
|
|
|
|
def test___repr__(self):
|
|
def _func(obj):
|
|
return obj.__repr__()
|
|
|
|
self._test_str_repr(_func)
|
|
|
|
def test___str__(self):
|
|
def _func(obj):
|
|
return obj.__str__()
|
|
|
|
self._test_str_repr(_func)
|
|
|
|
def test___repr___empty_list_of_line_strings(self):
|
|
def _func(obj):
|
|
return obj.__repr__()
|
|
|
|
self._test_str_repr_empty_list_of_line_strings(_func)
|
|
|
|
def test___str___empty_list_of_line_strings(self):
|
|
def _func(obj):
|
|
return obj.__str__()
|
|
|
|
self._test_str_repr_empty_list_of_line_strings(_func)
|
|
|
|
@classmethod
|
|
def _test_str_repr(cls, func):
|
|
ls1 = LineString([(0, 0), (1, 0), (2, 1)])
|
|
ls2 = LineString([(10, 10)])
|
|
lsoi = LineStringsOnImage([ls1, ls2], shape=(100, 100, 3))
|
|
|
|
observed = func(lsoi)
|
|
|
|
expected = "LineStringsOnImage([%s, %s], shape=(100, 100, 3))" % (
|
|
func(ls1), func(ls2)
|
|
)
|
|
assert observed == expected
|
|
|
|
@classmethod
|
|
def _test_str_repr_empty_list_of_line_strings(cls, func):
|
|
lsoi = LineStringsOnImage([], shape=(100, 100, 3))
|
|
|
|
observed = func(lsoi)
|
|
|
|
expected = "LineStringsOnImage([], shape=(100, 100, 3))"
|
|
assert observed == expected
|
|
|
|
|
|
def _coords_eq(ls, other):
|
|
return ls.coords_almost_equals(other, max_distance=1e-2)
|
|
|
|
|
|
def _drawing_allclose(arr, v):
|
|
# draw_points_heatmaps_array() and draw_line_heatmap_array() are
|
|
# currently limited to 1/255 accuracy due to drawing in uint8
|
|
return np.allclose(arr, v, atol=(1.01/255), rtol=0)
|