def main(): #game = 'SuperMarioBros-Nes' #play_number = 1000 game = 'QBert-Nes' play_number = 3928 sprite_dir = f'./sprites/sprites/{game}' play_through_data = migrate_play_through(get_playthrough(play_number, game), play_number, game) sys.exit(0) #raw = play_through_data['raw'] #cull(play_number, game) cull(play_number, game, sample=10)
def find(play_number, game='SuperMarioBros-Nes', sample=None, randomize=False, supervised=True, start=0, stop=None): play_through_data = migrate_play_through(get_playthrough(play_number, game), play_number, game) play_through = play_through_data['partial'] if 'partial' in play_through_data else play_through_data['raw'] #play_through_data = np.load('./culled.npz') #play_through = play_through_data['culled'] game_dir = f'./sprites/sprites/{game}' ensure_dir(game_dir) sprites = load_sprites(game_dir, game, ds=ds) if supervised is True: not_sprites = [] else: possible_sprites = [] if randomize is True: play_through = random.shuffle(play_through) stop = sample if stop is None else stop for i, frame in enumerate(play_through[start:stop]): parse_start = time.time() igraph = FrameGraph(frame, game=game, play_num=play_number, bg_color=frame[0][0], frame_num=i, indirect=True, ds=ds) dgraph = FrameGraph(frame, game=game, play_num=play_number, bg_color=frame[0][0], frame_num=i, indirect=False, ds=ds) parse_end = time.time() try: if supervised is True: sprites[True], not_sprites = confirm_sprites(igraph, sprites, True, not_sprites=not_sprites) sprites[False], not_sprites = confirm_sprites(dgraph, sprites, False, not_sprites=not_sprites) else: sprites[True], possible_sprites, new_possible_sprites = unsupervised_sprite_finder(igraph, sprites, True, possible_sprites=possible_sprites) sprites[False], possible_sprites, new_possible_sprites = unsupervised_sprite_finder(dgraph, sprites, False, possible_sprites=possible_sprites) except EOFError: return print('frame number:', i, parse_end - parse_start) if supervised is False: us = unique_sprites(new_possible_sprites) print('number of unique possible sprites:', len(us)) ensure_dir(f'{game_dir}/possible/') for j, sprite in enumerate([k for k in us]): cv2.imwrite(f'{game_dir}/possible/{start + i}-{j}.png', sprite.to_image()) possible_sprites.extend(new_possible_sprites) if supervised is True: us = unique_sprites(sprites[True] + sprites[False]) print('number of unique sprites:', len(us)) for i, sprite in enumerate([j for j in us]): show_image(sprite.to_image(), scale=8.0) cv2.imwrite(f'{game_dir}/{i}.png', sprite.to_image())
def parse_and_hash_playthrough(game, play_through_number, ntype, img_count=None): pool = mp.Pool(8) pt = get_playthrough(play_through_number, game=game)['raw'] parsed_frames_masks_and_hashes = [ f for f in par(pt, img_count=img_count, ntype=ntype, pool=pool) ] frame_features = [i[0] for i in parsed_frames_masks_and_hashes] masks = [i[1] for i in parsed_frames_masks_and_hashes] hashes = [i[2] for i in parsed_frames_masks_and_hashes] pix_to_patch_index = [i[3] for i in parsed_frames_masks_and_hashes] return frame_features, masks, hashes, pix_to_patch_index
def mine(play_number, game='SuperMarioBros-Nes'): play_through_data = migrate_play_through(get_playthrough(play_number, game), play_number, game) play_through = play_through_data['partial'] if 'partial' in play_through_data else play_through_data['raw'] game_dir = f'./sprites/sprites/{game}' ensure_dir(game_dir) sprites = load_sprites(game_dir, game, ds=ds) #for i, frame in enumerate(random.choices(play_through, k=2)): for i, frame in enumerate(play_through[:1]): ret_val = process_frame(frame, play_number=play_number, frame_number=i) for j, sprite in enumerate([j for j in ret_val['sprites'][True]]): show_image(sprite.raw_frame, scale=8.0) cv2.imwrite(f'{game_dir}/{j}.png', sprite.raw_frame)
def get_frame_count(): ds = DataStore('db/sqlite.db', games_path='./games.json', echo=False) Patch.init_patch_db(ds) data = [] accum = 0 for play_number in range(1, 17696): try: play_through = get_playthrough(play_number) data.append( (play_number, len(play_through), accum, play_through.shape)) print(data[-1]) accum += len(play_through) except FileNotFoundError as e: print('FileNotFoundError: ', play_number) except Exception as e: print(e) with open('frame_count', 'w') as fp: json.dump(data, fp, indent=2)
def main(): game = 'SuperMarioBros-Nes' play_number = 1000 frame_number = 0 ntype = False total_time = 0 sprites = [ cv2.imread(f'./sprites/sprites/SuperMarioBros-Nes/{i}.png', cv2.IMREAD_UNCHANGED) for i in [0, 3, 35] ] parsed_sprites = [ quick_parse(img, ntype=ntype, shrink_mask=shrink) for img in sprites ] sprite_clouds = [i[0] for i in parsed_sprites] sprite_masks = [i[1] for i in parsed_sprites] sprite_kdt = [cKDTree(data=cloud[:, :2]) for cloud in sprite_clouds] mario_sprite, mario_cloud, mario_kdt = sprites[1], sprite_clouds[ 1], sprite_kdt[1] muv, mmag, _ = normalize_knn(sprite_kdt[1], mario_cloud[:, :2], k=8) pt = get_playthrough(play_number, game=game)['raw'] img_count = 1 # Load test image test_img = cv2.imread('knn_test.png') img1, s, bb = generate_random_test_image(test_img.shape, sprites, 5, overlap=False, bg_color=(0, 0, 0)) show_image(img1, scale=3) start = time.time() # Parse frame full_features, masks = quick_parse(test_img, ntype=ntype, shrink_mask=shrink) features = full_features[:, :2] total_time += time.time() - start print('features', time.time() - start, 'average', float(time.time() - start) / float(img_count)) # KDTrees start = time.time() tree = cKDTree(data=features) #trees = [ for f in features] total_time += time.time() - start print('trees', time.time() - start, 'average', float(time.time() - start) / float(img_count)) # Normalize vectors start = time.time() tuv, tmag, _ = normalize_knn(tree, features, k=12) total_time += time.time() - start print('normalization', time.time() - start, 'average', float(time.time() - start) / float(img_count)) # Match points start = time.time() matches = [] smatches = np.zeros((len(mario_cloud)), dtype=np.bool8) for i, tf in enumerate(full_features): #print([match_features(full_features[i], tmag[i], tuv[i], f, m, u) for f, m, u in zip(mario_cloud, mmag, muv)]) matches.append([ match_feature(full_features[i], tmag[i], tuv[i], f, m, u, p=True) for f, m, u in zip(mario_cloud, mmag, muv) ]) try: smatches[matches[-1].index(True)] = True except ValueError: pass #print([int(j) for j in matches[-1]], sum([int(j) for j in matches[-1]]), i) print(smatches) temp = [] with np.printoptions(threshold=10000000, linewidth=1000000000, formatter={'bool': lambda b: '1,' if b else ' ,'}): for i, m in enumerate(matches): print(f'{i: <3}: {np.array(m, dtype=np.bool8)}') for i in matches: try: temp.append(i.index(True)) except ValueError: temp.append(-1) print(temp)
def bench(): game = 'SuperMarioBros-Nes' play_number = 1000 ntype = False pool = mp.Pool(8) total_time = 0 sprites = [ cv2.imread(f'./sprites/sprites/SuperMarioBros-Nes/{i}.png', cv2.IMREAD_UNCHANGED) for i in [0, 3, 35] ] quick_parse(sprites[0], ntype=ntype, shrink_mask=shrink) parsed_sprites = [ f for f in par(sprites, img_count=len(sprites), ntype=ntype, pool=pool) ] sprite_full_features = np.array([i[0] for i in parsed_sprites]) sprite_masks = [i[1] for i in parsed_sprites] #parsed_sprites = [quick_parse(img, ntype=ntype, shrink_mask=shrink) for img in sprites] sprite_kdt = [cKDTree(data=cloud[:, :2]) for cloud in sprite_full_features] snorm = pool.starmap( partial(normalize_knn, k=8), zip(sprite_kdt, [sc[:, :2] for sc in sprite_full_features])) suvs, smags = [i[0] for i in snorm], [i[1] for i in snorm] sfeatures = [] for i in range(len(sprites)): sfeatures.append( populate_features(sprite_full_features[i], smags[i], suvs[i])) mario_sprite, mario_sprite_point_cloud, mario_kdt = sprites[1], sfeatures[ 1], sprite_kdt[1] muv, mmag, _ = normalize_knn(sprite_kdt[1], [i[:2] for i in mario_sprite_point_cloud], k=8) pt = get_playthrough(play_number, game=game)['raw'] img_count = len(pt) print('img_count', img_count) sprites = [ cv2.imread(f'./sprites/sprites/SuperMarioBros-Nes/{i}.png', cv2.IMREAD_UNCHANGED) for i in [0, 3, 35] ] # ensure quick_parse function is compiled is quick_parse(sprites[1], ntype=False) start = time.time() #features = [f[:, :2] for f in par(pt, img_count=img_count)] parsed_frames = [ f for f in par(pt, img_count=img_count, ntype=ntype, pool=pool) ] full_features = [i[0] for i in parsed_frames] masks = [i[1] for i in parsed_frames] features = [f[:, :2] for f in full_features] total_time += time.time() - start print('features', time.time() - start, 'average', float(time.time() - start) / float(img_count)) start = time.time() trees = pool.map(cKDTree, features) #trees = [ for f in features] total_time += time.time() - start print('trees', time.time() - start, 'average', float(time.time() - start) / float(img_count)) start = time.time() norm = pool.starmap(partial(normalize_knn, k=12), zip(trees, features)) tuv, tmag, _ = norm[0] #[normalize_knn(kdt, f, k=12) for kdt, f in zip(trees, features)] total_time += time.time() - start print('normalization', time.time() - start, 'average', float(time.time() - start) / float(img_count)) start = time.time() total_time += time.time() - start print('matching', time.time() - start, 'average', float(time.time() - start) / float(img_count)) #for i in range(len(sprites)): # for j, f in enumerate(full_features): # #print('len sf', len(sfeatures[i])) # #print('len sm', len(smags[i])) # #print('len su', len(suvs[i])) # match_all_featues(full_features[j], tmag[j], tuv[j], sfeatures[i], smags[i], suvs[i]) print('total', total_time, 'average', float(total_time) / float(img_count))
def cull(play_number, game='SuperMarioBros-Nes', sample=None, randomize=False, start=0, stop=None): play_through_data = migrate_play_through(get_playthrough(play_number, game), play_number, game) raw = play_through_data['raw'] #play_through = play_through_data['in_progress'] if 'partial' in play_through_data else play_through_data['raw'] play_through = raw.copy() game_dir = f'./sprites/sprites/{game}' ensure_dir(game_dir) sprites = load_sprites(game_dir, game, ds=ds) not_sprites = [] if randomize is True: play_through = random.shuffle(range(play_through.shape[0])) loop_start = time.time() culled_frames = [] culled_markers = np.zeros(play_through.shape[0:1], dtype=np.bool8) commulative_time = 0 errors = [] stop = sample if stop is None else stop for i, frame in enumerate(play_through[start:stop]): index = frame if randomize is False else i frame = frame if randomize is False else play_through[frame] start = time.time() igraph = FrameGraph(frame, game=game, play_num=play_number, bg_color=frame[0][0], frame_num=i, indirect=True, ds=ds) dgraph = FrameGraph(frame, game=game, play_num=play_number, bg_color=frame[0][0], frame_num=i, indirect=False, ds=ds) try: i_img = find_and_cull(igraph, sprites[True]) except Exception as err: # ['error', 'stack_trace', 'frame_number', 'indirect', 'frame_shape', 'sprite'] err_tb = tb.format_exc() print('------------------------- err_tb -------------------------') print(err_tb) print('----------------------------------------------------------') print() errors.append( CullExceptionBundle( err, tb.format_exc(), i, False, igraph.raw_frame ) ) try: d_img = find_and_cull(dgraph, sprites[False]) except Exception as err: # ['error', 'stack_trace', 'frame_number', 'indirect', 'frame'] err_tb = tb.format_exc() print('------------------------- err_tb -------------------------') print(f'frame: {index}') print(err_tb) print('----------------------------------------------------------') print() errors.append( CullExceptionBundle( err, err_tb, i, False, dgraph.raw_frame ) ) end = time.time() commulative_time += end - start print(f'frame {i}: {end - start}, {commulative_time}') culled_frames.append(merge_images(i_img, d_img, bg_color=igraph.bg_color)) cv2.imwrite(f'./qbert/{i}.png', cv2.cvtColor(culled_frames[-1], cv2.COLOR_BGR2RGB)) loop_end = time.time() print('total time:', loop_end - loop_start) np.savez(f'culled.{game}.npz', raw=raw, culled=np.array(culled_frames, dtype=np.uint8), culled_markers=culled_markers) if len(errors) > 0: ensure_dir('./logs') with open('logs/errors.log', 'a') as fp: fp.write(log_info(f'\nrun started at: {loop_start}')) for e in errors: # ['error', 'stack_trace', 'frame_number', 'indirect', 'frame'] log_error(message=e.error.args, error=e.error, stack_trace=e.stack_trace, frame_number=e.frame_number, indirect=e.indirect, frame=e.frame)
SpriteLocation = namedtuple('SpriteLocation', ['bounding_box', 'path']) if __name__ == '__main__': sky = [248, 148, 88] sprite_dir = './sprites/sprites/SuperMarioBros-Nes' test_sprite_dir = './sprites/test/test_cases/SuperMarioBros-Nes/sprites/test_sets/sprite_set' game = 'SuperMarioBros-Nes' play_number = 1000 #ss = SpriteSet(game=game, sprite_dir=test_sprite_dir, ds=ds) ss = SpriteSet(game=game, sprite_dir=sprite_dir, ds=ds) print('sprite count:') print('\tTrue:', len(ss.sprites[True])) print('\tFalse:', len(ss.sprites[False])) pt = get_playthrough(1000, 'SuperMarioBros-Nes')['raw'] matches = [] for i, frame in enumerate(pt): print(i) graphs = { True: FrameGraph(frame, bg_color=sky, indirect=True, ds=ds), False: FrameGraph(frame, bg_color=sky, indirect=False, ds=ds), } img = frame.copy() for ntype in [True, False]: graph = graphs[ntype] for j, single in enumerate(ss._single_node_sprites[ntype]): sprite = ss.sprites[ntype][single] matching_nodes = get_matching_nodes(graph, sprite.patches[0]) for node in matching_nodes: matches.append(