Ejemplo n.º 1
0
def prepare_image(input_image, logger, options):
    dithered_image = input_image.convert(mode="1", dither=Image.FLOYDSTEINBERG)

    if options.auto_crop:
        bbox = dithered_image.getbbox()
        if bbox is not None:
            dithered_image = dithered_image.crop(bbox)
            size = dithered_image.size
            logger.debug("Cropped image has size: %s" % str(size))

            new_size = fix_size_to_block_multiple(size)
            if new_size != size:
                logger.info("Resizing picture to: %s" % str(new_size))
                new_image = Image.new("1", new_size)
                new_image.paste(dithered_image,
                                box=(0, 0, dithered_image.size[0],
                                     dithered_image.size[1]))
                dithered_image = new_image

        else:
            logger.error("Cannot crop a blank image")

    block_image = BlockImage(dithered_image)
    block_image.deduplicate_blocks()
    return block_image, dithered_image
Ejemplo n.º 2
0
    def test_deduplicated_images_is_unaltered(self):
        input_image = construct_redundant_image()
        im = BlockImage(input_image)
        im.deduplicate_blocks()

        new_image = im.get_image()

        are_images_equal(input_image, new_image)
Ejemplo n.º 3
0
 def test_random_search(self):
     print('\nTests random search for a single block')
     block = BlockImage(1, 1)
     self.assertEqual(block.get_face(), 1)
     self.assertEqual(block.get_pattern(),
                      BlockPattern.BlackTopRightCornerSquare)
     random_search(block, BlockPattern.WhiteSquare, [])
     self.assertEqual(block.get_pattern(), BlockPattern.WhiteSquare)
Ejemplo n.º 4
0
 def test_memory_search(self):
     print('\nTests memory search')
     actions = memory_search(BlockImage(),
                             BlockPattern.BlackTopLeftCornerSquare, [])
     block = BlockImage()
     visited = [(block.get_face(), block.get_pattern())]
     for action in actions:
         block.execute_action(action)
         visited.append((block.get_face(), block.get_pattern()))
     self.assertEqual(block.get_pattern(),
                      BlockPattern.BlackTopLeftCornerSquare)
     self.assertEqual(len(visited), len(set(visited)))
Ejemplo n.º 5
0
    def _setup_puzzle(self):
        self.block = None
        self.image_path = PUZZLE_OPTIONS[self.name]
        self.action_history = []
        self.num_rows, self.num_cols, self.bgr_len = (imread(
            self.image_path).shape)

        # Glance factor presumes that the puzzle is a square
        min_glance_factor = float(BLOCK_LENGTH - 10) / self.num_cols
        if not self.glance_factor >= min_glance_factor:
            raise Exception(
                "Specified glance factor {} must be at least {} to cover one square"
                .format(self.glance_factor, min_glance_factor))

        # Start with a blank slate
        self.image = np.zeros((self.num_rows, self.num_cols, self.bgr_len),
                              np.uint8)

        self.unsolved_pieces = []  # Represents as top left coordinate
        for r in range(0, self.num_rows - EDGE_OFFSET, BLOCK_LENGTH):
            for c in range(0, self.num_cols - EDGE_OFFSET, BLOCK_LENGTH):
                self.unsolved_pieces.append((r, c))

        self.block_bank = [
            BlockImage(1, i + 1, self)
            for i in range(len(self.unsolved_pieces))
        ]

        self.solved_pieces = {piece: None for piece in self.unsolved_pieces}
        self.puzzle_memory_loss_counter = 0
Ejemplo n.º 6
0
    def test_blocks_are_cut_from_input_image(self):
        input_image = construct_test_image()
        im = BlockImage(input_image)

        list_of_ones = [(0, 0), (7, 0), (1, 0), (6, 0), (2, 0), (5, 0)]

        for block_index in range(im.block_count):
            block_to_test = im.blocks[block_index]

            self.assertEqual(block_to_test.size, (BLOCK_WIDTH, BLOCK_HEIGHT),
                             "Block %i" % (block_index, ))
            self.assertEqual(block_to_test.mode, "1",
                             "Block %i" % (block_index, ))

            for y in range(BLOCK_HEIGHT):
                for x in range(BLOCK_WIDTH):
                    pixel = block_to_test.getpixel((x, y))
                    if (x, y) == list_of_ones[block_index]:
                        self.assertEqual(
                            pixel, 1,
                            "Coordinates %i (%i, %i)" % (block_index, x, y))
                    else:
                        self.assertEqual(
                            pixel, 0,
                            "Coordinates %i (%i, %i)" % (block_index, x, y))
    def test_basic_outputs_index_data(self):
        im = BlockImage(construct_redundant_image())
        basic = ImageToBasic(im)

        found_data = False
        for line in basic:
            if "DATA 32,32,33,33,34,34" in line:
                found_data = True

        self.assertTrue(found_data, "DATA section was not found")
Ejemplo n.º 8
0
 def test_beeline_search_complex(self):
     print('\nTests beeline search, complex sequence')
     actions = beeline_search(BlockImage(3),
                              BlockPattern.BlackTopLeftCornerSquare, [])
     block = BlockImage(3)
     self.assertEqual(block.get_pattern(), BlockPattern.WhiteSquare)
     self.assertTrue(len(actions) == 2)
     for action in actions:
         block.execute_action(action)
     self.assertEqual(block.get_pattern(),
                      BlockPattern.BlackTopLeftCornerSquare)
Ejemplo n.º 9
0
 def test_random_search(self):
     print('\nTests random search')
     actions = random_search(BlockImage(),
                             BlockPattern.BlackTopLeftCornerSquare, [])
     block = BlockImage()
     for action in actions:
         block.execute_action(action)
     self.assertEqual(block.get_pattern(),
                      BlockPattern.BlackTopLeftCornerSquare)
Ejemplo n.º 10
0
 def test_peek(self):
     print('\nTests peek')
     block = BlockImage(6)
     self.assertEqual(block.get_pattern(),
                      BlockPattern.BlackBottomRightCornerSquare)
     self.assertEqual(block.peek_action(BlockAction.RotateRight),
                      (6, BlockPattern.BlackBottomLeftCornerSquare))
     self.assertEqual(block.peek_action(BlockAction.RotateLeft),
                      (6, BlockPattern.BlackTopRightCornerSquare))
     self.assertEqual(block.peek_action(BlockAction.GoToFaceThree),
                      (3, BlockPattern.WhiteSquare))
     with self.assertRaises(Exception) as context:
         block.peek_action(BlockAction.GoToFaceOne)
     self.assertEqual(
         str(context.exception),
         "Invalid action BlockAction.GoToFaceOne for " +
         "Block,1,Face,6,Pattern,BlackBottomRightCornerSquare")
Ejemplo n.º 11
0
    def test_invalid_sequence(self):
        print('\nTests invalid block sequence')
        block = BlockImage()
        self.assertEqual(block.get_face(), 1)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackTopRightCornerSquare)

        with self.assertRaises(Exception) as context:
            block.execute_action(BlockAction.GoToFaceSix)
        self.assertEqual(str(context.exception), "Can't go from 1 to 6")
Ejemplo n.º 12
0
    def test_basic_centers_the_image(self):
        im = BlockImage(construct_redundant_image())
        basic = ImageToBasic(im)

        found_x_cursor_shift = False
        found_y_cursor_shift = False

        x_cursor_shift = "CURSORX X+19"
        y_cursor_shift = "CURSORY Y+11"

        for line in basic:
            if x_cursor_shift in line:
                found_x_cursor_shift = True
            if y_cursor_shift in line:
                found_y_cursor_shift = True

        self.assertTrue(found_x_cursor_shift, "cursor shift for X not found")
        self.assertTrue(found_y_cursor_shift, "cursor shift for Y not found")
Ejemplo n.º 13
0
    def test_basic_contains_loops_for_blocks(self):
        im = BlockImage(construct_redundant_image())
        basic = ImageToBasic(im)

        found_x_loop = False
        found_y_loop = False

        x_loop = "FOR X=0 TO 1"
        y_loop = "FOR Y=0 TO 2"

        for line in basic:
            if x_loop in line:
                found_x_loop = True
            if y_loop in line:
                found_y_loop = True

        self.assertTrue(found_x_loop, "for loop for X not found")
        self.assertTrue(found_y_loop, "for loop for Y not found")
Ejemplo n.º 14
0
    def test_reduce_blocks_removes_duplicates(self):
        input_image = construct_redundant_image()
        im = BlockImage(input_image)

        self.assertEqual(im.block_count, 6)
        self.assertEqual(im.get_unique_block_count(), 6)

        im.deduplicate_blocks()

        self.assertEqual(im.blocks[0], im.blocks[1])
        self.assertNotEqual(im.blocks[1], im.blocks[2])
        self.assertEqual(im.blocks[2], im.blocks[3])
        self.assertNotEqual(im.blocks[3], im.blocks[4])
        self.assertEqual(im.blocks[4], im.blocks[5])
        self.assertEqual(im.get_unique_block_count(), 3)
Ejemplo n.º 15
0
    def test_basic_outputs_encoded_blocks(self):
        im = BlockImage(construct_redundant_image())
        basic = ImageToBasic(im)

        character_count = 0
        found_char_1 = False
        found_char_2 = False
        found_char_3 = False

        for line in basic:
            if "SETEG " in line:
                character_count += 1
            if "80000000000000000000" in line:
                found_char_1 = True
            if "40000000000000000000" in line:
                found_char_2 = True
            if "00100000000000000000" in line:
                found_char_3 = True

        self.assertEqual(3, character_count)
        self.assertTrue(found_char_1, "Did not found Encoded Character 1")
        self.assertTrue(found_char_2, "Did not found Encoded Character 2")
        self.assertTrue(found_char_3, "Did not found Encoded Character 3")
Ejemplo n.º 16
0
 def test_block_image_asks_for_input_image(self):
     input_image = Image.new("1", (16, 30))
     im = BlockImage(input_image)
     self.assertEqual(im.size, (16, 30))
     self.assertEqual(im.block_size, (2, 3))
     self.assertEqual(im.block_count, 6)
Ejemplo n.º 17
0
    def test_complex_sequence(self):
        print('\nTests block complex sequence')
        block = BlockImage()
        self.assertEqual(block.get_face(), 1)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackTopRightCornerSquare)

        block.execute_action(BlockAction.GoToFaceFour)
        self.assertEqual(block.get_face(), 4)
        self.assertEqual(block.get_pattern(), BlockPattern.BlackSquare)

        block.execute_action(BlockAction.GoToFaceThree)
        self.assertEqual(block.get_face(), 3)
        self.assertEqual(block.get_pattern(), BlockPattern.WhiteSquare)

        block.execute_action(BlockAction.RotateRight)
        self.assertEqual(block.get_face(), 3)
        self.assertEqual(block.get_pattern(), BlockPattern.WhiteSquare)

        block.execute_action(BlockAction.GoToFaceOne)
        self.assertEqual(block.get_face(), 1)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackBottomRightCornerSquare)

        block.execute_action(BlockAction.GoToFaceFive)
        self.assertEqual(block.get_face(), 5)
        self.assertEqual(block.get_pattern(), BlockPattern.BlackSquare)

        block.execute_action(BlockAction.GoToFaceSix)
        self.assertEqual(block.get_face(), 6)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackBottomLeftCornerSquare)

        block.execute_action(BlockAction.RotateRight)
        self.assertEqual(block.get_face(), 6)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackTopLeftCornerSquare)

        block.execute_action(BlockAction.GoToFaceThree)
        self.assertEqual(block.get_face(), 3)
        self.assertEqual(block.get_pattern(), BlockPattern.WhiteSquare)

        block.execute_action(BlockAction.GoToFaceOne)
        self.assertEqual(block.get_face(), 1)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackBottomLeftCornerSquare)

        block.execute_action(BlockAction.RotateLeft)
        self.assertEqual(block.get_face(), 1)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackBottomRightCornerSquare)
Ejemplo n.º 18
0
    def test_simple_sequence_two(self):
        print('\nTests simple sequence two')
        block = BlockImage()
        self.assertEqual(block.get_face(), 1)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackTopRightCornerSquare)

        block.execute_action(BlockAction.RotateRight)
        self.assertEqual(block.get_face(), 1)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackBottomRightCornerSquare)

        block.execute_action(BlockAction.GoToFaceFour)
        self.assertEqual(block.get_face(), 4)
        self.assertEqual(block.get_pattern(), BlockPattern.BlackSquare)

        block.execute_action(BlockAction.GoToFaceSix)
        self.assertEqual(block.get_face(), 6)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackBottomLeftCornerSquare)
Ejemplo n.º 19
0
    def test_beeline_search_rotations(self):
        print('\nTests beeline search, rotations')
        actions = beeline_search(BlockImage(),
                                 BlockPattern.BlackTopLeftCornerSquare, [])
        block = BlockImage()
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackTopRightCornerSquare)
        self.assertEqual(len(actions), 1)
        block.execute_action(actions[0])
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackTopLeftCornerSquare)

        actions = beeline_search(BlockImage(),
                                 BlockPattern.BlackBottomLeftCornerSquare, [])
        block = BlockImage()
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackTopRightCornerSquare)
        # Since beeline search is somewhat stochastic, these test rely on heuristics
        self.assertEqual(len(actions), 2)
        for action in actions:
            block.execute_action(action)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackBottomLeftCornerSquare)
Ejemplo n.º 20
0
    def test_basic_first_line_is_10(self):
        im = BlockImage(construct_redundant_image())
        basic = ImageToBasic(im)

        all_lines = "\n".join(basic)
        self.assertEqual("10 ", all_lines[:3])
Ejemplo n.º 21
0
    def test_simple_sequence_one(self):
        print('\nTests simple block sequence one')
        block = BlockImage()
        self.assertEqual(block.get_face(), 1)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackTopRightCornerSquare)

        block.execute_action(BlockAction.GoToFaceFour)
        self.assertEqual(block.get_face(), 4)
        self.assertEqual(block.get_pattern(), BlockPattern.BlackSquare)

        block.execute_action(BlockAction.GoToFaceFive)
        self.assertEqual(block.get_face(), 5)
        self.assertEqual(block.get_pattern(), BlockPattern.BlackSquare)

        block.execute_action(BlockAction.GoToFaceOne)
        self.assertEqual(block.get_face(), 1)
        self.assertEqual(block.get_pattern(),
                         BlockPattern.BlackTopRightCornerSquare)
Ejemplo n.º 22
0
 def test_image_to_basic_takes_a_block_image(self):
     im = BlockImage(construct_redundant_image())
     basic = ImageToBasic(im)
     self.assertGreater(basic.get_line_count(), 0)