将图像分割成图块的最快方法

时间:2016-01-22 06:40:16

标签: python image-processing

我有一个字节数组,它是图像的RGB值。例如,数组的前三个字节将是左上角像素的RGB值。即a[0]为R,a[1]为G,a[2]为B。

此图像实际上是图像网格,通常以2x2格式排列。这是一个例子。

Example

我目前正在使用PIL将图像分割成4个子图像。这是我目前正在使用的代码。

def split_image_to_tiles(im, grid_width, grid_height):
    #This treats the image `im` as a square grid of images.
    w, h = im.size

    w_step = w / grid_width
    h_step = h / grid_height

    tiles = []
    for y in xrange(0, grid_height):
        for x in xrange(0, grid_width):
            x1 = x * w_step
            y1 = y * h_step
            x2 = x1 + w_step
            y2 = y1 + h_step
            t = im.crop((x1, y1, x2, y2))
            tiles.append(t)

    return tiles

这样可行,但速度并不快。是否有更好或更快的方式?

2 个答案:

答案 0 :(得分:1)

由于我正在使用Numpy和OpenCV,这可能无法解答您的问题,但我遇到了一个非常类似的问题,我想将灰度图像分割成一个二维图块/子图像。我最终用

做了
height, width = image.shape
tiles = image.reshape((GRID_HEIGHT, height/GRID_HEIGHT,
                       GRID_WIDTH,  width/GRID_WIDTH)).swapaxes(1, 2)

对于具有多个通道的彩色图像:

height, width = image.shape[:2]
tiles = image.reshape((GRID_HEIGHT, height/GRID_HEIGHT,
                       GRID_WIDTH,  width/GRID_WIDTH, image.shape[2])).swapaxes(1, 2)

之后你可以简单地tiles[y, x]来引用该索引处的图块。

特别是与其他图像处理操作相比,此方法实际上是即时的。

答案 1 :(得分:0)

事实上,就复杂性而言,你无能为力,它将继续作为O(N)复杂性,其中N是你想从图像中获得的Tiles的数量。

关于这一点,你应该运行一个分析器到realizer真正花费的时间。正如您可以猜到的那样im.crop是CPU卡住大部分时间的方法。

这是一个典型的CPU绑定问题,找到更好的近似而不尝试通过它自己优化裁剪的唯一方法是使用尽可能多的过程,就像你想要获得的多个过程一样。为什么要处理?

在我们没有IO绑定的情况下,GIL很重要,我们希望确保每个Python解释器都能正常运行CPU。

然后,我的推荐是使用multiprocessing Python模块。