dschandra commited on
Commit
93146ee
·
verified ·
1 Parent(s): 6776f03

Update utils.py

Browse files
Files changed (1) hide show
  1. utils.py +47 -46
utils.py CHANGED
@@ -4,15 +4,20 @@ import cv2
4
  import numpy as np
5
 
6
  def analyze_frame_sequence(frames):
 
 
 
7
  return {
8
  "pitch": "in line",
9
  "impact": "in line",
10
  "trajectory": "hitting",
11
  "shot_offered": True,
12
- "pitch_point": (200, 300), # example pixel position
13
- "impact_point": (220, 320),
14
- "trajectory_curve": [(230, 330), (250, 310), (270, 290), (290, 270)],
15
- "stump_zone": [(300, 200), (340, 400)] # top-left and bottom-right of projected stumps
 
 
16
  }
17
 
18
  def make_decision(analysis):
@@ -29,65 +34,61 @@ def make_decision(analysis):
29
  def overlay_text(frame, text, pos, size=1.0, color=(255,255,255)):
30
  cv2.putText(frame, text, pos, cv2.FONT_HERSHEY_SIMPLEX, size, color, 2, cv2.LINE_AA)
31
 
32
- def overlay_annotations(frame, analysis):
33
- # pitch point
34
- if 'pitch_point' in analysis:
35
- cv2.circle(frame, analysis['pitch_point'], 10, (0, 255, 0) if analysis['pitch'] == 'in line' else (0, 0, 255), -1)
36
- overlay_text(frame, f"Pitch: {analysis['pitch'].capitalize()}", (analysis['pitch_point'][0]+10, analysis['pitch_point'][1]), 0.7)
37
-
38
- # impact point
39
- if 'impact_point' in analysis:
40
- cv2.circle(frame, analysis['impact_point'], 10, (0, 255, 0) if analysis['impact'] == 'in line' else (0, 0, 255), -1)
41
- overlay_text(frame, f"Impact: {analysis['impact'].capitalize()}", (analysis['impact_point'][0]+10, analysis['impact_point'][1]), 0.7)
42
-
43
- # shot icon
 
 
 
 
 
 
 
 
44
  shot_icon = "✓" if analysis['shot_offered'] else "✗"
45
  overlay_text(frame, f"Shot Offered: {shot_icon}", (30, 170), 0.8, (0,255,0) if analysis['shot_offered'] else (0,0,255))
46
 
47
- # trajectory arc
48
- if 'trajectory_curve' in analysis:
49
- for i in range(len(analysis['trajectory_curve'])-1):
50
- cv2.line(frame, analysis['trajectory_curve'][i], analysis['trajectory_curve'][i+1], (0,255,0) if analysis['trajectory']=="hitting" else (0,0,255), 2, cv2.LINE_AA)
51
-
52
- # transparent stump zone
53
- if 'stump_zone' in analysis:
54
- x1, y1 = analysis['stump_zone'][0]
55
- x2, y2 = analysis['stump_zone'][1]
56
- overlay = frame.copy()
57
- cv2.rectangle(overlay, (x1, y1), (x2, y2), (255, 255, 255), -1)
58
- alpha = 0.2
59
- frame[:] = cv2.addWeighted(overlay, alpha, frame, 1 - alpha, 0)
60
- cv2.rectangle(frame, (x1, y1), (x2, y2), (180, 180, 180), 2)
61
-
62
- overlay_text(frame, f"Trajectory: {analysis['trajectory'].capitalize()}", (30, 130), 0.8, (0,255,0) if analysis['trajectory']=="hitting" else (0,0,255))
63
  overlay_text(frame, "ICC LBW Review • Third-Umpire Analysis", (30, frame.shape[0] - 30), 0.6, (180,180,180))
64
 
65
-
66
  def render_annotated_clip(frames, analysis, decision, reason, output_path):
67
  h, w = frames[0].shape[:2]
68
  out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'), 20.0, (w, h))
69
 
70
- # First 1s: Verdict card
71
  verdict_card = np.zeros_like(frames[0])
72
  overlay_text(verdict_card, f"FINAL DECISION: {decision}", (50, 200), 2.0, (255,255,255))
73
  overlay_text(verdict_card, reason, (50, 250), 0.9, (200,200,200))
74
  for _ in range(20):
75
  out.write(verdict_card)
76
 
77
- # Real-time with annotations
78
- for frame in frames:
79
- annotated = frame.copy()
80
- overlay_annotations(annotated, analysis)
81
- out.write(annotated)
82
-
83
- # Slow-motion replay
84
- for i in range(0, len(frames), 2):
85
- annotated = frames[i].copy()
86
- overlay_annotations(annotated, analysis)
87
- out.write(annotated)
88
  out.write(annotated)
89
 
90
- # End frame 0.5s static
 
 
 
 
 
 
 
 
 
 
91
  for _ in range(10):
92
  out.write(verdict_card)
93
 
 
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)] # sloping downward
10
  return {
11
  "pitch": "in line",
12
  "impact": "in line",
13
  "trajectory": "hitting",
14
  "shot_offered": True,
15
+ "pitch_point": trajectory_curve[0],
16
+ "impact_point": trajectory_curve[2],
17
+ "trajectory_curve": trajectory_curve,
18
+ "stump_zone": [(trajectory_curve[-1][0] - 20, trajectory_curve[-1][1] - 40),
19
+ (trajectory_curve[-1][0] + 20, trajectory_curve[-1][1] + 40)],
20
+ "hit_point": trajectory_curve[-1]
21
  }
22
 
23
  def make_decision(analysis):
 
34
  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, 0, 255), -1)
41
+
42
+ # Draw complete arc
43
+ for i in range(1, min(t + 1, len(analysis['trajectory_curve']))):
44
+ cv2.line(frame, analysis['trajectory_curve'][i - 1], analysis['trajectory_curve'][i],
45
+ (0, 255, 0) if analysis['trajectory'] == 'hitting' else (0, 0, 255), 2)
46
+
47
+ # Highlight stumps zone
48
+ x1, y1 = analysis['stump_zone'][0]
49
+ x2, y2 = analysis['stump_zone'][1]
50
+ overlay = frame.copy()
51
+ cv2.rectangle(overlay, (x1, y1), (x2, y2), (255, 255, 255), -1)
52
+ alpha = 0.2
53
+ frame[:] = cv2.addWeighted(overlay, alpha, frame, 1 - alpha, 0)
54
+ cv2.rectangle(frame, (x1, y1), (x2, y2), (180, 180, 180), 2)
55
+
56
+ # Shot
57
  shot_icon = "✓" if analysis['shot_offered'] else "✗"
58
  overlay_text(frame, f"Shot Offered: {shot_icon}", (30, 170), 0.8, (0,255,0) if analysis['shot_offered'] else (0,0,255))
59
 
60
+ overlay_text(frame, f"Trajectory: {analysis['trajectory'].capitalize()}", (30, 130), 0.8,
61
+ (0, 255, 0) if analysis['trajectory'] == 'hitting' else (0, 0, 255))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  overlay_text(frame, "ICC LBW Review • Third-Umpire Analysis", (30, frame.shape[0] - 30), 0.6, (180,180,180))
63
 
 
64
  def render_annotated_clip(frames, analysis, decision, reason, output_path):
65
  h, w = frames[0].shape[:2]
66
  out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'mp4v'), 20.0, (w, h))
67
 
68
+ # Verdict card (1s)
69
  verdict_card = np.zeros_like(frames[0])
70
  overlay_text(verdict_card, f"FINAL DECISION: {decision}", (50, 200), 2.0, (255,255,255))
71
  overlay_text(verdict_card, reason, (50, 250), 0.9, (200,200,200))
72
  for _ in range(20):
73
  out.write(verdict_card)
74
 
75
+ # Dynamic replay
76
+ for t, f in enumerate(frames):
77
+ annotated = f.copy()
78
+ overlay_annotations_dynamic(annotated, analysis, t)
 
 
 
 
 
 
 
79
  out.write(annotated)
80
 
81
+ # Slow-motion: emphasize final 3 points
82
+ for pt in analysis['trajectory_curve'][-3:]:
83
+ for _ in range(2):
84
+ f = frames[-1].copy()
85
+ cv2.circle(f, pt, 10, (0,255,0) if analysis['trajectory']=="hitting" else (0,0,255), -1)
86
+ cv2.rectangle(f, analysis['stump_zone'][0], analysis['stump_zone'][1], (180,180,180), 2)
87
+ overlay_text(f, "Trajectory End", (pt[0] + 10, pt[1] - 10), 0.8, (255,255,255))
88
+ overlay_text(f, "ICC LBW Review • Third-Umpire Analysis", (30, h - 30), 0.6, (180,180,180))
89
+ out.write(f)
90
+
91
+ # End card (0.5s)
92
  for _ in range(10):
93
  out.write(verdict_card)
94