Spaces:
Sleeping
Sleeping
Update utils.py
Browse files
utils.py
CHANGED
@@ -4,20 +4,20 @@ import cv2
|
|
4 |
import numpy as np
|
5 |
|
6 |
def analyze_frame_sequence(frames):
|
7 |
-
# Simulate realistic trajectory
|
8 |
h, w = frames[0].shape[:2]
|
9 |
-
trajectory_curve = [(200+i*10, 300 - i*8) for i in range(6)] #
|
|
|
10 |
return {
|
11 |
"pitch": "in line",
|
12 |
"impact": "in line",
|
13 |
-
"trajectory": "
|
14 |
"shot_offered": True,
|
15 |
"pitch_point": trajectory_curve[0],
|
16 |
"impact_point": trajectory_curve[2],
|
17 |
"trajectory_curve": trajectory_curve,
|
18 |
-
"stump_zone": [(
|
19 |
-
|
20 |
-
"hit_point": trajectory_curve[-1]
|
21 |
}
|
22 |
|
23 |
def make_decision(analysis):
|
@@ -35,27 +35,32 @@ def overlay_text(frame, text, pos, size=1.0, color=(255,255,255)):
|
|
35 |
cv2.putText(frame, text, pos, cv2.FONT_HERSHEY_SIMPLEX, size, color, 2, cv2.LINE_AA)
|
36 |
|
37 |
def overlay_annotations_dynamic(frame, analysis, t):
|
|
|
38 |
if t < len(analysis['trajectory_curve']):
|
39 |
ball_pos = analysis['trajectory_curve'][t]
|
40 |
-
cv2.circle(frame, ball_pos, 8, (0, 255, 0) if analysis['trajectory'] == 'hitting' else (0,
|
41 |
|
|
|
42 |
for i in range(1, min(t + 1, len(analysis['trajectory_curve']))):
|
43 |
-
|
44 |
-
|
|
|
|
|
45 |
|
|
|
46 |
x1, y1 = analysis['stump_zone'][0]
|
47 |
x2, y2 = analysis['stump_zone'][1]
|
48 |
overlay = frame.copy()
|
49 |
-
|
50 |
-
|
51 |
-
frame[:] = cv2.addWeighted(overlay,
|
52 |
cv2.rectangle(frame, (x1, y1), (x2, y2), (180, 180, 180), 2)
|
53 |
|
54 |
shot_icon = "✓" if analysis['shot_offered'] else "✗"
|
55 |
overlay_text(frame, f"Shot Offered: {shot_icon}", (30, 170), 0.8, (0,255,0) if analysis['shot_offered'] else (0,0,255))
|
56 |
overlay_text(frame, f"Trajectory: {analysis['trajectory'].capitalize()}", (30, 130), 0.8,
|
57 |
-
(0, 255, 0) if analysis['trajectory'] == 'hitting' else (0,
|
58 |
-
overlay_text(frame, "ICC LBW Review • Third-Umpire Analysis", (30,
|
59 |
|
60 |
def render_annotated_clip(frames, analysis, decision, reason, output_path):
|
61 |
h, w = frames[0].shape[:2]
|
@@ -68,7 +73,7 @@ def render_annotated_clip(frames, analysis, decision, reason, output_path):
|
|
68 |
for _ in range(20):
|
69 |
out.write(verdict_card)
|
70 |
|
71 |
-
# Dynamic replay with animated ball tracking
|
72 |
for t, f in enumerate(frames):
|
73 |
annotated = f.copy()
|
74 |
overlay_annotations_dynamic(annotated, analysis, t)
|
@@ -78,7 +83,7 @@ def render_annotated_clip(frames, analysis, decision, reason, output_path):
|
|
78 |
for pt in analysis['trajectory_curve'][-3:]:
|
79 |
for _ in range(2):
|
80 |
f = frames[-1].copy()
|
81 |
-
cv2.circle(f, pt, 10, (0,255,0) if analysis['trajectory']=="hitting" else (0,
|
82 |
cv2.rectangle(f, analysis['stump_zone'][0], analysis['stump_zone'][1], (180,180,180), 2)
|
83 |
overlay_text(f, "Trajectory End", (pt[0] + 10, pt[1] - 10), 0.8, (255,255,255))
|
84 |
overlay_text(f, "ICC LBW Review • Third-Umpire Analysis", (30, h - 30), 0.6, (180,180,180))
|
|
|
4 |
import numpy as np
|
5 |
|
6 |
def analyze_frame_sequence(frames):
|
7 |
+
# Simulate realistic trajectory with umpire's call zone
|
8 |
h, w = frames[0].shape[:2]
|
9 |
+
trajectory_curve = [(200 + i * 10, 300 - i * 8 + i ** 2 // 5) for i in range(6)] # parabolic downward curve
|
10 |
+
last = trajectory_curve[-1]
|
11 |
return {
|
12 |
"pitch": "in line",
|
13 |
"impact": "in line",
|
14 |
+
"trajectory": "umpires call", # simulate marginal zone
|
15 |
"shot_offered": True,
|
16 |
"pitch_point": trajectory_curve[0],
|
17 |
"impact_point": trajectory_curve[2],
|
18 |
"trajectory_curve": trajectory_curve,
|
19 |
+
"stump_zone": [(last[0] - 20, last[1] - 40), (last[0] + 20, last[1] + 40)],
|
20 |
+
"hit_point": last
|
|
|
21 |
}
|
22 |
|
23 |
def make_decision(analysis):
|
|
|
35 |
cv2.putText(frame, text, pos, cv2.FONT_HERSHEY_SIMPLEX, size, color, 2, cv2.LINE_AA)
|
36 |
|
37 |
def overlay_annotations_dynamic(frame, analysis, t):
|
38 |
+
h, w = frame.shape[:2]
|
39 |
if t < len(analysis['trajectory_curve']):
|
40 |
ball_pos = analysis['trajectory_curve'][t]
|
41 |
+
cv2.circle(frame, ball_pos, 8, (0, 255, 0) if analysis['trajectory'] == 'hitting' else (0, 140, 255), -1)
|
42 |
|
43 |
+
# Draw dashed arc
|
44 |
for i in range(1, min(t + 1, len(analysis['trajectory_curve']))):
|
45 |
+
p1 = analysis['trajectory_curve'][i - 1]
|
46 |
+
p2 = analysis['trajectory_curve'][i]
|
47 |
+
if i % 2 == 0:
|
48 |
+
cv2.line(frame, p1, p2, (0, 255, 0) if analysis['trajectory'] == 'hitting' else (0, 140, 255), 2)
|
49 |
|
50 |
+
# Umpire's Call Zone
|
51 |
x1, y1 = analysis['stump_zone'][0]
|
52 |
x2, y2 = analysis['stump_zone'][1]
|
53 |
overlay = frame.copy()
|
54 |
+
color = (0, 255, 0) if analysis['trajectory'] == 'hitting' else (0, 140, 255) # amber for umpire's call
|
55 |
+
cv2.rectangle(overlay, (x1, y1), (x2, y2), color, -1)
|
56 |
+
frame[:] = cv2.addWeighted(overlay, 0.25, frame, 0.75, 0)
|
57 |
cv2.rectangle(frame, (x1, y1), (x2, y2), (180, 180, 180), 2)
|
58 |
|
59 |
shot_icon = "✓" if analysis['shot_offered'] else "✗"
|
60 |
overlay_text(frame, f"Shot Offered: {shot_icon}", (30, 170), 0.8, (0,255,0) if analysis['shot_offered'] else (0,0,255))
|
61 |
overlay_text(frame, f"Trajectory: {analysis['trajectory'].capitalize()}", (30, 130), 0.8,
|
62 |
+
(0, 255, 0) if analysis['trajectory'] == 'hitting' else (0, 140, 255))
|
63 |
+
overlay_text(frame, "ICC LBW Review • Third-Umpire Analysis", (30, h - 30), 0.6, (180,180,180))
|
64 |
|
65 |
def render_annotated_clip(frames, analysis, decision, reason, output_path):
|
66 |
h, w = frames[0].shape[:2]
|
|
|
73 |
for _ in range(20):
|
74 |
out.write(verdict_card)
|
75 |
|
76 |
+
# Dynamic replay with animated ball tracking and umpire's call zone
|
77 |
for t, f in enumerate(frames):
|
78 |
annotated = f.copy()
|
79 |
overlay_annotations_dynamic(annotated, analysis, t)
|
|
|
83 |
for pt in analysis['trajectory_curve'][-3:]:
|
84 |
for _ in range(2):
|
85 |
f = frames[-1].copy()
|
86 |
+
cv2.circle(f, pt, 10, (0,255,0) if analysis['trajectory']=="hitting" else (0,140,255), -1)
|
87 |
cv2.rectangle(f, analysis['stump_zone'][0], analysis['stump_zone'][1], (180,180,180), 2)
|
88 |
overlay_text(f, "Trajectory End", (pt[0] + 10, pt[1] - 10), 0.8, (255,255,255))
|
89 |
overlay_text(f, "ICC LBW Review • Third-Umpire Analysis", (30, h - 30), 0.6, (180,180,180))
|