def display(self, worksheet, sorted_contours): contours = sorted_contours for i, contour in enumerate(contours): app = Helpers.approx(contour, 0.05) rect = Helpers.get_rectangle_corners(app) font_face = Helpers.font("Hershey") font_scale = 1.5 thickness = 3 text_size = Helpers.text_size(str(self.answer_key[i]), font_face, font_scale, thickness) text_x = int(rect[0][0] - text_size[0][0]) - 20 text_y = int(rect[3][1]) - 10 if self.marks[i] == "correct": contour_color = Helpers.BGR_COLORS["GREEN"] text_color = Helpers.BGR_COLORS["DARK GREEN"] elif self.marks[i] == "unknown": contour_color = Helpers.BGR_COLORS["YELLOW"] text_color = Helpers.BGR_COLORS["BLACK"] else: contour_color = Helpers.BGR_COLORS["RED"] text_color = Helpers.BGR_COLORS["DARK RED"] Helpers.draw_text(worksheet, str(self.answer_key[i]), (text_x, text_y), font_face, font_scale, \ text_color, thickness) Helpers.draw_contour(worksheet, contour, contour_color) Helpers.show(worksheet, 'graded') return worksheet
def __init__(self, path, show_steps=False, save=False): self.image = Helpers.load_image(path) # build the prepocessing pipleine pipeline = Pipeline([ Helpers.convert_to_grayscale, lambda image: Helpers.blur(image, 5), Helpers.thresholdify, Helpers.ellipse_morph ]) processed_image = pipeline.process_pipeline(self.image) # get the contour, crop it out, find the corners and straighten contour = Helpers.largest_contour(processed_image) processed_image_cropped = Helpers.cut_out_rect(processed_image, contour) corners = Helpers.get_corners(processed_image_cropped) # apply the same cropping and warping to the original image image_cropped = Helpers.cut_out_rect(self.image, contour) straigtened_image = Helpers.warp_perspective(corners, image_cropped) if show_steps: Helpers.show(processed_image, 'Preprocessing') Helpers.show(processed_image_cropped, 'Processed image cropped') Helpers.show(image_cropped, 'Original image cropped') Helpers.show(straigtened_image, 'Final image') self.final = straigtened_image if save: Helpers.save_image( f'{Helpers.IMAGE_DIRECTORY}/extractor_finish.png', self.final) return None
def __init__(self, image, show_steps=False): self.image = image self.show_steps = show_steps processed_image = self.process_image() self.cells = self.extract_cells(processed_image, self.image) student_responses = self.get_student_responses() if show_steps: Helpers.show(self.image, "start") Helpers.show(processed_image, "processed") self.student_responses = student_responses
def extract_cells(self, processed, display_image, count=14): ''' Extract a given amount of cells from the worksheet. This function assumes that the cells are 0.0016 +- 0.0004 of the total worksheet size. Parameters ---------- processed: np.ndarray Thresholded image of the worksheet display_image: np.ndarray BGR image of the worksheet count: int The number of image Return value ---------- returns a list of cells sorted by height and then by position ''' page_area = Helpers.area(processed) min_percent = 0.0012 max_percent = 0.0020 contours = Helpers.get_sorted_contours(processed, sort_by="area") contours = Helpers.filter_contours(contours, sides=[4], min_area=page_area*min_percent, \ max_area=page_area*max_percent) # get just the count biggest contours contours = contours[:count] rects = [] for contour in contours: rects.append(Helpers.cut_out_rect(display_image, contour)) sorted_rects, sorted_contours = self.sort_by_problem_num( rects, contours) self.sorted_contours = sorted_contours if self.show_steps: for i, rect in enumerate(sorted_rects): Helpers.show(rect, str(i + 1)) return sorted_rects
def show(name=None, platform=None, priorities=None, genres=None): """Show pile games, with optional filtering.""" db = helpers.read_db() if len(db.games) == 0: raise CommandError('No games found. Use the `add` command to add some.') gs = db.search(name=name, platform=platform, priorities=priorities, genres=genres) for line in helpers.show(gs): yield line
def rm(name): """Remove a pile game""" db = helpers.read_db() gs = db.search(exact_name=name) if len(gs) == 0: raise CommandError("No games found") g = gs[0] db.games.remove(g) yield "Removing game from pile" for line in helpers.show([g]): yield line helpers.write_db(db)
def add(name, platform, on_pile_date=datetime.date.today().isoformat(), priority = PRIORITY_MED, hours = 10, genres = []): """Add a pile game""" db = helpers.read_db() if len(db.search(exact_name=name)) > 0: raise CommandError("A game with that name already exists") g = PileGame(name, platform, on_pile_date, priority, hours, genres) db.games.append(g) helpers.write_db(db) yield "Added game to pile" for line in helpers.show([g]): yield line
def edit(name, platform = None, rename = None, on_pile_date=None, priority = None, hours = None, genres = None): """Edit a pile game""" db = helpers.read_db() gs = db.search(exact_name=name) if len(gs) == 0: raise CommandError("No games found") g = gs[0] if rename: g.name = rename if platform: g.platform = platform if hours: g.hours = hours if priority: g.priority = priority if on_pile_date: g.on_pile_date = on_pile_date if genres: g.genres = genres yield "Game updated" for line in helpers.show([g]): yield line helpers.write_db(db)
def game_loop(): construct_graph() quit = False char = Character.Character(100, 1, 1, "", pygame.image.load('art/hero.png'), 100, 100) keys = [] have_red_key = False have_blue_key = False have_black_key = False game_over = False current_chamber = 0 while not quit: if char.health <= 0: game_over = True # event handling for event in pygame.event.get(): if event.type == pygame.QUIT: quit = True # handle key down if event.type == pygame.KEYDOWN: if not game_over: # moving if event.key == pygame.K_a: char.x_change = -10 char.direction = 'left' if event.key == pygame.K_d: char.x_change = 10 char.direction = 'right' if event.key == pygame.K_w: char.y_change = -10 if event.key == pygame.K_s: char.y_change = 10 # using weapon if event.key == pygame.K_p: if char.direction == 'left': char.show_weapon_left = True if char.direction == 'right': char.show_weapon_right = True # quit game if event.key == pygame.K_ESCAPE: quit = True if event.key == pygame.K_RETURN and game_over: # reset them game construct_graph() current_chamber = 0 char.reset() keys = [] have_black_key = False have_red_key = False have_blue_key = False game_over = False # if a key is used on a door add the key to the door buffer # use red key if event.key == pygame.K_1: for door in graph.chambers[current_chamber].doors: if collided(char.x, char.y, char.img_w, char.img_h, door.x, door.y, door.width + 100, door.height + 100) and have_red_key: door.add_to_door_buffer(str(1)) for npc in graph.chambers[current_chamber].npcs: if collided(char.x, char.y, char.img_w, char.img_h, npc.x, npc.y, npc.img_w + 50, npc.img_h + 50) and have_red_key: npc.add_to_spell_buffer(str(1), char) # use blue key if event.key == pygame.K_2: for door in graph.chambers[current_chamber].doors: if collided(char.x, char.y, char.img_w, char.img_h, door.x, door.y, door.width + 100, door.height + 100) and have_blue_key: door.add_to_door_buffer(str(2)) for npc in graph.chambers[current_chamber].npcs: if collided(char.x, char.y, char.img_w, char.img_h, npc.x, npc.y, npc.img_w + 50, npc.img_h + 50) and have_blue_key: npc.add_to_spell_buffer(str(2), char) # use black key if event.key == pygame.K_3: for door in graph.chambers[current_chamber].doors: if collided(char.x, char.y, char.img_w, char.img_h, door.x, door.y, door.width + 100, door.height + 100) and have_black_key: door.add_to_door_buffer(str(3)) for npc in graph.chambers[current_chamber].npcs: if collided(char.x, char.y, char.img_w, char.img_h, npc.x, npc.y, npc.img_w + 50, npc.img_h + 50) and have_black_key: npc.add_to_spell_buffer(str(3), char) if event.key == pygame.K_o: char.use_spell() # handle key release if event.type == pygame.KEYUP: # stop moving if event.key == pygame.K_a or event.key == pygame.K_d: char.x_change = 0 if event.key == pygame.K_w or event.key == pygame.K_s: char.y_change = 0 # don't show weapon if event.key == pygame.K_p: char.show_weapon_left = False char.show_weapon_right = False # don't let user outside the screen if character_in_bounds(char): char.x += char.x_change char.y += char.y_change # change background colour depending on chamber we're in game_display.fill( (13 * (current_chamber + 1), 12 * (current_chamber + 1), 11 * (current_chamber + 1))) # show all doors in current chamber for door in graph.chambers[current_chamber].doors: show(door.x, door.y, door.door_img) # if user collides with the door and can pass through put them where they should be in the next chamber if collided(char.x, char.y, char.img_w, char.img_h, door.x, door.y, door.width, door.height) and door.can_pass(): current_chamber = door.destination if door.number == 1: char.x = 200 char.y = display_height / 2 elif door.number == 2: char.x = display_width / 2 char.y = 200 elif door.number == 3: char.x = display_width - 200 char.y = display_height / 2 elif door.number == 4: char.x = display_width / 2 char.y = display_height - 200 # if user failed to open door flash if door.failed_attempt and door.locked: door.door_flash = True door.flash_timer = 0 door.failed_attempt = False if door.door_flash: door.flash_timer += 1 if door.flash_timer == 10: if door.number % 2 == 0: door.door_img = pygame.image.load('art/door0.jpg') else: door.door_img = pygame.image.load('art/door.jpg') # show all tidabites in current chamber for tida in graph.chambers[current_chamber].tidas: if tida.health > 0: show(tida.x, tida.y, tida.tida_img) tida.chase(char) # if user collides with tidabite the user takes damage if collided(char.x, char.y, char.img_w, char.img_h, tida.x, tida.y, tida.img_w, tida.img_h): if char.x < tida.x: char.x += -15 elif char.x >= tida.x: char.x += 15 char.health += -ceil(tida.damage / char.armour) # if tidabite get hit by user's weapon it takes damage if collided(char.x - 50, char.y + 25, 50, 50, tida.x, tida.y, tida.img_w, tida.img_h) and char.show_weapon_left: tida.x += -15 tida.health += -char.attack if collided(char.x + 100, char.y + 25, 50, 50, tida.x, tida.y, tida.img_w, tida.img_h) and char.show_weapon_right: tida.x += 15 tida.health += -char.attack else: # remove from chamber if it's dead graph.chambers[current_chamber].tidas.remove(tida) # show all chests in the current chamber for chests in graph.chambers[current_chamber].chests: show(chests.x, chests.y, chests.chest_img) # if a user collides with a chest spill its contents into the chamber if collided(char.x, char.y, char.img_w, char.img_h, chests.x, chests.y, 100, 100): for x in chests.items: graph.chambers[current_chamber].items.append(x) chests.chest_img = pygame.image.load('art/emptyChest.png') chests.items.remove(x) # show all items in the current chamber for item in graph.chambers[current_chamber].items: show(item.x, item.y, item.item_img) # if user collides with an item handle various types of items if collided(char.x, char.y, char.img_w, char.img_h, item.x, item.y, item.img_w, item.img_h): if item.type == 'weapon': char.attack += item.stat char.new_weapon(item) elif item.type == 'armour': char.armour += item.stat char.new_armour(item.item_img) elif item.type == 'key': keys.append(item) graph.chambers[current_chamber].items.remove(item) # show keys if player has them for key in keys: if key.stat == 1: show(display_width - 400, 0, key.item_img) have_red_key = True if key.stat == 2: show(display_width - 300, 0, key.item_img) have_blue_key = True if key.stat == 3: show(display_width - 200, 0, key.item_img) have_black_key = True # show NPCs for npc in graph.chambers[current_chamber].npcs: show(npc.x, npc.y, npc.npc_img) # if the player collides with NPC show dialog if collided(char.x, char.y, char.img_w, char.img_h, npc.x, npc.y, npc.img_w + 50, npc.img_h + 50): show(display_width / 2 - 400, display_height / 2 - 100, npc.dialog_img) # show current attack, armour, and health show_text( f'attack: {char.attack} armour: {char.armour} health: {char.health}', 300, 50) # show character show(char.x, char.y, char.char_img) # show weapon on either side of character if it should be displayed if char.show_weapon_left and char.weapon_img_left is not None: show(char.x - 50, char.y + 25, char.weapon_img_left) elif char.show_weapon_right and char.weapon_img_right is not None: show(char.x + 100, char.y + 25, char.weapon_img_right) if game_over: show_text('Game OVER', display_width / 2, display_height / 2) show_text('Enter to play again', display_width / 2, display_height / 2 + 300) pygame.display.flip() clock.tick(60)