Пример #1
0
    def __init__(self):
        self.lines = None
        self.score = None
        self.level = None
        self.start_level = None
        self.field = None
        self.preview = None
        self.gameid = 0
        self.piece_stats = PieceStatAccumulator()
        self.gamestate = GameState.MENU
        self.cur_piece = None
        self.cur_piece_das = None
        self.instant_das = None
        self.current_time = 0
        self.line_clear_anim = None
        self.colors = Colors()

        # initialize palette
        palette_name = config["calibration.palette"]

        try:
            with open("nestris_ocr/palettes/%s.json" % (palette_name, ),
                      "r") as file:
                palette = json.load(file)
                self.colors.setPalette(palette)

        except ValueError:
            print("Warning: Unable to load palette %s" % (palette_name, ))
Пример #2
0
class FieldView(ImageCanvas):
    def __init__(self, root, width, height):
        super().__init__(root, width, height)
        self.color_table = Colors()
        self.current_level = None
        self.color_table.setLevel(0)

    def updateField(self, field, level):
        success, level = tryGetInt(level)
        if success and level != self.current_level:
            self.color_table.setLevel(level)

        field = convert_field(field)

        lut = np.array(self.color_table.colors)
        image = lut[field]
        # TODO: check out lut.take which might be faster
        image = Image.fromarray(image, "RGB")
        image = image.resize((self.width, self.height), Image.NEAREST)
        self.updateImage(image)
Пример #3
0
 def __init__(self):
     self.lines = None
     self.score = None
     self.level = None
     self.start_level = None
     self.field = None
     self.preview = None
     self.gameid = 0
     self.piece_stats = PieceStatAccumulator()
     self.gamestate = GameState.MENU
     self.cur_piece = None
     self.cur_piece_das = None
     self.instant_das = None
     self.current_time = 0
     self.colors = Colors()
Пример #4
0
def test(method1, method2, level, debug=False):
    print("Comparing %s vs %s" % (method1, method2))
    print("==========")
    print("level %d" % (level,))

    img_field = Image.open(
        "nestris_ocr/assets/sample_inputs/easiercap/lvl%d/field.png" % (level,)
    )
    img_col1 = Image.open(
        "nestris_ocr/assets/sample_inputs/easiercap/lvl%d/color1.png" % (level,)
    )
    img_col2 = Image.open(
        "nestris_ocr/assets/sample_inputs/easiercap/lvl%d/color2.png" % (level,)
    )

    if debug:
        img_field.show()
        img_col1.show()
        img_col2.show()

    # this is how the field is looked at to pick 10x20 unique pixels
    img_field = img_field.resize((10, 20), Image.NEAREST)

    if debug:
        img_field.show()

    getter1 = methods[method1]
    colorsM1 = Colors()
    colorsM1.setColor1Color2(getter1(img_col1), getter1(img_col2))
    print(method1, colorsM1.black, colorsM1.white, colorsM1.color1, colorsM1.color2)

    getter2 = methods[method2]
    colorsM2 = Colors()
    colorsM2.setColor1Color2(getter2(img_col1), getter2(img_col2))
    print(method2, colorsM2.black, colorsM2.white, colorsM2.color1, colorsM2.color2)

    res = getMatchAndDistance(img_field, colorsM1, colorsM2)

    printRes(res, method1, method2)

    return res
Пример #5
0
def runFor(src, level):
    img = Image.open(src)

    scaled_img_old = img.resize((10, 20), Image.NEAREST)

    o_width = img.width + img.height
    o_height = img.height * 2

    result_img = Image.new("RGB", (o_width, o_height), (0, 0, 0, 255))
    result_img.paste(img, (0, 0))
    result_img.paste(img, (0, img.height))

    result_img.paste(
        scaled_img_old.resize((floor(img.height / 2), img.height),
                              Image.NEAREST),
        (img.width, 0),
    )

    scaled_img_new = Image.new("RGB", (10, 20), (0, 0, 0, 255))
    res_img_old = Image.new("RGB", (10, 20), (0, 0, 0, 255))
    res_img_new = Image.new("RGB", (10, 20), (0, 0, 0, 255))

    spanx = img.width / 10
    spany = img.height / 20

    np_img = np.array(img, dtype=np.uint16)

    np_scaled_img = np.array(scaled_img_old, dtype=np.uint8)

    colors = Colors()
    colors.setLevel(level)

    cols = [colors.black, colors.white, colors.color1, colors.color2]

    for y in range(20):
        for x in range(10):
            pix = np_scaled_img[y, x]
            col_old = getColor(pix, cols)
            res_img_old.putpixel((x, y), tuple(cols[col_old]))

            xidx = round(spanx * (x + 0.5))
            yidx = round(spany * (y + 0.5))

            target = np_img[yidx - 1:yidx + 2, xidx - 1:xidx + 2]

            pix = [0, 0, 0]

            # grab 9 pixels in a 3x3 square
            # and compute average
            for i in range(3):
                for j in range(3):
                    tmp = target[i, j]
                    pix[0] += tmp[0] * tmp[0]
                    pix[1] += tmp[1] * tmp[1]
                    pix[2] += tmp[2] * tmp[2]

            pix[0] = int(sqrt(pix[0] / 9))
            pix[1] = int(sqrt(pix[1] / 9))
            pix[2] = int(sqrt(pix[2] / 9))

            col_new = getColor(pix, cols)

            scaled_img_new.putpixel((x, y), tuple(pix))
            res_img_new.putpixel((x, y), tuple(cols[col_new]))

    result_img.paste(
        scaled_img_new.resize((floor(img.height / 2), img.height),
                              Image.NEAREST),
        (img.width, img.height),
    )

    result_img.paste(
        res_img_old.resize((floor(img.height / 2), img.height), Image.NEAREST),
        (img.width + floor(img.height / 2), 0),
    )

    result_img.paste(
        res_img_new.resize((floor(img.height / 2), img.height), Image.NEAREST),
        (img.width + floor(img.height / 2), img.height),
    )

    result_img.show()
Пример #6
0
def runFor(src, level):
    img = Image.open(src)

    scaled_img_old = img.resize((10, 20), Image.NEAREST)

    o_width = img.width + img.height
    o_height = img.height * 2

    result_img = Image.new("RGB", (o_width, o_height), (0, 0, 0, 255))
    result_img.paste(img, (0, 0))
    result_img.paste(img, (0, img.height))

    result_img.paste(
        scaled_img_old.resize((floor(img.height / 2), img.height),
                              Image.NEAREST),
        (img.width, 0),
    )

    scaled_img_new = Image.new("RGB", (10, 20), (0, 0, 0, 255))
    res_img_old = Image.new("RGB", (10, 20), (0, 0, 0, 255))
    res_img_new = Image.new("RGB", (10, 20), (0, 0, 0, 255))

    spanx = img.width / 10
    spany = img.height / 20

    np_img = np.array(img, dtype=np.uint16)

    np_scaled_img = np.array(scaled_img_old, dtype=np.uint8)

    colors = Colors()
    colors.setLevel(level)

    for y in range(20):
        for x in range(10):
            pix = np_scaled_img[y, x]
            col_old = colors.getClosestColorIndex(pix)
            res_img_old.putpixel((x, y),
                                 tuple(colors.getColorByIndex(col_old)))

            xidx = round(spanx * (x + 0.5))
            yidx = round(spany * (y + 0.5))

            pix = [0, 0, 0]

            # grab 9 pixels in a 3x3 square
            # and compute average
            for i in range(xidx - 1, xidx + 2):
                for j in range(yidx - 1, yidx + 2):
                    tmp = np_img[j, i]
                    pix[0] += tmp[0] * tmp[0]
                    pix[1] += tmp[1] * tmp[1]
                    pix[2] += tmp[2] * tmp[2]

            pix[0] = round(sqrt(pix[0] / 9))
            pix[1] = round(sqrt(pix[1] / 9))
            pix[2] = round(sqrt(pix[2] / 9))

            col_new = colors.getClosestColorIndex(pix)

            scaled_img_new.putpixel((x, y), tuple(pix))
            res_img_new.putpixel((x, y),
                                 tuple(colors.getColorByIndex(col_new)))

    result_img.paste(
        scaled_img_new.resize((floor(img.height / 2), img.height),
                              Image.NEAREST),
        (img.width, img.height),
    )

    result_img.paste(
        res_img_old.resize((floor(img.height / 2), img.height), Image.NEAREST),
        (img.width + floor(img.height / 2), 0),
    )

    result_img.paste(
        res_img_new.resize((floor(img.height / 2), img.height), Image.NEAREST),
        (img.width + floor(img.height / 2), img.height),
    )

    result_img.show()
Пример #7
0
class BaseStrategy(object):
    def __init__(self):
        self.lines = None
        self.score = None
        self.level = None
        self.start_level = None
        self.field = None
        self.preview = None
        self.gameid = 0
        self.piece_stats = PieceStatAccumulator()
        self.gamestate = GameState.MENU
        self.cur_piece = None
        self.cur_piece_das = None
        self.instant_das = None
        self.current_time = 0
        self.line_clear_anim = None
        self.colors = Colors()

        # initialize palette
        palette_name = config["calibration.palette"]

        try:
            with open("nestris_ocr/palettes/%s.json" % (palette_name, ),
                      "r") as file:
                palette = json.load(file)
                self.colors.setPalette(palette)

        except ValueError:
            print("Warning: Unable to load palette %s" % (palette_name, ))

    # todo: don't include items not included in config.
    def to_dict(self):
        result = {}
        result["lines"] = dict_zfill(self.lines, 3)
        result["score"] = dict_zfill(self.score, 6)
        result["level"] = dict_zfill(self.level, 2)
        if config["calibration.capture_field"]:
            result["field"] = self.field
        if config["calibration.capture_preview"]:
            result["preview"] = self.preview
        result["gameid"] = self.gameid
        if config["stats.enabled"]:
            result.update(self.piece_stats.toDict())
        if config["calibration.capture_das"]:
            result["cur_piece"] = self.cur_piece
            result["cur_piece_das"] = self.cur_piece_das
            result["instant_das"] = self.instant_das
        if config["calibration.capture_line_clear"]:
            result["line_clear"] = self.line_clear_anim

        return result

    def update(self, timestamp, frame):
        self.current_time = timestamp
        self.current_frame = frame
        if self.gamestate == GameState.MENU:
            is_newgame = self.update_menu()
            if is_newgame:
                self.on_newgame()
        else:
            self.update_ingame()

    def update_menu(self):
        # returns whether we started a new game
        raise NotImplementedError("This is an abstract class, silly")

    def update_ingame(self):
        raise NotImplementedError("This is an abstract class, silly")

    def on_newgame(self):
        self.gameid += 1
Пример #8
0
 def __init__(self, root, width, height):
     super().__init__(root, width, height)
     self.color_table = Colors()
     self.current_level = None
     self.color_table.setLevel(0)
Пример #9
0
        return Piece.T
    if g and o and not b and not r:
        return Piece.L
    if g and not o and not b and r:
        return Piece.J
    if g and o and b and not r:
        return Piece.S
    if not g and not o and b and r:
        return Piece.Z

    if not g and not o and not b and not r and k:
        return Piece.EMPTY
    else:
        return Piece.UNKNOWN


if __name__ == "__main__":
    # run this from root directory as "python -m nestris_ocr.ocr_algo.piece_stats_spawn"
    img = Image.open("nestris_ocr/assets/test/spawn_z.png")
    import time
    from nestris_ocr.colors import Colors

    colors = Colors()

    iterations = 100000

    t = time.time()
    for i in range(iterations):
        parseImage(img, colors)
    print(time.time() - t, (time.time() - t) / iterations)
Пример #10
0
def getColors(level, field):
    img = Image.open(field)

    res_img = Image.new(
        "RGBA",
        (img.width, img.height),
        (0, 0, 0, 255),
    )

    res_img.paste(img.convert("RGBA"), (img.width * 0, 0))

    # nes pix size, block span and capture are only valid on perfect calibration
    # perfect calibration implies capturing the right and bottom black edges
    # still, since we're capturing a safe zone, things should still work with small discrepancies

    nes_pixels_to_sample = (
        (2, 4.5),
        (4.5, 2),
        (4.5, 4.5),
    )

    nes_pix_xsize = img.width / 80
    nes_pix_ysize = img.height / 160

    spanx = nes_pix_xsize * 8
    spany = nes_pix_ysize * 8

    corner_highlight = Image.new("RGBA", (1, 1), (255, 0, 0, 128))
    capture_highlight = Image.new("RGBA", (1, 1), (0, 255, 0, 128))

    np_img = np.array(img, dtype=np.uint16)

    colors = Colors()
    colors.setLevel(level)

    color_instances = ([], [], [], [])

    for y in range(20):
        for x in range(10):
            xidx = spanx * x
            yidx = spany * y

            # print the top-left corner
            res_img.paste(corner_highlight, (round(xidx), round(yidx)),
                          corner_highlight)

            pixels = []

            for offsetx, offsety in nes_pixels_to_sample:
                right = round(xidx + nes_pix_xsize * offsetx)
                top = round(yidx + nes_pix_ysize * offsety)
                left = round(xidx + nes_pix_xsize * (offsetx + 1))
                bottom = round(yidx + nes_pix_ysize * (offsety + 1))

                cap = capture_highlight.resize((left - right, bottom - top))

                res_img.paste(cap, (right, top), cap)

                # grab all pixels in the capture area
                for i in range(right, left):
                    for j in range(top, bottom):
                        pixels.append(np_img[j, i])

            pix = getAverageColor(pixels)

            col_index = colors.getClosestColorIndex(pix)

            color_instances[col_index].extend(pixels)

    if level == 0:
        res_img.convert("RGB").resize((img.width * 3, img.height * 3)).show()

    # average the colors
    col1 = getAverageColor(color_instances[2])
    col2 = getAverageColor(color_instances[3])

    return col1, col2
Пример #11
0

# expecting all 4 colors as np.array(dtype=np.uint8)
def parseImage(img, colors):
    img = np.array(img, dtype=np.uint8)

    return parseImage2(img, colors.black, colors.white, colors.color1,
                       colors.color2)


if __name__ == "__main__":
    # run this from root directory as "python -m nestris_ocr.ocr_algo.board"
    from nestris_ocr.colors import Colors
    import nestris_ocr.utils.time as time

    img = Image.open("nestris_ocr/assets/test/board_lvl7.png")

    colors = Colors()
    colors.setLevel(7)

    iterations = 25000

    start = time.time()
    for i in range(iterations):
        parseImage(img, colors)

    elapsed = time.time() - start
    print(elapsed, elapsed / iterations)

    print(parseImage(img, colors))