aboutsummaryrefslogtreecommitdiff
path: root/src/argaze/AreaOfInterest/AOI2DScene.py
blob: bcf9cfa4b02dd6db054ec9ca606d2a647dc95f74 (plain)
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)