forked from tryolabs/soccer-video-analytics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
run_utils.py
172 lines (135 loc) · 3.99 KB
/
run_utils.py
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
from typing import List
import norfair
import numpy as np
from norfair import Detection
from norfair.camera_motion import MotionEstimator
from inference import Converter, YoloV5
from soccer import Ball, Match
def get_ball_detections(
ball_detector: YoloV5, frame: np.ndarray
) -> List[norfair.Detection]:
"""
Uses custom Yolov5 detector in order
to get the predictions of the ball and converts it to
Norfair.Detection list.
Parameters
----------
ball_detector : YoloV5
YoloV5 detector for balls
frame : np.ndarray
Frame to get the ball detections from
Returns
-------
List[norfair.Detection]
List of ball detections
"""
ball_df = ball_detector.predict(frame)
ball_df = ball_df[ball_df["confidence"] > 0.3]
return Converter.DataFrame_to_Detections(ball_df)
def get_player_detections(
person_detector: YoloV5, frame: np.ndarray
) -> List[norfair.Detection]:
"""
Uses YoloV5 Detector in order to detect the players
in a match and filter out the detections that are not players
and have confidence lower than 0.35.
Parameters
----------
person_detector : YoloV5
YoloV5 detector
frame : np.ndarray
_description_
Returns
-------
List[norfair.Detection]
List of player detections
"""
person_df = person_detector.predict(frame)
person_df = person_df[person_df["name"] == "person"]
person_df = person_df[person_df["confidence"] > 0.35]
person_detections = Converter.DataFrame_to_Detections(person_df)
return person_detections
def create_mask(frame: np.ndarray, detections: List[norfair.Detection]) -> np.ndarray:
"""
Creates mask in order to hide detections and goal counter for motion estimation
Parameters
----------
frame : np.ndarray
Frame to create mask for.
detections : List[norfair.Detection]
Detections to hide.
Returns
-------
np.ndarray
Mask.
"""
if not detections:
mask = np.ones(frame.shape[:2], dtype=frame.dtype)
else:
detections_df = Converter.Detections_to_DataFrame(detections)
mask = YoloV5.generate_predictions_mask(detections_df, frame, margin=40)
# remove goal counter
mask[69:200, 160:510] = 0
return mask
def apply_mask(img: np.ndarray, mask: np.ndarray) -> np.ndarray:
"""
Applies a mask to an img
Parameters
----------
img : np.ndarray
Image to apply the mask to
mask : np.ndarray
Mask to apply
Returns
-------
np.ndarray
img with mask applied
"""
masked_img = img.copy()
masked_img[mask == 0] = 0
return masked_img
def update_motion_estimator(
motion_estimator: MotionEstimator,
detections: List[Detection],
frame: np.ndarray,
) -> "CoordinatesTransformation":
"""
Update coordinate transformations every frame
Parameters
----------
motion_estimator : MotionEstimator
Norfair motion estimator class
detections : List[Detection]
List of detections to hide in the mask
frame : np.ndarray
Current frame
Returns
-------
CoordinatesTransformation
Coordinate transformation for the current frame
"""
mask = create_mask(frame=frame, detections=detections)
coord_transformations = motion_estimator.update(frame, mask=mask)
return coord_transformations
def get_main_ball(detections: List[Detection], match: Match = None) -> Ball:
"""
Gets the main ball from a list of balls detection
The match is used in order to set the color of the ball to
the color of the team in possession of the ball.
Parameters
----------
detections : List[Detection]
List of detections
match : Match, optional
Match object, by default None
Returns
-------
Ball
Main ball
"""
ball = Ball(detection=None)
if match:
ball.set_color(match)
if detections:
ball.detection = detections[0]
return ball