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

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)