def tile_image(image, nrow=3, ncol=3, overlap=30):
    """Break an image into separate rect regions
    
    :param image: image to break-up
    :param nrow: number of rows
    :param ncol: number of columns
    :param overlap: How much should each region overlap with each other (in pixels)
    :return: list of images
    """
    h, w = image.shape[:2]
    col_w = w // ncol
    row_h = h // nrow

    shards = []
    for col_i in range(ncol):
        x0 = col_i * col_w - overlap
        x1 = (col_i + 1) * col_w + overlap

        x0 = max([0, x0])
        x1 = min([w, x1])
        for row_i in range(nrow):
            y0 = row_i * row_h - overlap
            y1 = (row_i + 1) * row_h + overlap

            y0 = max([0, y0])
            y1 = min([h, y1])

            shard = image[y0:y1, x0:x1]
            shards.append(shard)

    return shards