diff options
-rw-r--r-- | setup.py | 2 | ||||
-rw-r--r-- | src/argaze/AreaOfInterest/AOIFeatures.py | 42 |
2 files changed, 34 insertions, 10 deletions
@@ -35,7 +35,7 @@ setup( packages=find_packages(where='src'), python_requires='>=3.6, <4', - install_requires=['opencv-python==4.6.0.66', 'opencv-contrib-python==4.6.0.66', 'numpy', 'av', 'rtsp', 'pandas', 'matplotlib'], + install_requires=['opencv-python==4.6.0.66', 'opencv-contrib-python==4.6.0.66', 'numpy', 'av', 'rtsp', 'pandas', 'matplotlib', 'shapely'], project_urls={ 'Bug Reports': 'https://git.recherche.enac.fr/projects/argaze/issues', diff --git a/src/argaze/AreaOfInterest/AOIFeatures.py b/src/argaze/AreaOfInterest/AOIFeatures.py index 8e4965c..987a25f 100644 --- a/src/argaze/AreaOfInterest/AOIFeatures.py +++ b/src/argaze/AreaOfInterest/AOIFeatures.py @@ -7,6 +7,8 @@ from argaze import DataStructures, GazeFeatures import cv2 as cv import matplotlib.path as mpath import numpy +from shapely.geometry import Polygon +from shapely.geometry.point import Point @dataclass class AreaOfInterest(numpy.ndarray): @@ -88,17 +90,39 @@ class AreaOfInterest(numpy.ndarray): return numpy.rint(Lp).astype(int).tolist() - def draw(self, frame, color): + def looked_region(self, gaze_position, gaze_radius): + """Get intersection shape with gaze circle as the looked area, (looked area / AOI area) and (looked area / gaze circle area).""" - # Draw form - pixels = numpy.rint(self).astype(int) - cv.line(frame, pixels[-1], pixels[0], color, 1) - for A, B in zip(pixels, pixels[1:]): - cv.line(frame, A, B, color, 1) + self_polygon = Polygon(self) + gaze_circle = Point(gaze_position).buffer(gaze_radius) - # Draw center - center_pixel = numpy.rint(self.center()).astype(int) - cv.circle(frame, center_pixel, 1, color, -1) + if self_polygon.intersects(gaze_circle): + + intersection = self_polygon.intersection(gaze_circle) + + intersection_array = numpy.array([list(xy) for xy in intersection.exterior.coords[:]]).astype(numpy.float32).view(AreaOfInterest) + + return intersection_array, intersection.area / self_polygon.area, intersection.area / gaze_circle.area + + else: + + empty_array = numpy.array([list([])]).astype(numpy.float32).view(AreaOfInterest) + + return empty_array, 0., 0. + + def draw(self, frame, color, border_size=1): + + if len(self) > 1: + + # Draw form + pixels = numpy.rint(self).astype(int) + cv.line(frame, pixels[-1], pixels[0], color, border_size) + for A, B in zip(pixels, pixels[1:]): + cv.line(frame, A, B, color, border_size) + + # Draw center + center_pixel = numpy.rint(self.center()).astype(int) + cv.circle(frame, center_pixel, 1, color, -1) @dataclass class AOIScene(): |