Skip to content

Commit

Permalink
Fix possession calculation!
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikonooooo committed Oct 28, 2023
1 parent 1d26a4a commit 4d94c93
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 17 deletions.
11 changes: 7 additions & 4 deletions src/processing/shot.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ def detect_shot(state: GameState, inte: Interval, window: int) -> ShotAttempt:
ball = state.frames[i].ball

sf = ShotFrame()
if ball.box.intersects(top):
sf.top = True
if rim.contains(ball.box):
sf.rim = True
if ball is None or rim is None:
pass
else:
if ball.box.intersects(top):
sf.top = True
if rim.contains(ball.box):
sf.rim = True
sfs.append(sf)

r = 0 # freq rim intersects in window
Expand Down
9 changes: 5 additions & 4 deletions src/processrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ def run_parse(self):
parse.parse_sort_output(self.state, self.ball_tracking)

def run_possession(self):
self.state.recompute_possesssions()
self.state.filter_players(threshold=100)
self.state.recompute_possession_list(threshold=20, join_threshold=20)
self.state.recompute_possession_list(threshold=10, join_threshold=20)
self.state.recompute_pass_from_possession()

def run_team_detect(self):
Expand Down Expand Up @@ -63,11 +64,11 @@ def run(self):
self.run_possession()
self.run_team_detect()
self.run_shot_detect()
print('G, T, S detect fine')
print("G, T, S detect fine")
self.run_courtline_detect()
print('courtline detect fine')
print("courtline detect fine")
self.run_video_render()
print('video render fine')
print("video render fine")

def get_results(self):
"""
Expand Down
39 changes: 30 additions & 9 deletions src/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,8 @@ def __init__(self, frameno: int) -> None:
"dictionary of form {ball_[id] : BallFrame}"
self.rim: Box = None # ASSUMPTION: SINGLE RIM
"bounding box of rim"
self.possesions: list[str] = []
"player in possession of ball"
self.possessions: list[str] = []
"player in possession of ball, area of intersection"

def add_player_frame(self, id: int, xmin: int, ymin: int, xmax: int, ymax: int):
"update players in frame given id and bounding boxes"
Expand Down Expand Up @@ -284,7 +284,7 @@ def calculate_possesions(self):
max_a = a
max_p = set()
max_p.add(p)
self.possesions = max_p
self.possessions = max_p

def check(self) -> bool:
"verifies if well-defined"
Expand Down Expand Up @@ -412,6 +412,25 @@ def recompute_frame_count(self):
self.players.update({pid: PlayerState()})
self.players.get(pid).frames += 1

def recompute_possesssions(self):
"naively compute frame-by-frame possession of ball"
for frame in self.frames:
if frame.ball is None:
frame.possessions = []
continue
lst: list[(str, int)] = []
ball: Box = frame.ball.box
for id, p in frame.players.items():
a: int = p.box.area_of_intersection(ball)
if a == 0:
continue
lst.append((id, a))

sorted_lst: list[(str, int)] = sorted(
lst, key=lambda x: x[1]
) # sorted from least to greatest intersect
frame.possessions = [x for (x, _) in sorted_lst]

def recompute_possession_list(self, threshold=20, join_threshold=20):
"""
Recompute posssession list with frame possession minimum [threshold].
Expand All @@ -426,7 +445,7 @@ def recompute_possession_list(self, threshold=20, join_threshold=20):
self.filter_poss(lst, join_threshold)
self.possessions = lst

def grow_poss(self, lst: list) -> None:
def grow_poss(self, lst: list[Interval]) -> None:
"""
modifies posssession list [lst] with more possession, if avaiable
Expand All @@ -436,7 +455,7 @@ def grow_poss(self, lst: list) -> None:
while fi < len(self.frames):
f: Frame = self.frames[fi]
frame = f.frameno
poss = f.possesions
poss = f.possessions

if i >= len(lst):
s = sys.maxsize # ensures new poss frame added
Expand All @@ -448,11 +467,13 @@ def grow_poss(self, lst: list) -> None:
fi += 1 # next frame
continue
else: # frame < start
p = poss.pop() # arbitrary player
lst.insert(i, (p, frame, frame))
p = poss.pop() # pop last player, most likely intersect
lst.insert(i, Interval(p, frame, frame))
i += 1 # next interval

def join_poss(self, lst: list, threshold: int = 20): # possiblility of mapreduce
def join_poss(
self, lst: list[Interval], threshold: int = 20
): # possiblility of mapreduce
"modifies posssession list to join same player intervals within threshold frames"
i = 0
while i < len(lst) - 1:
Expand All @@ -467,7 +488,7 @@ def join_poss(self, lst: list, threshold: int = 20): # possiblility of mapreduc
else:
i += 1 # next interval pair

def filter_poss(self, lst: list, threshold: int = 20):
def filter_poss(self, lst: list[Interval], threshold: int = 20):
"modifies posssession list to join same player intervals within threshold frames"
i = 0
while i < len(lst):
Expand Down

0 comments on commit 4d94c93

Please sign in to comment.