diff options
Diffstat (limited to 'src/argaze.test/AreaOfInterest/AOIFeatures.py')
-rw-r--r-- | src/argaze.test/AreaOfInterest/AOIFeatures.py | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/src/argaze.test/AreaOfInterest/AOIFeatures.py b/src/argaze.test/AreaOfInterest/AOIFeatures.py new file mode 100644 index 0000000..650411a --- /dev/null +++ b/src/argaze.test/AreaOfInterest/AOIFeatures.py @@ -0,0 +1,204 @@ +#!/usr/bin/env python + +import unittest +import math + +from argaze.AreaOfInterest import AOIFeatures + +import numpy + +class TestAreaOfInterestClass(unittest.TestCase): + """Test AreaOfInterest class.""" + + def test_new(self): + """Test AreaOfInterest creation.""" + + # Check that 0D AreaOfInterest creation fails + with self.assertRaises(TypeError): + + aoi_0D = AOIFeatures.AreaOfInterest() + + # Check 1 point 1D AreaOfInterest creation + aoi_1D = AOIFeatures.AreaOfInterest([[0]]) + + self.assertEqual(aoi_1D.dimension, 1) + self.assertEqual(aoi_1D.size, 1) + self.assertEqual(aoi_1D.center, [0]) + + with self.assertRaises(AssertionError): + self.assertEqual(aoi_1D.bounding_box, 1) + + # Check 2 points 1D AreaOfInterest creation + aoi_1D = AOIFeatures.AreaOfInterest([[0], [1]]) + + self.assertEqual(aoi_1D.dimension, 1) + self.assertEqual(aoi_1D.size, 2) + self.assertEqual(aoi_1D.center, [0.5]) + + with self.assertRaises(AssertionError): + self.assertEqual(aoi_1D.bounding_box, 1) + + # Check 4 points 2D AreaOfInterest creation + aoi_2D = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 0], [1, 1]]) + + self.assertEqual(aoi_2D.dimension, 2) + self.assertEqual(aoi_2D.size, 4) + self.assertIsNone(numpy.testing.assert_array_equal(aoi_2D.center, [0.5, 0.5])) + self.assertIsNone(numpy.testing.assert_array_equal(aoi_2D.bounding_box, [[0, 0], [1, 0], [1, 1], [0, 1]])) + + # Check 8 points 3D AreaOfInterest creation + aoi_3D = AOIFeatures.AreaOfInterest([[0, 0, 0], [0, 1, 0], [1, 0, 0], [1, 1, 0], [0, 0, 1], [0, 1, 1], [1, 0, 1], [1, 1, 1]]) + + self.assertEqual(aoi_3D.dimension, 3) + self.assertEqual(aoi_3D.size, 8) + + with self.assertRaises(AssertionError): + self.assertEqual(aoi_3D.bounding_box, 1) + + def test___repr__(self): + """Test AreaOfInterest string representation.""" + + aoi_2D_int = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 0], [1, 1]]) + + self.assertEqual(repr(aoi_2D_int), "[[0, 0], [0, 1], [1, 0], [1, 1]]") + + aoi_2D_float = AOIFeatures.AreaOfInterest([[0, 0], [0, math.pi], [math.pi, 0], [math.pi, math.pi]]) + + self.assertEqual(repr(aoi_2D_float), f'[[0.0, 0.0], [0.0, {repr(math.pi)}], [{repr(math.pi)}, 0.0], [{repr(math.pi)}, {repr(math.pi)}]]') + + def text_clockwise(self): + """Test AreaOfInterest clockwise method.""" + + aoi_2D_clockwise = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 0], [1, 1]]).clockwise() + + assertEqual(type(aoi_2D_clockwise), AOIFeatures.AreaOfInterest) + self.assertIsNone(numpy.testing.assert_array_equal(aoi_2D_clockwise, [0, 0], [0, 1], [1, 1], [1, 0])) + + def test_contains_point(self): + """Test AreaOfInterest contains_point method.""" + + aoi_2D = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) + + self.assertTrue(aoi_2D.contains_point((0.1, 0.9))) + self.assertFalse(aoi_2D.contains_point((1.1, 0.9))) + + def test_inner_axis(self): + + aoi_2D = AOIFeatures.AreaOfInterest([[0, 0], [0, 2], [2, 2], [2, 0]]) + + self.assertEqual(aoi_2D.inner_axis((1, 1)), (0.5, 0.5)) + + def test_outter_axis(self): + + aoi_2D = AOIFeatures.AreaOfInterest([[0, 0], [0, 2], [2, 2], [2, 0]]) + + self.assertEqual(aoi_2D.outter_axis((0.5, 0.5)), (1, 1)) + + def test_circle_intersection(self): + + aoi_2D = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) + intersection, aoi_ratio, circle_ratio = aoi_2D.circle_intersection((0, 0), 1) + + self.assertTrue(math.isclose(aoi_ratio, math.pi / 4, abs_tol=1e-2)) + self.assertTrue(math.isclose(circle_ratio, 1 / 4, abs_tol=1e-3)) + +class TestAOISceneClass(unittest.TestCase): + """Test AOIScene class.""" + + def test_new(self): + """Test AOIScene creation.""" + + # Check that 0D AOIScene creation fails + with self.assertRaises(AssertionError): + aoi_0D_scene = AOIFeatures.AOIScene(0) + + # Check empty 2D AOIScene creation + aoi_2d_scene = AOIFeatures.AOIScene(2) + + self.assertEqual(aoi_2d_scene.dimension, 2) + self.assertEqual(len(aoi_2d_scene.items()), 0) + + # Check 2D AOIScene creation + aoi_2D = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) + aoi_2d_scene = AOIFeatures.AOIScene(2, {"A": aoi_2D}) + + self.assertEqual(aoi_2d_scene.dimension, 2) + self.assertEqual(len(aoi_2d_scene.items()), 1) + self.assertEqual(list(aoi_2d_scene.keys()), ["A"]) + + def test___repr__(self): + """Test AOIScene string representation.""" + + # Check empty 2D AOIScene representation + self.assertEqual(repr(AOIFeatures.AOIScene(2)), "{}") + + # Check 2D AOIScene representation with integer AOI + aoi_2D_int = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) + aoi_2d_scene = AOIFeatures.AOIScene(2, {"A": aoi_2D_int}) + + self.assertEqual(repr(aoi_2d_scene), "{'A': [[0, 0], [0, 1], [1, 1], [1, 0]]}") + + # Check 2D AOIScene representation with float AOI + aoi_2D_float = AOIFeatures.AreaOfInterest([[0, 0], [0, math.pi], [math.pi, 0], [math.pi, math.pi]]) + aoi_2d_scene = AOIFeatures.AOIScene(2, {"A": aoi_2D_float}) + + expected_representation = "{'A': " + f'[[0.0, 0.0], [0.0, {repr(math.pi)}], [{repr(math.pi)}, 0.0], [{repr(math.pi)}, {repr(math.pi)}]]' + "}" + self.assertEqual(repr(aoi_2d_scene), expected_representation) + + def test_properties(self): + """Test AOIScene properties.""" + + aoi_2D_A = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) + aoi_2D_B = AOIFeatures.AreaOfInterest([[1, 1], [1, 2], [2, 2], [2, 1]]) + aoi_2d_scene = AOIFeatures.AOIScene(2, {"A": aoi_2D_A, "B": aoi_2D_B}) + + self.assertEqual(aoi_2d_scene.dimension, 2) + self.assertEqual(len(aoi_2d_scene.items()), 2) + self.assertEqual(list(aoi_2d_scene.keys()), ["A", "B"]) + self.assertIsNone(numpy.testing.assert_array_equal(aoi_2d_scene.bounds, [[0, 0], [2, 2]])) + self.assertIsNone(numpy.testing.assert_array_equal(aoi_2d_scene.center, [1, 1])) + self.assertIsNone(numpy.testing.assert_array_equal(aoi_2d_scene.size, [2, 2])) + + def test_copy(self): + """Test AOIScene copy method.""" + + aoi_2D_A = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) + aoi_2D_B = AOIFeatures.AreaOfInterest([[1, 1], [1, 2], [2, 2], [2, 1]]) + aoi_2d_scene = AOIFeatures.AOIScene(2, {"A": aoi_2D_A, "B": aoi_2D_B}) + + # Check full copy + aoi_2d_scene_copy = aoi_2d_scene.copy() + + self.assertEqual(aoi_2d_scene_copy.dimension, 2) + self.assertEqual(len(aoi_2d_scene_copy.items()), 2) + self.assertEqual(list(aoi_2d_scene_copy.keys()), ["A", "B"]) + + # Check cpy with exclusion + aoi_2d_scene_copy = aoi_2d_scene.copy(exclude=["B"]) + + self.assertEqual(aoi_2d_scene_copy.dimension, 2) + self.assertEqual(len(aoi_2d_scene_copy.items()), 1) + self.assertEqual(list(aoi_2d_scene_copy.keys()), ["A"]) + +class TestTimeStampedAOIScenesClass(unittest.TestCase): + """Test TimeStampedAOIScenes class.""" + + def test___setitem__(self): + """Test TimeStampedAOIScenes creation.""" + + aoi_2D_A = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) + aoi_2D_B = AOIFeatures.AreaOfInterest([[1, 1], [1, 2], [2, 2], [2, 1]]) + aoi_2d_scene = AOIFeatures.AOIScene(2, {"A": aoi_2D_A, "B": aoi_2D_B}) + + ts_aois_scenes = AOIFeatures.TimeStampedAOIScenes() + + ts_aois_scenes[0] = aoi_2d_scene + + # Check that only AOIScene can be added + with self.assertRaises(AssertionError): + + ts_aois_scenes[1] = "This string is not an AOIScene" + +if __name__ == '__main__': + + unittest.main()
\ No newline at end of file |