Esempio n. 1
0
def main():
    # 3 of the 12 set that's bad
    cards_3_bad = cv2.imread('images/set-3-bad.jpg')
    thresh_3bad = s.get_binary(cards_3_bad)
    res3bad = s.detect_cards(cards_3_bad)
    assert res3bad is not None and len(res3bad) == 3

    # 12 cards
    cards_12 = cv2.imread('images/set-12-random-2sets-sm.jpg')

    thresh_12bad = s.get_binary(cards_12)
    res12bad = s.detect_cards(cards_12, draw_rects=False)
    util.show(cards_12)

    # Subset of 3, with the 1 problem card
    cards = res12bad
    for i in range(len(cards)):
        card = cards[i]
        # test_props(card)
        cv2.imwrite('images/cards/card-12-%02d.jpg' % i, card)

    props = s.get_cards_properties(res12bad)
    s.pretty_print_properties(props)

    g = game(cards=props)
    sets = g.play(True)

    if sets:
        print '\nFound sets:'
        for st in sets:
            just_props = [e for i, e in st]
            print just_props
            s.pretty_print_properties(just_props)
            print('---')
    else:
        print 'no sets :('

    print 'tests pass'
Esempio n. 2
0
def play_game(path_in, path_is_url=False, printall=False, \
              draw_contours=True, resize_contours=True, \
              draw_rects=False, sets_or_no=False, \
              pop_open=True):
    """Takes in an image path (to local file or onlin), finds all sets, and pretty prints them to screen.
    if printall - prints the identities of all cards in the image
    if draw_contours - outlines the cards belonging to each set
    if resize_contours - enlarges contours for cards belonging to multiple sets to avoid overlay
    if draw_rects - draws box rects around cards belonging to each set
    if sets_or_no - outlines the image in green or red, depending on whether there are any sets present"""
    if path_is_url:
        # parse image string directly into numpy array
        img_str = requests.get(path_in).content
        nparr = np.fromstring(img_str, np.uint8)
        img = cv2.imdecode(nparr, cv2.CV_LOAD_IMAGE_COLOR)

    else:
        img = cv2.imread(path_in)

    img = s.resize_image(img, 600)
    util.show(img)

    contours, detected = s.detect_cards(img, draw_rects=False, return_contours=True)
    props = s.get_cards_properties(detected)

    if printall:
        s.pretty_print_properties(props)

    g = game(cards=props)
    sets = g.play(idx=True)

    # RED, ORANGE, YELLOW, GREEN, BLUE, //INDIGO,// VIOLET
    #BGR_RAINBOW = [ (0, 0, 255), (0, 127, 255), (0, 255, 255), \
    #                (0, 255, 0), (255, 0, 0), #(130, 0, 75),
    #                (255, 0, 139) ]

    if sets:
        # choose a group of colors at random to represent the set of sets
        #COLORS = random.sample(BGR_RAINBOW, len(sets))
        COLORS = util.random_color_palette(len(sets))

        if resize_contours:
            # count number of sets that each winning card index belongs to
            counter = Counter( card[0] for st in sets for card in st )

        for i, st in enumerate(sets):
            color = COLORS[i]
            st_indices, st_props = zip(*st)
            s.pretty_print_properties(st_props)
            print ('---')

            if draw_contours or draw_rects:
                winning_contours = [ contours[c] for c in st_indices ]

                if draw_contours:
                    if resize_contours:
                        for idx in st_indices:
                            # set base thickness
                            thickness = 3
                            count = counter[idx]
                            if count > 1:
                                thickness += 6*counter[idx]
                            counter[idx] -= 1
                            cv2.drawContours(img, contours, idx, color, thickness)

                    else:
                        cv2.drawContours(img, winning_contours, -1, color, 3)

                if draw_rects:
                    # get bounding rectangles
                    winning_rects = [ cv2.minAreaRect(c) for c in winning_contours ]
                    for rect in winning_rects:
                        # convert to ints
                        r = [ (int(x), int(y)) for x,y in cv.BoxPoints(rect) ]
                        cv2.rectangle(img, r[0], r[2], color)

    else:
        print 'no sets :('

    if sets_or_no:
        height, width, _ = img.shape
        BORDER_SCALAR = 0.01
        border_h, border_w = ( int(dim*BORDER_SCALAR) for dim in (height, width))

        # indices 0 or 1 correspond to bool for if no sets (BGR for red) or sets (green)
        BORDER_COLORS = [ (19,19,214), (94,214,19) ]

        img_outlined = cv2.copyMakeBorder(img, border_h, border_h, \
                                          border_w, border_w, \
                                          cv2.BORDER_CONSTANT,
                                          value = BORDER_COLORS[bool(sets)])

    processed_img = (img_outlined if sets_or_no else img)

    final_img = processed_img #s.resize_image(processed_img, 800)

    if pop_open: util.show(final_img)

    num_sets = ( len(sets) if sets else 0 )

    # convert image array to string representing JPEG of image (in RGB)
    image = Image.fromarray( cv2.cvtColor(processed_img, cv2.COLOR_BGR2RGB) )
    output = StringIO.StringIO()
    image.save(output, format='JPEG')
    mystr = output.getvalue()
    output.close()

    # don't write image to file, dude....because we are badass Tweepy hackers
    #cv2.imwrite('tmp.jpeg', final_img)

    # encode image string to base64 and safe-encode it for Twitter upload request
    final = requests.utils.quote(base64.b64encode(mystr), safe='')

    #l = len(final)
    #print 'length is {}'.format(l)
    #print 'size is {} bytes'.format((l-814)/1.37)
    # N.B.
    # length is 123932
    # size is 89867.1532847 bytes

    return (num_sets, final)