def main(): from overtrack_cv.util.logging_config import config_logger from overtrack_cv.util.test_processor import test_processor config_logger(os.path.basename(__file__), level=logging.DEBUG, write_to_file=False) proc = TopHudProcessor() agent_paths = [ os.path.join( "C:/Users/simon/overtrack_2/valorant_images/top_hud_agents", agent_name.lower() + ".png", ) for agent_name in agents ] agent_frames = [ agent_path for agent_path in agent_paths if os.path.exists(agent_path) ] # util.test_processor(agent_frames, proc, 'valorant.top_hud', test_all=False, wait=True) # util.test_processor([ # r'C:/Users/simon/overtrack_2/valorant_images/ingame\00-41-617.image.png' # ], TopHudProcessor(), 'valorant.top_hud', test_all=False, wait=True) # test_processor(proc, "valorant.top_hud", test_all=False, wait=True)
def main(): from overtrack_cv.util.logging_config import config_logger from overtrack_cv.util.test_processor import test_processor config_logger(os.path.basename(__file__), level=logging.DEBUG, write_to_file=False) test_processor(HomeScreenProcessor(), "valorant.home_screen")
def main(): from overtrack_cv.util.logging_config import config_logger from overtrack_cv.util.test_processor import test_processor config_logger(os.path.basename(__file__), level=logging.DEBUG, write_to_file=False) test_processor(AgentSelectProcessor(), "valorant.agent_select", test_all=False)
def main(): from overtrack_cv.util.logging_config import config_logger from overtrack_cv.util.test_processor import test_processor config_logger(os.path.basename(__file__), level=logging.DEBUG, write_to_file=False) proc = KillfeedProcessor() test_processor(proc, "valorant.killfeed", wait=True, test_all=False) test_processor(proc, "valorant.killfeed", wait=True, test_all=False)
def main() -> None: from overtrack_cv.util.test_processor import test_processor test_processor( YourSquadProcessor(), "your_squad", "your_selection", "champion_squad", "squad_match", "duos_match", game="apex", )
def main(): from overtrack_cv.util.test_processor import test_processor proc = CoordinateProcessor() test_processor(proc, "coordinates", test_all=False, warmup=False) paths = sorted([ f for f in glob("S:/Downloads/apexframesdump/*.png") if float(os.path.basename(f).split("_")[0]) > 1612499100 ]) test_processor(proc, "coordinates", images=paths)
def main(): from overtrack_cv.util.logging_config import config_logger from overtrack_cv.util.test_processor import test_processor config_logger(os.path.basename(__file__), level=logging.DEBUG, write_to_file=False) p = PostgameProcessor() test_processor(p, "valorant.postgame", "valorant.scoreboard", test_all=False) test_processor(p, "valorant.postgame", "valorant.scoreboard", test_all=False)
def main() -> None: import glob from overtrack_cv.util.test_processor import test_processor test_processor( # [p for p in glob.glob("D:/overtrack/frames7/*.png") if "debug" not in p][40:], create_pipeline(interleave_processors=True), "frame", "minimap", "location", "match_status", "minimap", "apex_play_menu", "your_squad", "champion_squad", "match_summary", "squad_summary", "combat", "squad", game="apex", images=glob.glob("S:/Downloads/apexframesdump/*.png") # images=glob.glob('./processors/**/samples/*.png') )
cv2.imshow("template", t) import matplotlib.pyplot as plt plt.figure() plt.plot(x, y) plt.figure() plt.imshow(hero_image) s = x[np.argmin(y)] print(s) t = _make_template(bgcol, hero, s) plt.figure() plt.imshow(cv2.matchTemplate(t, hero_image, cv2.TM_SQDIFF_NORMED)) plt.show() if __name__ == "__main__": # find_scale('sigma') from overtrack_cv.util.test_processor import test_processor test_processor( SpectatorProcessor( bgcols=((255, 255, 255), (130, 70, 90)), top=SpectatorProcessor.OWL_TOP, ), "spectator_bar", )
def main() -> None: from overtrack_cv.util.test_processor import test_processor test_processor(MenuProcessor(), "match_status")
kills_text = kills_text.replace(s1, s2) try: kills = int(kills_text) if 0 < kills <= 50: return kills else: logger.warning(f"Rejecting kills={kills}") return None except ValueError: logger.warning(f"Cannot parse kills={kills_text!r} as int") return None else: return None def _parse_badge( self, badge_image: np.ndarray, badges: List[Tuple[str, np.ndarray, np.ndarray]]) -> Tuple[float, ...]: matches = [] for rank, template, mask in badges: match = np.min( matchTemplate(badge_image, template, cv2.TM_SQDIFF, mask=mask)) matches.append(round(match, 1)) return tuple(matches) if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(MatchStatusProcessor(), "match_status")
def main(): from overtrack_cv.util.logging_config import config_logger from overtrack_cv.util.test_processor import test_processor config_logger(os.path.basename(__file__), level=logging.DEBUG, write_to_file=False) test_processor(TimerProcessor(), "timer", wait=True)
np.array(self.PLACED_COLOUR) + 40, ) text = imageops.tesser_ocr(orange, whitelist=string.digits + "#") if text and text[0] == "#": try: placed = int(text[1:]) except ValueError: logger.warning(f"Could not parse {text!r} as number") return None else: logger.debug(f"Parsed {text!r} as {placed}") if 1 <= placed <= 30: return placed else: logger.warning(f"Rejected placed={placed}") else: logger.warning(f'Rejected placed text {text!r} - did not get "#"') return None if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor( "match_summary", MatchSummaryProcessor(), "match_summary", "match_summary_match", game="apex", )
) return state def _parse_ult_status(self, frame: Frame) -> Optional[int]: ult_image = self.REGIONS["ult"].extract_one(frame.image) thresh = imageops.unsharp_mask(ult_image, unsharp=2, weight=4, threshold=240) ult_circle = cv2.resize(thresh, (0, 0), fx=0.5, fy=0.5) contours, _ = imageops.findContours(ult_circle, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) contour_match = 1.0 for cnt in contours: if 1500 < cv2.contourArea(cnt) < 2500: contour_match = min(contour_match, cv2.matchShapes(cnt, self.ULT_CONTOUR_TEMPLATE, 1, 0)) if contour_match < 0.01: logger.debug(f"Got ult contour match {contour_match:1.5f} - ult=100%") return 100 else: ult = big_noodle.ocr_int(thresh, channel=None, threshold=None, height=33) logger.debug(f"Parsed ult as {ult}%") if ult is not None and 0 <= ult <= 99: return ult else: return None if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(HeroProcessor(), "hero")
logger.debug(f"Parsed map as {map_text}") return result, map_text LEAVE_GAME_TEMPLATE = imageops.imread( os.path.join(os.path.dirname(__file__), "data", "leave_game_template.png"), 0) LEAVE_GAME_TEMPLATE_THRESH = 0.6 def detect_endgame(self, frame: Frame) -> bool: leave_game_button = self.REGIONS["leave_game_button"].extract_one( frame.image) # leave_game_button = cv2.resize(leave_game_button, (0, 0), fx=0.5, fy=0.5) gray = np.min(leave_game_button, axis=2) _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) frame.overwatch.endgame_match = round( 1 - float( np.min( cv2.matchTemplate(thresh, self.LEAVE_GAME_TEMPLATE, cv2.TM_SQDIFF_NORMED))), 5) return frame.overwatch.endgame_match > self.LEAVE_GAME_TEMPLATE_THRESH if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(EndgameProcessor(), "endgame")
mode=mode_text, blue_names=names, is_in_queue=self.detect_in_queue(frame), ) return True return False TIME_ELAPSED_TEMPLATE = imageops.imread( os.path.join(os.path.dirname(__file__), "data", "time_elapsed.png"), 0) TIME_ELAPSED_MATCH_THRESHOLD = 0.75 def detect_in_queue(self, frame: Frame) -> bool: region = self.REGIONS["time_elapsed"].extract_one(frame.image_yuv[:, :, 0]) _, thresh = cv2.threshold(region, 130, 255, cv2.THRESH_BINARY) match = np.max( cv2.matchTemplate(thresh, self.TIME_ELAPSED_TEMPLATE, cv2.TM_CCORR_NORMED)) logger.debug(f"Time elapsed match={match:.1f}") return match > self.TIME_ELAPSED_MATCH_THRESHOLD if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(HeroSelectProcessor(), "assemble_your_team", "assemble_your_team_match")
else: s.kills = s.kills[0] logger.info(f"Got {pprint.pformat(r)}") return r def _mask_components_touching_edges(self, im: np.ndarray, threshold=100) -> bool: masked = False _, t = cv2.threshold(im, threshold, 255, cv2.THRESH_BINARY) mask, components = imageops.connected_components(t) for c in components[1:]: if c.y <= 1 or c.y + c.h >= im.shape[0] - 1: mask = (mask != c.label).astype(np.uint8) * 255 mask = cv2.erode(mask, None) im[:] = cv2.bitwise_and(im, mask) masked = c.area > 50 return masked if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor( SquadSummaryProcessor(), "squad_summary", "squad_summary_match", game="apex", )
return map_text, mode_text VS_TEMPLATE = imageops.imread( os.path.join(os.path.dirname(__file__), "data", "vs_template.png"), 0) VS_MATCH_THRESHOLD = 0.6 def detect_tab(self, frame: Frame) -> bool: region = self.REGIONS["vs"].extract_one(frame.image) region = cv2.resize(region, (50, 50), cv2.INTER_NEAREST) region_gray = np.min(region, axis=2) # threshold of around 200, allow for flux/lower brightness settings bringing the range down _, thresh = cv2.threshold(region_gray, np.percentile(region_gray.ravel(), 93), 255, cv2.THRESH_BINARY) match = 1 - float( np.min( cv2.matchTemplate(thresh, self.VS_TEMPLATE, cv2.TM_SQDIFF_NORMED))) frame.overwatch.tab_match = round(match, 5) return match > self.VS_MATCH_THRESHOLD if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(TabProcessor(), "tab_screen", "tab_match")
os.path.join(os.path.dirname(__file__), "data", "competitive_points.png"), 0 ) COMPETITIVE_POINTS_THRESH = 0.8 def process(self, frame: Frame) -> bool: y = frame.image_yuv[:, :, 0] im = self.REGIONS["competitive_points"].extract_one(y) _, thresh = cv2.threshold(im, 50, 255, cv2.THRESH_BINARY) match = np.max(cv2.matchTemplate(thresh, self.COMPETITIVE_POINTS_TEMPLATE, cv2.TM_CCORR_NORMED)) frame.overwatch.endgame_sr_match = round(float(match), 5) if match > self.COMPETITIVE_POINTS_THRESH: sr_image = self.REGIONS["sr"].extract_one(y) sr = big_noodle.ocr_int(sr_image) if sr is None: logger.warning(f"Unable to parse SR") else: frame.overwatch.endgame_sr = EndgameSR( sr, image=lazy_upload("end_sr", self.REGIONS.blank_out(frame.image), frame.timestamp) ) return True return False if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(EndgameSRProcessor(), "endgame_sr", "endgame_sr_match")
logger.debug( f"Found match for {matched!r} with match={match:0.3f} ({match_sm:.2f}, {match_lg:.2f}, {match_lock:.2f}), x={match_x} => grouped={grouped}" ) suffix = "_group" if grouped else "_solo" frame.overwatch.role_select = RoleSelect( placement_text=imageops.tesser_ocr_all( self.REGIONS["placements" + suffix].extract(y), whitelist=string.digits + "/-" ), sr_text=big_noodle.ocr_all(self.REGIONS["srs" + suffix].extract(y), height=23, invert=True), account_name=imageops.tesser_ocr( self.REGIONS["account_name"].extract_one(y), engine=imageops.tesseract_lstm ), grouped=grouped, image=lazy_upload( "role_select", self.REGIONS.blank_out(frame.image), frame.timestamp, selection="last" ), ) if frame.debug_image is not None: self.REGIONS.draw(frame.debug_image) _draw_role_select(frame.debug_image, frame.overwatch.role_select) return True return False if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(RoleSelectProcessor(), "role_select", "role_select_match")
def main() -> None: from overtrack_cv.util.test_processor import test_processor test_processor(CombatProcessor(), "combat_log")
# with open(p) as f: # fdata = json.load(f) # if 'minimap' in fdata: # f = Frame.create( # cv2.imread(p.replace('_frame.json', '_image.png')), # fdata['timestamp'], # debug=True, # current_game=cg, # game_time=fdata.get('game_time') # ) # proc.process(f) # # if proc.current_composite: # for i in proc.current_composite.images: # cv2.imshow(f'ring {i}', ((np.clip(proc.current_composite.images[i].array, 0, 30) / 30) * 255).astype(np.uint8)) # # cv2.imshow('debug', f.debug_image) # cv2.waitKey(0) # util.test_processor(proc, 'minimap', 'game_time', 'current_game') test_processor( "minimap_s3", proc, "minimap", "game_time", "current_game", game="apex", test_all=False, warmup=False, )
) if not digits: return None try: return int("".join(digits)) except Exception as e: logger.warning(f"Unable to parse OCR of clip: {digits!r}: {e}") return None if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor( WeaponProcessor(), "weapons", game="apex", ) # util.test_processor('weapons', WeaponProcessor(), 'weapons', game='apex') # util.test_processor(WeaponProcessor(), 'weapons') # proc = WeaponProcessor() # # from overtrack_cv.source.shmem.shmem_capture import SharedMemoryCapture # # cap = SharedMemoryCapture(debug_frames=True) # cap.start() # # while True: # frame = cap.get()
cv2.rectangle(debug_image, (x, y), (x + template_shape[1], y + template_shape[0]), (0, 0, 255), 1) cv2.putText( debug_image, f"{(x, y)}: {name}, match={match:.3f}, index={i}", (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), ) if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(EliminationsProcessor(), "eliminations", show=True) # for p in glob.glob('C:/scratch/lines/*.png'): # im = cv2.imread(p) # s = big_noodle.ocr(im, channel='max', height=30, debug=False) # print(s) # # s = big_noodle_ctc.ocr( # im # ) # print(s) # # cv2.imshow('im', im) # cv2.waitKey(0) # print()
cv2.THRESH_BINARY) frame.overwatch.score_screen_match = round( 1 - float( np.min( cv2.matchTemplate(thresh, self.COMPLETE_TEMPLATE, cv2.TM_SQDIFF_NORMED))), 5) return frame.overwatch.score_screen_match > self.COMPLETE_TEMPLATE_THRESH FINAL_SCORE_TEMPLATE = imageops.imread( os.path.join(os.path.dirname(__file__), "data", "final_score_template.png"), 0) FINAL_SCORE_TEMPLATE_THRESH = 0.6 def detect_final_score(self, frame: Frame) -> bool: text_region = self.REGIONS["final_score_text"].extract_one(frame.image) text_region = cv2.resize(text_region, (0, 0), fx=0.75, fy=0.75) thresh = imageops.otsu_thresh_lb_fraction(text_region, 0.8) frame.overwatch.final_score_match = round( 1 - float( np.min( cv2.matchTemplate(thresh, self.FINAL_SCORE_TEMPLATE, cv2.TM_SQDIFF_NORMED))), 5) return frame.overwatch.final_score_match > self.FINAL_SCORE_TEMPLATE_THRESH if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(ScoreProcessor(), "score_screen", "final_score", "score_screen_match", "final_score_match")
converter = tf.lite.TFLiteConverter.from_keras_model(new_model) tflite_model = converter.convert() with open(os.path.join(os.path.dirname(__file__), "data", "parse_objective.tflite"), "wb") as f: f.write(tflite_model) import tflite_runtime.interpreter as tflite interpreter = tflite.Interpreter(os.path.join(os.path.dirname(__file__), "data", "parse_objective.tflite")) pprint(new_model.outputs) pprint(interpreter.get_output_details()) if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(ObjectiveProcessor(), "objective") if __name__ == "__": # convert_tflite() import tensorflow as tf with tf.device("/cpu:0"): proc = ObjectiveProcessor() # util.test_processor('objective', proc, 'objective2', test_all=False) import glob import random
# t1 = time.time() # del f['killfeed_2'] # run = (t1 - t0) # totaltime += run # sleep = 1 - run # sleeptime += sleep # print(f'{run:1.3f} {sleep:1.3f}') # time.sleep(sleep) # # print() # print(f'{totaltime:1.3f} {sleeptime:1.3f}') # exit(0) from overtrack_cv.util.test_processor import test_processor test_processor( KillfeedProcessor(use_tflite=True, extrapolate_rowdetect=True), "killfeed") import glob import random paths = glob.glob( "D:/overtrack/overwatch_killfeed/autoclass/vid_low/*.png") random.shuffle(paths) proc = KillfeedProcessor() for p in paths: killrow = cv2.imread(p) predictions, decoded = proc._predict([killrow]) kill = proc.parse_kill(0, predictions, decoded, 0, False)
TEMPLATES = { str(os.path.basename(p)).split(".")[0]: cv2.imread(p, 0) for p in glob.glob( os.path.join(os.path.dirname(__file__), "data", "*.png")) } REQUIRED_MATCH = 0.9 def eager_load(self) -> None: self.REGIONS.eager_load() def process(self, frame: Frame) -> bool: y = frame.image_yuv[:, :, 0] region = self.REGIONS["map_name"].extract_one(y) _, thresh = cv2.threshold(region, 200, 255, cv2.THRESH_BINARY) match, map_name = imageops.match_templates(thresh, self.TEMPLATES, method=cv2.TM_CCORR_NORMED, required_match=0.95) if match > self.REQUIRED_MATCH: frame.apex.map_loading = MapLoading(map_name) return True return False if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(MapLoadingProcessor(), "apex.map_loading")
frame.overwatch.main_menu_match = round( 1 - float(np.min(cv2.matchTemplate(thresh, self.OVERWATCH_TEMPLATE, cv2.TM_SQDIFF_NORMED))), 5 ) return frame.overwatch.main_menu_match > self.OVERWATCH_TEMPLATE_THRESH COMPETITIVE_TEMPLATE = imageops.imread( os.path.join(os.path.dirname(__file__), "data", "competitive_play.png"), 0 ) COMPETITIVE_TEMPLATE_LARGE = imageops.imread( os.path.join(os.path.dirname(__file__), "data", "competitive_play_large.png"), 0 ) COMPETITIVE_TEMPLATE_THRESH = 0.6 def detect_play_menu(self, frame: Frame) -> bool: competitive_region = self.REGIONS["competitive_play"].extract_one(frame.image) competitive_region = cv2.resize(competitive_region, (0, 0), fx=0.5, fy=0.5) gray = np.min(competitive_region, axis=2) _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU) match = 0.0 for t in self.COMPETITIVE_TEMPLATE, self.COMPETITIVE_TEMPLATE_LARGE: match = max(match, round(1 - float(np.min(cv2.matchTemplate(thresh, t, cv2.TM_SQDIFF_NORMED))), 5)) frame.overwatch.play_menu_match = match return frame.overwatch.play_menu_match > self.COMPETITIVE_TEMPLATE_THRESH if __name__ == "__main__": from overtrack_cv.util.test_processor import test_processor test_processor(MenuProcessor(), "play_menu", "play_menu_match", "main_menu", "main_menu_match")