Skip to content

Commit

Permalink
fix(goal-counting): Fix a false positive by defining goal grace perio…
Browse files Browse the repository at this point in the history
…d in seconds of runtime not seconds in rendering
  • Loading branch information
DarwinsBuddy committed Oct 4, 2024
1 parent a864829 commit ac419e8
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 10 deletions.
1 change: 1 addition & 0 deletions const.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
GPU = "gpu"
AUDIO = "audio"
WEBHOOK = "webhook"
SEEK = "seek"


class CalibrationMode:
Expand Down
7 changes: 4 additions & 3 deletions foosball/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from const import CALIBRATION_MODE, CALIBRATION_IMG_PATH, CALIBRATION_VIDEO, CALIBRATION_SAMPLE_SIZE, ARUCO_BOARD, \
FILE, CAMERA_ID, FRAMERATE, OUTPUT, CAPTURE, DISPLAY, BALL, XPAD, YPAD, SCALE, VERBOSE, HEADLESS, OFF, \
MAX_PIPE_SIZE, INFO_VERBOSITY, GPU, AUDIO, WEBHOOK, BUFFER, BallPresets, CalibrationMode, GOAL_GRACE_PERIOD
MAX_PIPE_SIZE, INFO_VERBOSITY, GPU, AUDIO, WEBHOOK, BUFFER, BallPresets, CalibrationMode, GOAL_GRACE_PERIOD, SEEK
from foosball.arUcos.calibration import print_aruco_board, calibrate_camera
from foosball.tracking.ai import AI

Expand Down Expand Up @@ -67,6 +67,7 @@ def get_argparse():
help="use GPU")
general.add_argument("-A", f"--{AUDIO}", action='store_true', help="Enable audio")
general.add_argument("-W", f"--{WEBHOOK}", action='store_true', help="Enable webhook")
general.add_argument("-S", f"--{SEEK}", type=int, default=None, help="Seek to frame number")

preprocess = ap.add_argument_group(title="Preprocessor", description="Options for the preprocessing step")
preprocess.add_argument("-xp", f"--{XPAD}", type=int, default=50,
Expand Down Expand Up @@ -122,10 +123,10 @@ def main(kwargs):
match kwargs.get(CAPTURE):
case 'gear':
from .source.gear import GearSource
cap = GearSource(source, framerate=kwargs.get(FRAMERATE), resolution=(1280, 720))
cap = GearSource(source, framerate=kwargs.get(FRAMERATE), resolution=(1280, 720), seek_to_frame=kwargs.get(SEEK))
case 'cv':
from .source.opencv import OpenCVSource
cap = OpenCVSource(source)
cap = OpenCVSource(source, seek_to_frame=kwargs.get(SEEK))
case _:
return usage_and_exit()
ai = AI(cap, dis, **kwargs)
Expand Down
8 changes: 6 additions & 2 deletions foosball/source/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@

class Source(Thread):

def __init__(self, maxsize=128, skip_frames=True, timeout=2, *args, **kwargs):
def __init__(self, maxsize=128, skip_frames=True, timeout=2, seek_to_frame: int | None = None, *args, **kwargs):
super().__init__(daemon=True, *args, **kwargs)
# initialize the file video stream along with the boolean
# used to indicate if the thread should be stopped or not
self.timeout = timeout
self.skip_frames = skip_frames
self.skipped_frames = 0
self.stopped = False
self.seek_to_frame = seek_to_frame

# initialize the queue used to store frames read from
# the video file
Expand Down Expand Up @@ -74,7 +75,10 @@ def run(self) -> None:
print("Could not grab")
self.stopped = True
frame = None
self.send_frame(frame)
if self.seek_to_frame is not None and self.seek_to_frame >= 0:
self.seek_to_frame -= 1
else:
self.send_frame(frame)
print("Release")
self.close_capture()

Expand Down
7 changes: 2 additions & 5 deletions foosball/tracking/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ def process(self, msg: Msg) -> Msg:
try:
self.check_reset_score()
now = dt.datetime.now()

# TODO: define goal grace period in seconds of runtime not seconds in rendering!
no_track_sighting_in_grace_period = (now - self.last_track_sighting).total_seconds() >= self.goal_grace_period_sec if self.last_track_sighting is not None else None

if not self.is_track_empty(track):
# track is not empty, so we save our state and remove a potential goal (which was wrongly tracked)
# case1: detected goals where not accurate => false positive
Expand All @@ -75,14 +74,12 @@ def process(self, msg: Msg) -> Msg:
else:
# let's wait for track (s.a.), or we run out of grace period (down below)
# whatever happens first
if self.goal_candidate is not None:
if self.last_track_sighting is not None and no_track_sighting_in_grace_period:
if self.goal_candidate is not None and self.last_track_sighting is not None and no_track_sighting_in_grace_period:
self.count_goal(self.goal_candidate)
self.goal_candidate = None
else:
# if track is empty, and we have no current goal candidate, check if there is one
self.goal_candidate = self.goal_shot(goals, track) if None not in [goals, track, self.last_track] else None

except Exception as e:
self.logger.error("Error in analyzer ", e)
traceback.print_exc()
Expand Down

0 comments on commit ac419e8

Please sign in to comment.