def main(): random.seed() #bg_images = load_dtd() #bg = Backgrounds() #bg.get_random(display=True) card_pool = pd.DataFrame() for set_name in Config.all_set_list: df = fetch_data.load_all_cards_text('%s/csv/%s.csv' % (Config.data_dir, set_name)) #for _ in range(3): # card_info = df.iloc[random.randint(0, df.shape[0] - 1)] # # Currently ignoring planeswalker cards due to their different card layout # is_planeswalker = 'Planeswalker' in card_info['type_line'] # if not is_planeswalker: # card_pool = card_pool.append(card_info) card_pool = card_pool.append(df) ''' print(card_pool) mana_symbol_set = set() for _, card_info in card_pool.iterrows(): has_mana_cost = isinstance(card_info['mana_cost'], str) if has_mana_cost: mana_cost = re.findall('\{(.*?)\}', card_info['mana_cost']) for symbol in mana_cost: mana_symbol_set.add(symbol) print(mana_symbol_set) ''' for _, card_info in card_pool.iterrows(): img_name = '%s/card_img/png/%s/%s_%s.png' % ( Config.data_dir, card_info['set'], card_info['collector_number'], fetch_data.get_valid_filename(card_info['name'])) print(img_name) card_img = cv2.imread(img_name) if card_img is None: fetch_data.fetch_card_image(card_info, out_dir='../usb/data/png/%s' % card_info['set']) card_img = cv2.imread(img_name) detected_object_list = apply_bounding_box(card_img, card_info, display=True) print(detected_object_list) return
def draw_card_graph(exist_cards, card_pool, f_len): """ Given the history of detected cards in the current and several previous frames, draw a simple graph displaying the detected cards with its confidence level :param exist_cards: History of all detected cards in the previous (f_len) frames :param card_pool: pandas dataframe of all card's information :param f_len: length of windows (in frames) to consider for confidence level :return: """ # Lots of constants to set the dimension of each elements w_card = 63 # Width of the card image displayed h_card = 88 gap = 25 # Offset between each elements gap_sm = 10 # Small offset w_bar = 300 # Length of the confidence bar at 100% h_bar = 12 txt_scale = 0.8 n_cards_p_col = 4 # Number of cards displayed per one column w_img = gap + (w_card + gap + w_bar + gap) * 2 # Dimension of the entire graph (for 2 columns) h_img = 480 img_graph = np.zeros((h_img, w_img, 3), dtype=np.uint8) x_anchor = gap y_anchor = gap i = 0 # Cards are displayed from the most confident to the least # Confidence level is calculated by number of frames that the card was detected in for key, val in sorted(exist_cards.items(), key=itemgetter(1), reverse=True)[:n_cards_p_col * 2]: card_name = key[:key.find('(') - 1] card_set = key[key.find('(') + 1:key.find(')')] confidence = sum(val) / f_len card_info = card_pool[(card_pool['name'] == card_name) & (card_pool['set'] == card_set)].iloc[0] img_name = '%s/card_img/tiny/%s/%s_%s.png' % ( Config.data_dir, card_info['set'], card_info['collector_number'], fetch_data.get_valid_filename(card_info['name'])) # If the card image is not found, just leave it blank if os.path.exists(img_name): card_img = cv2.imread(img_name) else: card_img = np.ones((h_card, w_card, 3)) * 255 cv2.putText(card_img, 'X', ((w_card - int(txt_scale * 25)) // 2, (h_card + int(txt_scale * 25)) // 2), cv2.FONT_HERSHEY_SIMPLEX, txt_scale, (0, 0, 0), 2) # Insert the card image, card name, and confidence bar to the graph img_graph[y_anchor:y_anchor + h_card, x_anchor:x_anchor + w_card] = card_img cv2.putText( img_graph, '%s (%s)' % (card_name, card_set), (x_anchor + w_card + gap, y_anchor + gap_sm + int(txt_scale * 25)), cv2.FONT_HERSHEY_SIMPLEX, txt_scale, (255, 255, 255), 1) cv2.rectangle(img_graph, (x_anchor + w_card + gap, y_anchor + h_card - (gap_sm + h_bar)), (x_anchor + w_card + gap + int(w_bar * confidence), y_anchor + h_card - gap_sm), (0, 255, 0), thickness=cv2.FILLED) y_anchor += h_card + gap i += 1 if i % n_cards_p_col == 0: x_anchor += w_card + gap + w_bar + gap y_anchor = gap pass return img_graph
def main(args): random.seed() ia.seed(random.randrange(10000)) bg_images = generate_data.load_dtd(dtd_dir='%s/dtd/images' % Config.data_dir, dump_it=False) background = generate_data.Backgrounds(images=bg_images) card_pool = pd.DataFrame() for set_name in Config.all_set_list: df = fetch_data.load_all_cards_text('%s/csv/%s.csv' % (Config.data_dir, set_name)) card_pool = card_pool.append(df) class_ids = {} with open('%s/obj.names' % Config.data_dir) as names_file: class_name_list = names_file.read().splitlines() for i in range(len(class_name_list)): class_ids[class_name_list[i]] = i for i in range(args.num_gen): # Arbitrarily select top left and right corners for perspective transformation # Since the training image are generated with random rotation, don't need to skew all four sides skew = [[random.uniform(0, 0.25), 0], [0, 1], [1, 1], [random.uniform(0.75, 1), 0]] generator = ImageGenerator(background.get_random(), class_ids, args.width, args.height, skew=skew) out_name = '' # Use 2 to 5 cards per generator for _, card_info in card_pool.sample(random.randint(2, 5)).iterrows(): img_name = '%s/card_img/png/%s/%s_%s.png' % ( Config.data_dir, card_info['set'], card_info['collector_number'], fetch_data.get_valid_filename(card_info['name'])) out_name += '%s%s_' % (card_info['set'], card_info['collector_number']) card_img = cv2.imread(img_name) if card_img is None: fetch_data.fetch_card_image( card_info, out_dir='%s/card_img/png/%s' % (Config.data_dir, card_info['set'])) card_img = cv2.imread(img_name) if card_img is None: print('WARNING: card %s is not found!' % img_name) detected_object_list = generate_data.apply_bounding_box( card_img, card_info) card = Card(card_img, card_info, detected_object_list) generator.add_card(card) for j in range(args.num_iter): seq = iaa.Sequential([ iaa.Multiply((0.8, 1.2)), # darken / brighten the whole image iaa.SimplexNoiseAlpha(first=iaa.Add(random.randrange(64)), per_channel=0.1, size_px_max=[3, 6], upscale_method="cubic"), # Lighting iaa.AdditiveGaussianNoise(scale=random.uniform(0, 0.05) * 255, per_channel=0.1), # Noises iaa.Dropout(p=[0, 0.05], per_channel=0.1) # Dropout ]) if i % 3 == 0: generator.generate_non_obstructive() generator.export_training_data( visibility=0.0, out_name='%s/train/non_obstructive_update/%s%d' % (Config.data_dir, out_name, j), aug=seq) elif i % 3 == 1: generator.generate_horizontal_span( theta=random.uniform(-math.pi, math.pi)) generator.export_training_data( visibility=0.0, out_name='%s/train/horizontal_span_update/%s%d' % (Config.data_dir, out_name, j), aug=seq) else: generator.generate_vertical_span( theta=random.uniform(-math.pi, math.pi)) generator.export_training_data( visibility=0.0, out_name='%s/train/vertical_span_update/%s%d' % (Config.data_dir, out_name, j), aug=seq) #generator.generate_horizontal_span(theta=random.uniform(-math.pi, math.pi)) #generator.render(display=True, aug=seq, debug=True) print('Generated %s%d' % (out_name, j)) generator.img_bg = background.get_random() pass
def calc_image_hashes(card_pool, save_to=None, hash_size=None): """ Calculate perceptual hash (pHash) value for each cards in the database, then store them if needed :param card_pool: pandas dataframe containing all card information :param save_to: path for the pickle file to be saved :param hash_size: param for pHash algorithm :return: pandas dataframe """ if hash_size is None: hash_size = [16, 32] elif isinstance(hash_size, int): hash_size = [hash_size] # Since some double-faced cards may result in two different cards, create a new dataframe to store the result new_pool = pd.DataFrame(columns=list(card_pool.columns.values)) for hs in hash_size: new_pool['card_hash_%d' % hs] = np.NaN #new_pool['art_hash_%d' % hs] = np.NaN for ind, card_info in card_pool.iterrows(): if ind % 100 == 0: print('Calculating hashes: %dth card' % ind) card_names = [] # Double-faced cards have a different json format than normal cards if card_info['layout'] in ['transform', 'double_faced_token']: if isinstance(card_info['card_faces'], str): card_faces = ast.literal_eval(card_info['card_faces']) else: card_faces = card_info['card_faces'] for i in range(len(card_faces)): card_names.append(card_faces[i]['name']) else: # if card_info['layout'] == 'normal': card_names.append(card_info['name']) for card_name in card_names: # Fetch the image - name can be found based on the card's information card_info['name'] = card_name img_name = '%s/card_img/png/%s/%s_%s.png' % ( Config.data_dir, card_info['set'], card_info['collector_number'], fetch_data.get_valid_filename(card_info['name'])) card_img = cv2.imread(img_name) # If the image doesn't exist, download it from the URL if card_img is None: fetch_data.fetch_card_image( card_info, out_dir='%s/card_img/png/%s' % (Config.data_dir, card_info['set'])) card_img = cv2.imread(img_name) if card_img is None: print('WARNING: card %s is not found!' % img_name) # Compute value of the card's perceptual hash, then store it to the database #img_art = Image.fromarray(card_img[121:580, 63:685]) # For 745*1040 size card image img_card = Image.fromarray(card_img) for hs in hash_size: card_hash = ih.phash(img_card, hash_size=hs) card_info['card_hash_%d' % hs] = card_hash #art_hash = ih.phash(img_art, hash_size=hs) #card_info['art_hash_%d' % hs] = art_hash new_pool.loc[0 if new_pool.empty else new_pool.index.max() + 1] = card_info if save_to is not None: new_pool.to_pickle(save_to) return new_pool