From 86a43e8af7d70302937e27da181198f3ddab5eed Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Tue, 9 May 2023 14:25:46 +0200 Subject: Changing raycast and circlecast interface. --- src/argaze.test/AreaOfInterest/AOI2DScene.py | 42 +++++++++++----------- src/argaze/AreaOfInterest/AOI2DScene.py | 52 ++++++++++++++-------------- 2 files changed, 47 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/argaze.test/AreaOfInterest/AOI2DScene.py b/src/argaze.test/AreaOfInterest/AOI2DScene.py index ecd6bbb..a73aa20 100644 --- a/src/argaze.test/AreaOfInterest/AOI2DScene.py +++ b/src/argaze.test/AreaOfInterest/AOI2DScene.py @@ -39,43 +39,43 @@ class TestAOI2DSceneClass(unittest.TestCase): gaze_position_C = GazeFeatures.GazePosition((0.5, 1.5)) # Check raycast results for gaze postion A - for name, aoi, looked in aoi_2d_scene.raycast(gaze_position_A): + for name, aoi, matching in aoi_2d_scene.raycast(gaze_position_A.value): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) - self.assertEqual(looked, True) + self.assertEqual(matching, True) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) - self.assertEqual(looked, False) + self.assertEqual(matching, False) # Check raycast results for gaze postion B - for name, aoi, looked in aoi_2d_scene.raycast(gaze_position_B): + for name, aoi, matching in aoi_2d_scene.raycast(gaze_position_B.value): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) - self.assertEqual(looked, False) + self.assertEqual(matching, False) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) - self.assertEqual(looked, True) + self.assertEqual(matching, True) # Check raycast results for gaze postion C - for name, aoi, looked in aoi_2d_scene.raycast(gaze_position_C): + for name, aoi, matching in aoi_2d_scene.raycast(gaze_position_C.value): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) - self.assertEqual(looked, False) + self.assertEqual(matching, False) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) - self.assertEqual(looked, False) + self.assertEqual(matching, False) def test_circlecast(self): """Test AOI2DScene circlecast method.""" @@ -90,64 +90,64 @@ class TestAOI2DSceneClass(unittest.TestCase): gaze_position_D = GazeFeatures.GazePosition((0.5, 1.5), precision=0.25) # Check circlecast results for gaze postion A - for name, aoi, looked_region, aoi_ratio, gaze_ratio in aoi_2d_scene.circlecast(gaze_position_A): + for name, aoi, matching_region, aoi_ratio, circle_ratio in aoi_2d_scene.circlecast(gaze_position_A.value, gaze_position_A.precision): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertTrue(math.isclose(aoi_ratio, math.pi / 4, abs_tol=1e-2)) - self.assertTrue(math.isclose(gaze_ratio, 1., abs_tol=1e-3)) + self.assertTrue(math.isclose(circle_ratio, 1., abs_tol=1e-3)) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertEqual(aoi_ratio, 0.) - self.assertEqual(gaze_ratio, 0.) + self.assertEqual(circle_ratio, 0.) # Check circlecast results for gaze postion B - for name, aoi, looked_region, aoi_ratio, gaze_ratio in aoi_2d_scene.circlecast(gaze_position_B): + for name, aoi, matching_region, aoi_ratio, circle_ratio in aoi_2d_scene.circlecast(gaze_position_B.value, gaze_position_B.precision): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertEqual(aoi_ratio, 0.) - self.assertEqual(gaze_ratio, 0.) + self.assertEqual(circle_ratio, 0.) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertTrue(math.isclose(aoi_ratio, math.pi / 4, abs_tol=1e-2)) - self.assertTrue(math.isclose(gaze_ratio, 1., abs_tol=1e-3)) + self.assertTrue(math.isclose(circle_ratio, 1., abs_tol=1e-3)) # Check circlecast results for gaze postion C - for name, aoi, looked_region, aoi_ratio, gaze_ratio in aoi_2d_scene.circlecast(gaze_position_C): + for name, aoi, matching_region, aoi_ratio, circle_ratio in aoi_2d_scene.circlecast(gaze_position_C.value, gaze_position_C.precision): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertTrue(math.isclose(aoi_ratio, math.pi / 4, abs_tol=1e-2)) - self.assertTrue(math.isclose(gaze_ratio, 1 / 4, abs_tol=1e-3)) + self.assertTrue(math.isclose(circle_ratio, 1 / 4, abs_tol=1e-3)) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertTrue(math.isclose(aoi_ratio, math.pi / 4, abs_tol=1e-2)) - self.assertTrue(math.isclose(gaze_ratio, 1 / 4, abs_tol=1e-3)) + self.assertTrue(math.isclose(circle_ratio, 1 / 4, abs_tol=1e-3)) # Check circlecast results for gaze postion D - for name, aoi, looked_region, aoi_ratio, gaze_ratio in aoi_2d_scene.circlecast(gaze_position_D): + for name, aoi, matching_region, aoi_ratio, circle_ratio in aoi_2d_scene.circlecast(gaze_position_D.value, gaze_position_D.precision): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertEqual(aoi_ratio, 0.) - self.assertEqual(gaze_ratio, 0.) + self.assertEqual(circle_ratio, 0.) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertEqual(aoi_ratio, 0.) - self.assertEqual(gaze_ratio, 0.) + self.assertEqual(circle_ratio, 0.) def test_copy(self): """Test AOI2DScene copy method.""" diff --git a/src/argaze/AreaOfInterest/AOI2DScene.py b/src/argaze/AreaOfInterest/AOI2DScene.py index 6930613..0799dc5 100644 --- a/src/argaze/AreaOfInterest/AOI2DScene.py +++ b/src/argaze/AreaOfInterest/AOI2DScene.py @@ -26,31 +26,31 @@ class AOI2DScene(AOIFeatures.AOIScene): aoi.draw(frame, color) - def raycast(self, gaze_position: GazeFeatures.GazePosition) -> Tuple[str, "AOIFeatures.AreaOfInterest", bool]: - """Iterate over aoi to know which aoi is looked considering only gaze position value. + def raycast(self, pointer:tuple) -> Tuple[str, "AOIFeatures.AreaOfInterest", bool]: + """Iterate over aoi to know which aoi is matching the given pointer position. * **Returns:** - aoi name - aoi object - - looked status + - matching status """ for name, aoi in self.items(): - looked = aoi.contains_point(gaze_position.value) + matching = aoi.contains_point(pointer) - yield name, aoi, looked + yield name, aoi, matching - def draw_raycast(self, frame, gaze_position: GazeFeatures.GazePosition, exclude=[], base_color=(0, 0, 255), looked_color=(0, 255, 0)): - """Draw AOIs with their looked status.""" + def draw_raycast(self, frame, pointer:tuple, exclude=[], base_color=(0, 0, 255), matching_color=(0, 255, 0)): + """Draw AOIs with their matching status.""" - for name, aoi, looked in self.raycast(gaze_position): + for name, aoi, matching in self.raycast(pointer): if name in exclude: continue - color = looked_color if looked else base_color + color = matching_color if matching else base_color - if looked: + if matching: top_left_corner_pixel = numpy.rint(aoi.clockwise()[0]).astype(int) cv.putText(frame, name, top_left_corner_pixel, cv.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv.LINE_AA) @@ -59,45 +59,45 @@ class AOI2DScene(AOIFeatures.AOIScene): aoi.draw(frame, color) def circlecast(self, center:tuple, radius:float) -> Tuple[str, "AOIFeatures.AreaOfInterest", numpy.array, float, float]: - """Iterate over areas to know which aoi is looked considering gaze position value and its precision. + """Iterate over areas to know which aoi is matching circle. * **Returns:** - aoi name - aoi object - - looked region points - - ratio of looked region area relatively to aoi area - - ratio of looked region area relatively to gaze position circle precision + - matching region points + - ratio of matching region area relatively to aoi area + - ratio of matching region area relatively to circle area """ for name, aoi in self.items(): - looked_region, aoi_ratio, gaze_ratio = aoi.circle_intersection(center, radius) + matching_region, aoi_ratio, circle_ratio = aoi.circle_intersection(center, radius) - yield name, aoi, looked_region, aoi_ratio, gaze_ratio + yield name, aoi, matching_region, aoi_ratio, circle_ratio - def draw_circlecast(self, frame, center:tuple, radius:float, exclude=[], base_color=(0, 0, 255), looked_color=(0, 255, 0)): - """Draw AOIs with their looked status and looked region.""" + def draw_circlecast(self, frame, center:tuple, radius:float, exclude=[], base_color=(0, 0, 255), matching_color=(0, 255, 0)): + """Draw AOIs with their matching status and matching region.""" - for name, aoi, looked_region, aoi_ratio, gaze_ratio in self.circlecast(center, radius): + for name, aoi, matching_region, aoi_ratio, circle_ratio in self.circlecast(center, radius): if name in exclude: continue - # Draw looked region + # Draw matching region if aoi_ratio > 0: - looked_region.draw(frame, base_color, 4) + matching_region.draw(frame, base_color, 4) # TODO : Externalise this criteria - looked = aoi_ratio > 0.25 or gaze_ratio > 0.5 + matching = aoi_ratio > 0.25 or circle_ratio > 0.5 - color = looked_color if looked else base_color + color = matching_color if matching else base_color - if looked: + if matching: top_left_corner_pixel = numpy.rint(aoi.clockwise()[0]).astype(int) cv.putText(frame, name, top_left_corner_pixel, cv.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv.LINE_AA) - # Draw looked region - looked_region.draw(frame, looked_color, 4) + # Draw matching region + matching_region.draw(frame, matching_color, 4) # Draw form aoi.draw(frame, color) -- cgit v1.1