1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#!/usr/bin/env python
""" """
__author__ = "Théo de la Hogue"
__credits__ = []
__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)"
__license__ = "BSD"
from typing import Tuple
from argaze import DataStructures
from argaze.AreaOfInterest import AOIFeatures
from argaze import GazeFeatures
import cv2 as cv
import numpy
class AOI2DScene(AOIFeatures.AOIScene):
"""Define AOI 2D scene."""
def __init__(self, aois_2d = None):
super().__init__(2, aois_2d)
def draw(self, frame, exclude=[], color=(0, 255, 255)):
"""Draw AOI polygons on frame."""
for name, aoi in self.items():
if name in exclude:
continue
aoi.draw(frame, color)
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
- matching status
"""
for name, aoi in self.items():
matching = aoi.contains_point(pointer)
yield name, aoi, matching
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, matching in self.raycast(pointer):
if name in exclude:
continue
color = matching_color if matching else base_color
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 form
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 matching circle.
* **Returns:**
- aoi name
- aoi object
- 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():
matching_region, aoi_ratio, circle_ratio = aoi.circle_intersection(center, radius)
yield name, aoi, matching_region, aoi_ratio, circle_ratio
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, matching_region, aoi_ratio, circle_ratio in self.circlecast(center, radius):
if name in exclude:
continue
# Draw matching region
if aoi_ratio > 0:
matching_region.draw(frame, base_color, 4)
# TODO : Externalise this criteria
matching = aoi_ratio > 0.25 or circle_ratio > 0.5
color = matching_color if matching else base_color
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 matching region
matching_region.draw(frame, matching_color, 4)
# Draw form
aoi.draw(frame, color)
|