def __init__(self, frame, frame_num, timestamp, playback_time, frame_settings, prev_frame_analysis, controls): self.frame = frame self.frame_num = frame_num self.timestamp = timestamp self.playback_time = playback_time self.frame_settings = frame_settings self.controls = controls # Table tracker prev_table_tracker = prev_frame_analysis.table_tracker if prev_frame_analysis is not None else None self.table_tracker = TableTracker(prev_table_tracker, self.frame_settings.table_tracking_settings, controls.subpanel("table tracking"), ticker=self) # Table analysis self.prev_table_bg_estimation = prev_frame_analysis.table_bg_estimation if prev_frame_analysis is not None else None self.table_bg_estimation = None # Spot finder self.spots_finder = SpotsFinder(frame_settings.spots_finder_settings); # Computed data self.table_transform = None self.table_frame = None self.ball_density = None # Final data self.ball_pos = None # False if absent, (x, y) if present self.bars_pos = None # list of (lists of?) (shift, angle) # Timing data self.timings = {} # Record beginning of processing of this frame self.tic("lifetime")
class FrameAnalysis: def __init__(self, frame, frame_num, timestamp, playback_time, frame_settings, prev_frame_analysis, controls): self.frame = frame self.frame_num = frame_num self.timestamp = timestamp self.playback_time = playback_time self.frame_settings = frame_settings self.controls = controls # Table tracker prev_table_tracker = prev_frame_analysis.table_tracker if prev_frame_analysis is not None else None self.table_tracker = TableTracker(prev_table_tracker, self.frame_settings.table_tracking_settings, controls.subpanel("table tracking"), ticker=self) # Table analysis self.prev_table_bg_estimation = prev_frame_analysis.table_bg_estimation if prev_frame_analysis is not None else None self.table_bg_estimation = None # Spot finder self.spots_finder = SpotsFinder(frame_settings.spots_finder_settings); # Computed data self.table_transform = None self.table_frame = None self.ball_density = None # Final data self.ball_pos = None # False if absent, (x, y) if present self.bars_pos = None # list of (lists of?) (shift, angle) # Timing data self.timings = {} # Record beginning of processing of this frame self.tic("lifetime") def do_undistort_frame(self): if self.frame_settings.undistort_camera: self.tic("undistort frame") self.frame = cv2.undistort(self.frame, self.frame_settings.camera_matrix, self.frame_settings.dist_coeffs) self.controls.subpanel("table tracking").show("undistorted", self.frame / 255.0) self.toc("undistort frame") def do_table_tracking(self): self.tic("table tracking") self.table_corners = self.table_tracker.track_table(self.frame) self.toc("table tracking") self.tic("table warping") warping_proj = numpy.dot(rectangle_to_region(self.table_corners), pixels_to_rectangle(*self.frame_settings.table_frame_size)) # logger.info("\n%r\n%r", self.table_corners, warping_proj) self.table_frame = cv2.warpPerspective(self.frame, warping_proj, self.frame_settings.table_frame_size, flags=cv2.INTER_LINEAR | cv2.WARP_INVERSE_MAP, borderMode=cv2.BORDER_REPLICATE) / 255.0 self.toc("table warping") self.controls.subpanel("table tracking").show("table frame", self.table_frame) def do_compute_ball_density(self): self.tic("estimate background") self.table_bg_estimation = estimate_table_background(self.prev_table_bg_estimation, self.table_frame, self.frame_settings.table_bg_settings, self.controls.subpanel("tablebg")) self.toc("estimate background") self.tic("compute ball density") self.table_bg_analysis = analyze_table_background(self.table_bg_estimation, self.table_frame, self.controls.subpanel("tablebg")) # FIXME: the ball analysis is done in the analyze_table_background self.ball_density = self.table_bg_analysis.ballness self.toc("compute ball density") def find_spots(self): self.spots = self.spots_finder.find_spots(self.ball_density) def get_csv_line(self): line = "%.5f" % (self.playback_time) if self.ball_pos is not None: line += ",%.5f,%.5f" % (self.ball_pos[0], self.ball_pos[1]) else: line += ",," # FIXME: decide how bars are to be enumerated # for side in [0, 1]: # for bar in xrange(BARS): # line += ",%.5f,%.5f" % (self.bars_pos[side][bar][0], self.bars_pos[side][bar][1]) line += '\n' # Record finishing of processing of this frame self.toc("lifetime") return line def tic(self, name): assert name not in self.timings self.timings[name] = [monotonic_time(), None] def toc(self, name): assert name in self.timings assert self.timings[name][1] is None self.timings[name][1] = monotonic_time() timings_logger.debug("Frame %d, %s took %f msecs", self.frame_num, name, 1000.0 * (self.timings[name][1] - self.timings[name][0]))