Coverage for skcvideo/minimap.py: 0%
43 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-02 14:10 +0200
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-02 14:10 +0200
1import cv2
2import numpy as np
4from skcvideo.colors import WHITE
5from skcvideo.field_model import create_field_objects
6from skcvideo.utils import put_text
8FIELD_COLOR = (65, 165, 113)
11class Minimap:
12 def __init__(self, box=None, pitch_length=105.0, pitch_width=68.0):
13 if box is None:
14 box = [200, 57, 740, 57 + 796]
15 self.box = box
16 self.pitch_length = pitch_length
17 self.pitch_width = pitch_width
19 self.xc, self.yc = (self.box[1] + self.box[3]) / 2.0, (self.box[0] + self.box[2]) / 2.0
20 self.w, self.h = self.box[3] - self.box[1], self.box[2] - self.box[0]
21 self.pixel_per_meter = 5.0 * min(float(self.h) / 390.0, float(self.w) / 575.0)
23 def build(self, image):
24 image[self.box[0] : self.box[2], self.box[1] : self.box[3], :] = np.array(FIELD_COLOR, dtype=np.uint8)[
25 np.newaxis, np.newaxis, :
26 ]
28 field_objects = create_field_objects(
29 pitch_length=self.pitch_length,
30 pitch_width=self.pitch_width,
31 )
33 for _name, field_object in field_objects.items():
34 if field_object["type"] == "line":
35 start_x, start_y = self.switch_coords_meter_to_minimap(*field_object["start_point"])
36 end_x, end_y = self.switch_coords_meter_to_minimap(*field_object["end_point"])
37 cv2.line(
38 img=image,
39 pt1=(start_x, start_y),
40 pt2=(end_x, end_y),
41 color=WHITE,
42 thickness=2,
43 )
44 elif field_object["type"] == "circle":
45 x, y = self.switch_coords_meter_to_minimap(
46 field_object["x"],
47 field_object["y"],
48 )
49 radius = int(np.round(self.pixel_per_meter * field_object["radius"]))
50 startAngle = int(np.round(180.0 * field_object["startAngle"] / np.pi))
51 endAngle = int(np.round(180.0 * field_object["endAngle"] / np.pi))
53 cv2.ellipse(
54 img=image,
55 center=(x, y),
56 axes=(radius, radius),
57 angle=0,
58 startAngle=startAngle,
59 endAngle=endAngle,
60 color=WHITE,
61 thickness=2,
62 )
64 def switch_coords_meter_to_minimap(self, x, y):
65 x_to_disp = np.round(x * self.pixel_per_meter + self.xc)
66 y_to_disp = np.round(-y * self.pixel_per_meter + self.yc)
67 x_to_disp, y_to_disp = map(int, [x_to_disp, y_to_disp])
68 return x_to_disp, y_to_disp
70 def refresh(self, image, data, info_mapping=lambda d: d):
71 """
72 info_mapping: a function taking d and returning a dict containing:
73 {
74 'x': float,
75 'y': float,
76 'radius': int,
77 'color': (int, int, int),
78 'second_color': (int, int, int),
79 'text': str or None,
80 'text_color': (int, int, int) or None,
81 }
82 """
83 for d in data:
84 info = info_mapping(d)
85 x, y = self.switch_coords_meter_to_minimap(info["x"], info["y"])
86 cv2.circle(image, (x, y), info["radius"], info["color"], thickness=-1)
87 cv2.circle(image, (x, y), info["radius"], info["second_color"], thickness=1)
88 if info["text"] is not None:
89 put_text(
90 img=image,
91 text=info["text"],
92 org=(x, y),
93 fontScale=0.4,
94 color=info["text_color"],
95 align_x="center",
96 align_y="center",
97 )