diff --git a/bot.py b/bot.py index 27fc925..0fb2b27 100644 --- a/bot.py +++ b/bot.py @@ -7,15 +7,13 @@ class listener_tweeter(StreamListener): - def _onconnect(self): - print 'Connected! Listening...' # override on_status to pass data from on_data method of tweepy's StreamListener def on_status(self, status): print '{} said: "{}"'.format(status.user.screen_name, status.text) # ignore retweets or tweets from self - if status.retweeted or ( status.user.screen_name == 'ProfessorSet' ): + if status.retweeted or ( status.user.screen_name.lower() == 'professorset' ): return img_str = None @@ -26,8 +24,8 @@ def on_status(self, status): try: tweet_url = re.search(r'https:.*\b', status.text).group(0) with_sets_outlined = (False if re.search(r'sets or not', status.text) else True) - text, img_str = solve_tweeted_set(tweet_url, with_sets_outlined=with_sets_outlined) + #print text #ignore tweets with no image except AttributeError: @@ -36,7 +34,7 @@ def on_status(self, status): text += '!'*n response_text = '.@{} {}'.format(status.user.screen_name, text) - print response_text + #print response_text try: response = api.retweet(id=status.id) @@ -100,12 +98,15 @@ def solve_tweeted_set(tweet_url, with_sets_outlined=True): # scrape tweet HTML string for image url soup = BeautifulSoup(tweet_content, 'lxml') img_url = soup.find('meta', attrs={'property': 'og:image'})['content'] + #print img_url # find Sets kwargs = {'path_is_url': True, 'pop_open': False} kwargs['draw_contours'] = (True if with_sets_outlined else False) kwargs['sets_or_no'] = (False if with_sets_outlined else True) + #print "about to play" num_sets, initial_img_str = t.play_game(img_url, **kwargs) + #print num_sets # send string with media_data (rather than media) tag because it is base64 encoded img_str = 'media_data={}'.format(initial_img_str) diff --git a/set_solver.py b/set_solver.py index d692197..a3536f5 100644 --- a/set_solver.py +++ b/set_solver.py @@ -1,10 +1,7 @@ import cv2, sys, os import cv2.cv as cv -import sys import numpy as np import util as util -import os -import code import set_constants as sc reload(util) @@ -12,7 +9,7 @@ def resize_image(img, new_width=600): """Given cv2 image object and maximum dimension, returns resized image such that height or width (whichever is larger) == max dimension""" h, w, _ = img.shape - + if h > w: img = np.rot90(img) new_height = int((1.0*h/w)*new_width) @@ -31,7 +28,7 @@ def get_card_properties(cards, training_set=None): texture = get_card_texture(img) p = (num, color, shape, texture) if None not in p: - properties.append(p) + properties.append(p) return properties def pretty_print_properties(properties): @@ -97,7 +94,7 @@ def transform_card(card, image): approximated_poly = get_approx_poly(card, do_rectify=True) if approximated_poly is None: - # could not find card poly + # could not find card poly return None dest = np.array(card_shape, np.float32) @@ -414,21 +411,15 @@ def get_color_from_hue(hue): # get histogram of hue values hist,_ = np.histogram(hue, 15, (0, 255)) + print hist + if hist[3]+hist[4] > 1200: return sc.PROP_COLOR_GREEN - elif hist[8]+hist[9] > 250: + elif hist[8]+hist[9] > 30: return sc.PROP_COLOR_PURPLE else: return sc.PROP_COLOR_RED - - # if sum(hist[130:181]) > 750: - # return sc.PROP_COLOR_PURPLE - # elif sum(hist[40:81]) > 750: - # return sc.PROP_COLOR_GREEN - # else: - # return sc.PROP_COLOR_RED - def get_texture_from_hue(hue, contour_box): # for convenience card_w = sc.SIZE_CARD_W @@ -439,12 +430,14 @@ def get_texture_from_hue(hue, contour_box): # get a 20x20 square from each of the corners of the card, average values hue_bg = np.mean([ - hue[0:20, 0:20], hue[card_h-20:card_h, card_w-20:card_w], - hue[0:20, card_w-20:card_w], hue[card_h-20:card_h, 0:20]]) + hue[6:26, 6:26], hue[card_h-26:card_h-6, card_w-26:card_w-6], + hue[6:26, card_w-26:card_w-6], hue[card_h-26:card_h-6, 6:26]]) # get a 20x20 square from the center of the shape, average values hue_center = np.mean(hue[y+h/2-10:y+h/2+10, x+w/2-10:x+w/2+10]) + util.show(hue[y+h/2-10:y+h/2+10, x+w/2-10:x+w/2+10]) + # guess texture based on ratio of inside to outside hues hue_ratio = max(hue_bg, hue_center) / min(hue_bg, hue_center) if hue_ratio < 1.3: @@ -454,6 +447,49 @@ def get_texture_from_hue(hue, contour_box): else: return sc.PROP_TEXTURE_SOLID +def get_texture_from_hue_val(hue, val, contour_box): + # for convenience + card_w = sc.SIZE_CARD_W + card_h = sc.SIZE_CARD_H + + # uppack bounding box of contour + x, y, w, h = contour_box + + val_bg_box = np.mean([ + val[6:26, 6:26], val[card_h-26:card_h-6, card_w-26:card_w-6], + val[6:26, card_w-26:card_w-6], val[card_h-26:card_h-6, 6:26]], + axis=0).astype('uint8') + + val_center_box = val[y+h/2-10:y+h/2+10, x+w/2-10:x+w/2+10] + + val_diff = cv2.absdiff(val_bg_box, val_center_box) + val_mean = np.mean(val_diff) + val_std = np.std(val_diff) + + # get a 20x20 hue square from each of the corners of the card, average values + hue_bg = np.mean([ + hue[6:26, 6:26], hue[card_h-26:card_h-6, card_w-26:card_w-6], + hue[6:26, card_w-26:card_w-6], hue[card_h-26:card_h-6, 6:26]]) + + # get a 12x12 square from the center of the shape, average values + hue_center = np.mean(hue[y+h/2-10:y+h/2+10, x+w/2-10:x+w/2+10]) + + # guess texture based on ratio of inside to outside hues + hue_ratio = max(hue_bg, hue_center) / min(hue_bg, hue_center) + + print "{}\t{}\t{}".format(val_std, hue_ratio, val_mean) + + if val_mean > 35 or hue_ratio > 5: + return sc.PROP_TEXTURE_SOLID + elif val_mean > 10: + return sc.PROP_TEXTURE_STRIPED + elif val_mean < 3: + return sc.PROP_TEXTURE_EMPTY + elif hue_ratio > 2: + return sc.PROP_TEXTURE_STRIPED + else: + return sc.PROP_TEXTURE_EMPTY + def get_shape_from_contour(contour, contour_box): # uppack bounding box of contour x, y, w, h = contour_box @@ -496,11 +532,12 @@ def get_card_properties_v2(card, debug=False): x, y, w, h = contour_boxes[0] hue_crop = hue[y:y+h, x:x+w] - #prop_num = get_number_from_contours(contour_areas, contour_centers) - prop_num = get_dropoff([b[2]*b[3] for b in contour_boxes], maxratio=1.2) + # no more than 3 shapes per card + prop_num_init = get_dropoff([b[2]*b[3] for b in contour_boxes], maxratio=1.2) + prop_num = ( prop_num_init if prop_num_init < 3 else 3 ) prop_col = get_color_from_hue(hue_crop) prop_shp = get_shape_from_contour(contours[0], contour_boxes[0]) - prop_tex = get_texture_from_hue(hue, contour_boxes[0]) + prop_tex = get_texture_from_hue_val(hue, val, contour_boxes[0]) if debug: pretty_print_properties([(prop_num, prop_col, prop_shp, prop_tex)]) @@ -516,6 +553,6 @@ def get_cards_properties(cards): for card in cards: p = get_card_properties_v2(card) if None not in p: - properties.append(p) + properties.append(p) - return properties \ No newline at end of file + return properties