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
|
#!/usr/bin/env python
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, gaze_position: GazeFeatures.GazePosition) -> Tuple[str, "AOIFeatures.AreaOfInterest", bool]:
"""Iterate over aoi to know which aoi is looked considering only gaze position value.
* **Returns:**
- aoi name
- aoi object
- looked status
"""
for name, aoi in self.items():
looked = aoi.contains_point(gaze_position.value)
yield name, aoi, looked
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."""
for name, aoi, looked in self.raycast(gaze_position):
if name in exclude:
continue
color = looked_color if looked else base_color
if looked:
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, gaze_position: GazeFeatures.GazePosition) -> Tuple[str, "AOIFeatures.AreaOfInterest", numpy.array, float, float]:
"""Iterate over areas to know which aoi is looked considering gaze position value and its accuracy.
* **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 accuracy
"""
for name, aoi in self.items():
looked_region, aoi_ratio, gaze_ratio = aoi.circle_intersection(gaze_position.value, gaze_position.accuracy)
yield name, aoi, looked_region, aoi_ratio, gaze_ratio
def draw_circlecast(self, frame, gaze_position: GazeFeatures.GazePosition, exclude=[], base_color=(0, 0, 255), looked_color=(0, 255, 0)):
"""Draw AOIs with their looked status and looked region."""
for name, aoi, looked_region, aoi_ratio, gaze_ratio in self.circlecast(gaze_position):
if name in exclude:
continue
# Draw looked region
if aoi_ratio > 0:
looked_region.draw(frame, base_color, 4)
# TODO : Externalise this criteria
looked = aoi_ratio > 0.25 or gaze_ratio > 0.5
color = looked_color if looked else base_color
if looked:
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 form
aoi.draw(frame, color)
|