Spaces:
Sleeping
Sleeping
File size: 4,293 Bytes
297f570 0cb6105 297f570 153fc95 93146ee 153fc95 0cb6105 297f570 153fc95 6776f03 93146ee 153fc95 297f570 0cb6105 297f570 0cb6105 297f570 0cb6105 93146ee 153fc95 93146ee 153fc95 93146ee 153fc95 93146ee 153fc95 93146ee 153fc95 93146ee 153fc95 93146ee 6776f03 93146ee 153fc95 6776f03 0cb6105 93146ee 0cb6105 153fc95 90f98f4 0cb6105 93146ee 153fc95 93146ee 0cb6105 |
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 |
# utils.py
import cv2
import numpy as np
def analyze_frame_sequence(frames):
# Simulate realistic trajectory with umpire's call zone
h, w = frames[0].shape[:2]
trajectory_curve = [(200 + i * 10, 300 - i * 8 + i ** 2 // 5) for i in range(6)] # parabolic downward curve
last = trajectory_curve[-1]
return {
"pitch": "in line",
"impact": "in line",
"trajectory": "umpires call", # simulate marginal zone
"shot_offered": True,
"pitch_point": trajectory_curve[0],
"impact_point": trajectory_curve[2],
"trajectory_curve": trajectory_curve,
"stump_zone": [(last[0] - 20, last[1] - 40), (last[0] + 20, last[1] + 40)],
"hit_point": last
}
def make_decision(analysis):
if analysis['pitch'] == 'outside leg':
return "NOT OUT", "Pitched outside leg stump."
if analysis['impact'] == 'outside off' and analysis['shot_offered']:
return "NOT OUT", "Impact outside off with shot offered."
if analysis['trajectory'] == 'missing':
return "NOT OUT", "Ball missing stumps."
if analysis['trajectory'] == 'umpires call':
return "UMPIRE’S CALL", "Marginal trajectory impact."
return "OUT", "Impact in line and ball hitting stumps."
def overlay_text(frame, text, pos, size=1.0, color=(255,255,255)):
cv2.putText(frame, text, pos, cv2.FONT_HERSHEY_SIMPLEX, size, color, 2, cv2.LINE_AA)
def overlay_annotations_dynamic(frame, analysis, t):
h, w = frame.shape[:2]
if t < len(analysis['trajectory_curve']):
ball_pos = analysis['trajectory_curve'][t]
cv2.circle(frame, ball_pos, 8, (0, 255, 0) if analysis['trajectory'] == 'hitting' else (0, 140, 255), -1)
# Draw dashed arc
for i in range(1, min(t + 1, len(analysis['trajectory_curve']))):
p1 = analysis['trajectory_curve'][i - 1]
p2 = analysis['trajectory_curve'][i]
if i % 2 == 0:
cv2.line(frame, p1, p2, (0, 255, 0) if analysis['trajectory'] == 'hitting' else (0, 140, 255), 2)
# Umpire's Call Zone
x1, y1 = analysis['stump_zone'][0]
x2, y2 = analysis['stump_zone'][1]
overlay = frame.copy()
color = (0, 255, 0) if analysis['trajectory'] == 'hitting' else (0, 140, 255) # amber for umpire's call
cv2.rectangle(overlay, (x1, y1), (x2, y2), color, -1)
frame[:] = cv2.addWeighted(overlay, 0.25, frame, 0.75, 0)
cv2.rectangle(frame, (x1, y1), (x2, y2), (180, 180, 180), 2)
shot_icon = "✓" if analysis['shot_offered'] else "✗"
overlay_text(frame, f"Shot Offered: {shot_icon}", (30, 170), 0.8, (0,255,0) if analysis['shot_offered'] else (0,0,255))
overlay_text(frame, f"Trajectory: {analysis['trajectory'].capitalize()}", (30, 130), 0.8,
(0, 255, 0) if analysis['trajectory'] == 'hitting' else (0, 140, 255))
overlay_text(frame, "ICC LBW Review • Third-Umpire Analysis", (30, h - 30), 0.6, (180,180,180))
def render_annotated_clip(frames, analysis, decision, reason, output_path):
h, w = frames[0].shape[:2]
out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'), 20.0, (w, h))
# Verdict card (1s)
verdict_card = np.zeros_like(frames[0])
overlay_text(verdict_card, f"FINAL DECISION: {decision}", (50, 200), 2.0, (255,255,255))
overlay_text(verdict_card, reason, (50, 250), 0.9, (200,200,200))
for _ in range(20):
out.write(verdict_card)
# Dynamic replay with animated ball tracking and umpire's call zone
for t, f in enumerate(frames):
annotated = f.copy()
overlay_annotations_dynamic(annotated, analysis, t)
out.write(annotated)
# Slow-motion: emphasize final 3 points
for pt in analysis['trajectory_curve'][-3:]:
for _ in range(2):
f = frames[-1].copy()
cv2.circle(f, pt, 10, (0,255,0) if analysis['trajectory']=="hitting" else (0,140,255), -1)
cv2.rectangle(f, analysis['stump_zone'][0], analysis['stump_zone'][1], (180,180,180), 2)
overlay_text(f, "Trajectory End", (pt[0] + 10, pt[1] - 10), 0.8, (255,255,255))
overlay_text(f, "ICC LBW Review • Third-Umpire Analysis", (30, h - 30), 0.6, (180,180,180))
out.write(f)
for _ in range(10):
out.write(verdict_card)
out.release()
|