在numpy或tensorflow(批量图像裁剪)中有效地批量拍摄图像并裁剪图像的矩形切片



我想找到一种有效地批量图像裁剪的方法。输入图像是相同的。每个裁剪都有不同的输入偏移量、高度和宽度。

天真的代码:

img = np.zeros([100, 100, 3])
ofsets_x = np.array([10, 15, 18])
img_w = np.array([10, 12, 15])
ofsets_y = np.array([20, 22, 14])
img_h = np.array([14, 12, 16])
crops= []
for i in range(ofsets_x.shape[0]):
ofset_x = ofsets_x[i]
ofset_y = ofsets_y[i]
w = img_w[i]
h = img_h[i]
crop = img[ofsets_x:ofsets_x + w, ofsets_y:ofsets_y + h, :] 
crops.append(crop)

因为这在numpy和tensorflow中都非常缓慢(在tensorflow中,我在循环结束时使用tf.image.resize将每个作物的大小调整为特定的大小)。在tensorflow中我也尝试过。Vectorized_map和tf。While_loop -并没有给我任何显著的速度提升。这一切>比c++慢20倍。农作物是一个简单的memcpy。它应该是超级快的,特别是在预分配内存的情况下。

如何在numpy或tensorflow中更快地实现这一点?

我在tensorflow中编写代码,正如您在问题中标记的那样。我用tf.data.Dataset创建了一个数据库,并使用map。我检查5_000 images,并得到751 ms裁剪和调整图像.(因为我在colab中检查代码,并且ram低,仅检查5_000图像的运行时间)。我将每张图像重复三次,并设置数据集中使用并行性的索引数量,并从偏移量中选择裁剪然后调整大小。

为测试基准创建图像数据集:

import numpy as np
import tensorflow as tf
num_imgs = 5_000
len_ofset = 3
img = np.random.rand(num_imgs, 100, 100, 3)
img_dataset = tf.data.Dataset.from_tensor_slices((np.tile(img, (len_ofset,1,1,1)), 
np.repeat(np.arange(len_ofset), num_imgs)))

ofsets_x = np.array([10, 15, 18])
img_w = np.array([10, 12, 15])
ofsets_y = np.array([20, 22, 14])
img_h = np.array([14, 12, 16])
# converting ofsets to tensor for using in tf.function
tns_ofsets_x = tf.convert_to_tensor(ofsets_x)
tns_img_w = tf.convert_to_tensor(img_w)
tns_ofsets_y = tf.convert_to_tensor(ofsets_y)
tns_img_h = tf.convert_to_tensor(img_h)

Benchmark in colab:(假设你想调整图像的大小为(16,16))

%%time
size_resize = 16
def crop_resize(img, idx_crop):
ofset_x = tns_ofsets_x[idx_crop]
ofset_y = tns_ofsets_y[idx_crop]
w = tns_img_w[idx_crop]
h = tns_img_h[idx_crop]
img = img[ofset_x:ofset_x + w, ofset_y:ofset_y + h, :] 
img = tf.image.resize(img, (size_resize, size_resize))
return img
img_dataset = img_dataset.map(
map_func = crop_resize,
num_parallel_calls=tf.data.AUTOTUNE
)
next(iter(img_dataset.take(1))).shape
# TensorShape([16, 16, 3])

输出:

CPU times: user 714 ms, sys: 2.07 s, total: 2.78 s
Wall time: 3.64 s

最新更新