I have a function that does the task I need, but is not very efficient. The function takes a color image represented by a numpy array and creates a new array of every complete, 3x3 slice of my image. At the end I reshape it for my desired purpose, effectively reshaping to (columns*rows, 3*3*3 slice) Here is the code:
def get_kernels(im, k_size):
X, Y = im.shape[1] + 1 - k_size, im.shape[0] + 1 - k_size
new = np.zeros((Y, X, k_size, k_size, 3))
for y in range(Y):
for x in range(X):
new[y, x] = im[y:y + k_size, x:x + k_size]
return new.reshape(X * Y, k_size ** 2 * 3)
答案 0 :(得分:2)
您可以使用scikit-image's view_as_windows
创建那些滑动窗口,然后我们需要置换轴并重新塑造 -
from skimage.util.shape import view_as_windows
def get_kernels_vectorized(im, k_size):
X, Y = im.shape[1] + 1 - k_size, im.shape[0] + 1 - k_size
new = view_as_windows(im,(k_size,k_size,1))[...,0].transpose(0,1,3,4,2)
return new.reshape(X * Y, k_size ** 2 * 3)
使用view_as_windows
view_as_windows
的想法是我们将输入arg window_shape
作为一个长度元组,其长度与输入数组中需要滑动窗口的维数相同。此外,我们不需要滑动的轴作为1s
。因此,此处window_shape
的输入值为(k_size, k_size, 1)
,因为最后一个轴是颜色通道,我们不需要幻灯片。
运行样本以进行验证 -
In [186]: np.random.seed(0)
...: im = np.random.randint(0,9,(6,8,3))
In [189]: out1 = get_kernels(im, k_size=3)
In [190]: out2 = get_kernels_vectorized(im, k_size=3)
In [191]: np.array_equal(out1, out2)
Out[191]: True
3264x2448 image
与kernel size = 3
-
In [177]: np.random.seed(0)
...: im = np.random.randint(0,9,(3264,2448,3))
In [178]: %timeit get_kernels(im, k_size=3)
1 loop, best of 3: 5.46 s per loop
In [179]: %timeit get_kernels_vectorized(im, k_size=3)
1 loop, best of 3: 327 ms per loop
16x+
加速。
答案 1 :(得分:0)
用例对我来说并不完全清楚。
您可能会要求skimage的view_as_windows之类的内容。如果是这种情况,请使用它或从中学习(numpy.lib.stride_tricks)。
使用正确的输入,它是视图(不会创建新的数组),并且会尽可能快!