def get_starting_pot(self, game_area_image_array): pot_image_array = cfg.STARTING_POT_AREA.clip_2d_array(game_area_image_array) pot_image_grey_array = rgb_yx_array_to_grayscale(pot_image_array) digit_contours = find_contours(grey_array=pot_image_grey_array, **cfg.POT_CONTOUR_CONFIG, display=False ) digit_contours = list(digit_contours) # display_image_with_contours(pot_image_grey_array, [c.points_array for c in digit_contours]) starting_pot_value = self._digit_contours_to_integer(digit_contours) # display_image_with_contours(pot_image_grey_array, [digit_contours[2].points_array] + # # [x[1].points_array for x in self.training_data if x[0] in [9,0]]) if starting_pot_value is None: starting_pot_value = 0 return starting_pot_value
def get_hero_chips_remaining(self, game_area_image_array): chips_image_array = cfg.HERO_REMAINING_CHIPS_AREA.clip_2d_array(game_area_image_array) #display_image_with_contours(chips_image_array, contours=[]) chips_image_grey_array = rgb_yx_array_to_grayscale(chips_image_array) digit_group_contours = find_contours(grey_array=chips_image_grey_array, **cfg.CHIPS_REMAINING_DIGIT_GROUPS_CONTOUR_CONFIG, display=False ) digit_group_contours = list(digit_group_contours) if False: display_image_with_contours(chips_image_grey_array, [c.points_array for c in digit_group_contours]) chips_image_grey_array = self.add_spaces_to_digits( image_grey_array=chips_image_grey_array, digit_group_contours=digit_group_contours ) digit_contours = find_contours(grey_array=chips_image_grey_array, **cfg.CHIPS_REMAINING_DIGIT_CONTOUR_CONFIG, display=False ) digit_contours = list(digit_contours) chips_remaining = self._digit_contours_to_integer(digit_contours) logger.info(f"Chips remaining: {chips_remaining}") if False: display_image_with_contours(chips_image_grey_array, [c.points_array for c in digit_contours]) return chips_remaining
def get_suit_and_number(card_grey_image_array, has_2_cards=False, clip_bottom=True, display=False): """ :param image: :return: Suit card contour object and number card contour object """ grey_array = card_grey_image_array if not has_2_cards and clip_bottom: # chips can cover up bottom grey_array = grey_array[0:28, :] card_contours = list(find_contours( grey_array=grey_array, min_width=5, max_width=15, display=display )) if display: display_image_with_contours(grey_array, [c.points_array for c in card_contours]) if has_2_cards: # pass sorted_by_x = sorted(card_contours, key=lambda c: c.bounding_box.min_x) if has_2_cards: if len(sorted_by_x) < 4: logger.warning("Not enough images for hole cards") # display_image_with_contours(grey_array, [c.contour for c in card_contours]) return None, None, None, None sorted_contours_1 = sorted(sorted_by_x[0:2], key=lambda c: c.bounding_box.min_y) sorted_contours_2 = sorted(sorted_by_x[-2:], key=lambda c: c.bounding_box.min_y) #display_image_with_contours(grey_array, [c.points_array for c in sorted_contours_1]) # suit, number return sorted_contours_1[1], sorted_contours_1[0], sorted_contours_2[1], sorted_contours_2[0] else: if len(sorted_by_x) < 2: logger.warning("Not enough images for cards") #display_image_with_contours(grey_array, [c.contour for c in card_contours]) return None, None sorted_by_y = sorted(sorted_by_x[0:2], key=lambda c: c.bounding_box.min_y) return sorted_by_y[1], sorted_by_y[0]
def find_common_cards(screenshot_rgb_yx_array, card_classifier, gi): #image = cv2.imread(screenshot_file_path) #image = cv2.cvtColor(screenshot_rgb_yx_array, cv2.COLOR_RGB2BGR) bw = rgb_yx_array_to_grayscale(screenshot_rgb_yx_array[125:190, 240:550]) # NOTE: its img[y: y + h, x: x + w] and *not* img[x: x + w, y: y + h] if False: cv2.imshow('image', bw) cv2.waitKey(0) cv2.destroyAllWindows() # display_cv2_image_with_contours(image, []) #bw = get_black_and_white_image(image) #cnts = find_contours_with_cv(bw) cnts = find_contours(bw, min_width=cfg.CARD_WIDTH_PIXELS - 5, max_width=cfg.CARD_WIDTH_PIXELS + 15, min_height=cfg.CARD_HEIGHT_PIXELS - 15, max_height=cfg.CARD_HEIGHT_PIXELS + 15, display=False) contours_list = list(cnts) #display_image_with_contours(bw, [c.points_array for c in contours_list]) image_array = bw # loop over the contours individually for idx, contour in enumerate(contours_list): y = contour.bounding_box crop_img = contour.bounding_box.clip_2d_array(image_array) #card_image = Image.fromarray(crop_img) c = card_classifier.evaluate_card(crop_img) logger.info( f"Classified extracted image #{idx} as {card_classifier.get_card_string(c)}" ) if c is not None: gi.common_cards.append(c)
def train_numbers(self, file_path, hero_numbers): image_array = get_game_area_as_2d_array(file_path) # display_image_with_contours(image_array, []) hero_bet_array = cfg.HERO_BETTING_AREA.clip_2d_array(image_array) hero_bet_grey_array = rgb_yx_array_to_grayscale(hero_bet_array) hero_bet_grey_array[hero_bet_grey_array >= 121] = 255 contour_list = find_contours(grey_array=hero_bet_grey_array, **cfg.OTHER_PLAYER_BET_CONTOUR_CONFIG ) sorted_contours = sorted(contour_list, key=lambda x: x.bounding_box.min_x) # display_image_with_contours(hero_bet_grey_array, [c.points_array for c in sorted_contours]) self.training_data.extend(zip(hero_numbers, sorted_contours))
def get_bets(self, game_area_image_array): bet_image_array = cfg.BETS_AREA.clip_2d_array(game_area_image_array) #display_image_with_contours(bet_image_array, []) # get just green component # display_image_with_contours(bet_image_array, []) # Basically we just want green things, so... # take max of red and blue columns (indexs 0 and 2) max_red_blue_value = np.max(bet_image_array[:, :, [0, 2]], axis=2) # build a boolean array of green values that are less than the max of red or blue cond = bet_image_array[:, :, 1] < max_red_blue_value # for those pixels where green not the max, set it to 0, otherwise subtract the max bet_image_array[:, :, 1] = np.where(cond, 0, bet_image_array[:, :, 1] - max_red_blue_value) # now we just have a picture of green things image_array = bet_image_array[:, :, 1].copy() bet_bubbles = find_contours(grey_array=image_array, min_width=30, max_width=100, min_height=9, # Sometimes green chips can make height larger max_height=35, display=False ) bet_bubbles = sorted(bet_bubbles, key=lambda x: x.bounding_box.min_x) #display_image_with_contours(image_array, [b.points_array for b in bet_bubbles]) all_bets = [0] * 5 center_bet_area_yx = bet_image_array.shape[0] / 2, bet_image_array.shape[1] / 2 for contour in bet_bubbles: # logger.info(contour.bounding_box) just_text = contour.bounding_box.clip_2d_array(image_array) center_bet_yx = list(contour.bounding_box.center_yx()) center_bet_yx[0] -= center_bet_area_yx[0] center_bet_yx[1] -= center_bet_area_yx[1] player_position = None if abs(center_bet_yx[0]) < 75 and abs(center_bet_yx[1]) < 15: player_position = 0 elif center_bet_yx[0] > 0 and center_bet_yx[1] < 0: player_position = 1 elif center_bet_yx[0] < 0 and center_bet_yx[1] < 0: player_position = 2 elif center_bet_yx[0] < 0 and center_bet_yx[1] > 0: player_position = 3 elif center_bet_yx[0] > 0 and center_bet_yx[1] > 0: player_position = 4 else: raise Exception("cain") # clip off 4 leftmost pixels which are giving false contours just_text_grey_array = just_text[:, 4:] digit_group_contours = find_contours(grey_array=just_text_grey_array, **cfg.OTHER_PLAYER_BET_DIGIT_GROUP_CONFIG, display=False ) digit_group_contours = list(digit_group_contours) #display_image_with_contours(just_text_grey_array, [c.points_array for c in digit_group_contours]) bet_image_grey_array = self.add_spaces_to_digits( image_grey_array=just_text_grey_array, digit_group_contours=digit_group_contours, digit_width=6, fill_color=255 ) digit_contours = find_contours(grey_array=bet_image_grey_array, **cfg.OTHER_PLAYER_BET_CONTOUR_CONFIG, display=False ) digit_contours = list(digit_contours) # display_image_with_contours(bet_image_grey_array, [c.points_array for c in digit_contours]) this_bet_value = self._digit_contours_to_integer(digit_contours) if this_bet_value is not None: logger.info(f"Found bet {this_bet_value}. Players position: {player_position}") logger.debug( "Bet area center: {}. Bet center: {} ".format( center_bet_area_yx, center_bet_yx)) #display_image_with_contours(bet_image_grey_array, [c.points_array for c in digit_contours]) all_bets[player_position] = this_bet_value return all_bets