使用 PIL 对图像进行矢量化重塑和裁剪
Vectorizing the reshaping and cropping of images using PIL
我有很多图像要裁剪,然后再整形。为了帮助我解决这个问题,我编写了两个辅助函数:
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
理想情况下应该是矢量化操作,因为它更快。
对于裁剪,如果将所有图像放入一个三维数组中,则可以一次将它们全部裁剪(三维是图像轴):
cropped = images[top:bottom, left:right, :]
但不确定这是否会更快 - 将所有图像存储在内存中两次的内存成本可能会减慢它的速度。
这是更高级别的迭代 - 在图像数组上 - 通常所说的 'vectorizing' 并不适用。
图像数组的大小往往类似于 (400,400,3) 或更大。如果不需要,您不想迭代这 400 个边中的一个。所以 'vectorizing' 对图像数组的操作很有意义。
但如果处理 100 张这样的图像,图像循环也不错。 'vectorize' 的唯一方法是将它们 assemble 放入更大的数组 (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
尝试 'vectorize' 批处理操作时,代码清晰度也会受到影响。
我有很多图像要裁剪,然后再整形。为了帮助我解决这个问题,我编写了两个辅助函数:
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
理想情况下应该是矢量化操作,因为它更快。
对于裁剪,如果将所有图像放入一个三维数组中,则可以一次将它们全部裁剪(三维是图像轴):
cropped = images[top:bottom, left:right, :]
但不确定这是否会更快 - 将所有图像存储在内存中两次的内存成本可能会减慢它的速度。
这是更高级别的迭代 - 在图像数组上 - 通常所说的 'vectorizing' 并不适用。
图像数组的大小往往类似于 (400,400,3) 或更大。如果不需要,您不想迭代这 400 个边中的一个。所以 'vectorizing' 对图像数组的操作很有意义。
但如果处理 100 张这样的图像,图像循环也不错。 'vectorize' 的唯一方法是将它们 assemble 放入更大的数组 (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
尝试 'vectorize' 批处理操作时,代码清晰度也会受到影响。