使用PIL矢量化图像的整形和裁剪

时间:2017-01-22 10:56:50

标签: python numpy python-imaging-library

我想要裁剪一些图像,然后重新塑造。为了帮助我,我写了两个辅助函数:

def crop_images(images_data):
    cropped_images = []
    for image_data in images_data:
        image = Image.fromarray(image_data)
        cropped_image = np.asarray(image.crop((25,40,275,120)))
        cropped_images.append(cropped_image)
    return(np.array(cropped_images))

def resize_images(images_data):
    resized_images = []
    width, height = images_data.shape[2], images_data.shape[1]
    resized_width, resized_height = int(width/2), int(height/2)
    for image_data in images_data:
        image = Image.fromarray(image_data)
        image = image.resize((resized_width, resized_height), Image.ANTIALIAS)
        resized_images.append(np.asarray(image))
    return(np.array(resized_images))

然后我将两个函数链接在一起来处理我的图像,如: resize_images(crop_images(images_data))

但我想知道是否有办法对这些操作进行矢量化,因为我知道numpy理想情况下应该是矢量化操作,因为它更快。

2 个答案:

答案 0 :(得分:1)

对于裁剪,如果将所有图像放入一个三维阵列中,则可以一次性裁剪所有图像(第三维是图像轴):

cropped = images[top:bottom, left:right, :]

不确定是否会更快 - 内存中所有图像两次的内存成本可能会降低它的速度。

答案 1 :(得分:1)

这是一个更高级别的迭代 - 在图像阵列上 - 通常谈论'矢量化'不适用。

图像数组的大小往往为(400,400,3)或更大。如果你不必要,你不想迭代这400个方面中的一方。所以'矢量化'对图像阵列的操作很有意义。

但是如果处理这些图像中的100个,那么图像上的循环就不那么糟糕了。唯一可以“矢量化”的方法是将它们组装成一个更大的数组(N,400,400,3)并找到适用于4d的表达式,或者是那个大数组的表达式。如果N是1000或更多,那么走这条路是很诱人的,但是对于一个大阵列来说,内存管理问题开始咀嚼任何速度增益。

对于迭代,我认为附加到列表并插入预分配的数组都很有用。在所有情况下,我都没有看到明确的证据表明一个人比另一个人更快。

alist = []
for arr in source:
    <process arr>
    alist.append(arr)
bigarr = np.array(alist)

bigarr = np.zeros((N,..)
for i in range(N):
    arr = source[i,...]
    <process arr>
    bigarr[i,...] = arr

在尝试“矢量化”时,代码清晰度也会受到影响。批量操作。