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)