예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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