【发布时间】:2020-11-09 07:30:12
【问题描述】:
我想构建一个形状为 (HEIGHT, WIDTH, 3) 的 NumPy 数组,其中 HEIGHT 和 WIDTH 对应于存储在标准 NumPy 数组中的图像的形状,其中每个 (i, j) 位置都有中间邻居(在某个方向)的那个位置。例如,如果A = [[0, 1, 2, 3, 4],[5, 6, 7, 8, 9]] 和我希望(1, 2) 的邻居位于北边,我会得到[1, 2, 3]。所以,我的结果矩阵应该在其各自的(1, 2) 上有[1, 2, 3] = A[1:4]。
目前,我尝试了一种简单的方法,我不使用这样的矩阵,而是遍历数组中的所有值并相应地对其进行切片以获得所需的邻居。尽管如此,如果我可以事先计算该矩阵,那么我之后使用的算法可以被矢量化(我没有在问题中包含这部分,因为它与我的问题无关),这几乎总是更快,但代价是更多的内存使用.
scales = 3
padded_img = np.pad(img, scales, mode='constant')
feature_vectors = np.zeros((img.shape[0]*img.shape[1], 4*scales))
z = 0
for i in range(scales, padded_img.shape[0] - scales):
for j in range(scales, padded_img.shape[1] - scales):
for scale in range(1, scales + 1):
N = padded_img[i - scale, j - scale: j + scale + 1]
E = padded_img[i - scale: i + scale + 1, j + scale]
S = padded_img[i + scale, j - scale: j + scale + 1]
W = padded_img[i - scale: i + scale + 1, j - scale]
neighbors = np.vstack((N, E, S, W))
avgs = np.mean(neighbors, axis=1)
feature_vectors[z, 4*(scale-1):4*scale] = avgs.flatten()
z += 1
img 是我原来的 NumPy 数组;我填充它以避免角落出现问题。另一方面,我使用scales,因为我基本上不仅需要中间邻居,还需要从某个位置距离1 到scales 的那些。因为我也对所有可能的方向感兴趣,所以我使用N, E, S, W 作为循环内的邻居向量。最重要的是,这个想法是降低这个算法的时间复杂度。有任何想法吗?谢谢。
编辑:在每次迭代得到这 4 个向量后,我计算它们的平均值,将它们展平并将它们附加到特征向量,其行包含所有 4 个尺度上所有方向的信息。 p>
【问题讨论】:
-
大量降低复杂性将取决于您之后对
N, E, S, W向量的处理。看起来像是蛮力卷积算法的开始,但在不了解后续操作的情况下,我们无法建议使用卷积核与scipy.signal.convolve2d一起替换它。 -
或者更确切地说是
scipy.ndimage.convolve或者一些自制的as_strided解决方案,如果你只能使用numpy -
我编辑了我的答案,以包括我之后对这些向量所做的事情。有没有这样的内核?
-
。 . .啊。是的,这可以卷积但是。 . .这可能需要一些修补。开始工作,希望问题处于其他人现在可以提供帮助的状态。
标签: python arrays numpy time-complexity convolution