Coverage for skcvideo/minimap.py: 0%

43 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-10-02 14:10 +0200

1import cv2 

2import numpy as np 

3 

4from skcvideo.colors import WHITE 

5from skcvideo.field_model import create_field_objects 

6from skcvideo.utils import put_text 

7 

8FIELD_COLOR = (65, 165, 113) 

9 

10 

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 

18 

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) 

22 

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 ] 

27 

28 field_objects = create_field_objects( 

29 pitch_length=self.pitch_length, 

30 pitch_width=self.pitch_width, 

31 ) 

32 

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)) 

52 

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 ) 

63 

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 

69 

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 )