我在Numpy有一个16x16x4阵列。
尺寸1:水平位置[0,15]
尺寸2:垂直位置[0,15]
尺寸3:RGB值0-255 [0,3]
将16x16替换为2048x1285并且:
for x in range(0,15):
for y in range(0,15):
不切割它(超过7分钟做到这一点,并在每个有趣的点填充洪水)。迭代一个PIL图像是非常快的,但是一个numpy数组拖动(即7分钟以上)。
numpy.where(bitmap == [red, green, blue, alpha])
似乎不是我正在寻找的东西。什么是一个合理快速的方法呢?
编辑:
bitmap == [red, green, blue, alpha]
实际上几乎是有用的。如果z = [True,True,True,True],如何将16x16x4阵列转换为16x16x1阵列,其中array [x,y]为1,否则为0?
答案 0 :(得分:1)
我无法重现你的速度 - 即使我现在古老的笔记本上的暴力迭代速度提高了大约14倍 - 而且我不确定where
是否像你想象的那样工作,所以我怀疑你的大部分时间都花在其他地方(比如你的填充)。无论如何:
如何从16x16x4阵列转到16x16x1阵列,其中array [x,y] 如果z = [True,True,True,True]则为1,否则为0
我会:
In [169]: m = numpy.random.randint(0, 16, size=(2048, 1285, 4))
In [170]: b = [4,5,6,7]
In [171]: matches = (m == b).all(axis=2)*1
In [172]: matches.shape
Out[172]: (2048, 1285)
而且速度非常快:
In [173]: timeit matches = (m == b).all(axis=2)*1
10 loops, best of 3: 137 ms per loop
答案 1 :(得分:0)
正如您所注意到的,在for
上使用ndarray
循环进行迭代效率不高。如果你想找到满足你条件的条目的索引,你应该确实使用
indices = np.where(bitmap == [R, G, B, A])
这将返回一个3元素元组,给出沿第1,第2和第3轴的解的索引。由于您只对前两个维度感兴趣,因此可以删除第三个项目。如果你想要一系列像(x,y)
这样的索引,你只需要使用像
zip(*indices[:2])
第二种可能性是使用(N,M,4)
将ndarray
标准整数(N,M)
查看到dtype=[[('',int)]*4]
结构化数组中(不要打扰字段名称,它们会自动用于'f0', 'f1', ...
:
alt_bitmap = bitmap.view([('',int)'*4).squeeze()
(引入squeeze
将(N,M,1)
数组折叠为(N,M)
数组)
然后您可以使用np.where
功能,但您正在测试的值也必须是np.array
:
indices = np.where(bitmap==np.array((R, G, B, A), dtype=bitmap.dtype))
这一次,indices
只会是一个2元组,你可以通过前面提到的(x,y)
获得zip(*indices)
对。
答案 2 :(得分:0)
事实证明,我所描述的是通过
实现的zip(*numpy.where(numpy.logical_and.reduce(image == [255,255,255])))
根据任何文档都不清楚,但是你有它。 (编辑:缺少alpha通道并不重要。)
我感兴趣的测试实际上并不是与点的相等,而是欧几里德到该点的距离在阈值内。
numpy.apply_along_axis(distance_from_white ...
其中distance_from_white是一个从白色返回欧几里德距离的函数,工作在16x16但在2048x1245需要几分钟。 scipy.spatial.distance.pdist(或cdist?)可能就是那里的答案,但我无法弄清楚如何使它计算距离单个点的距离而不是2个数组中所有点之间的距离(这适用于16x16,但是这太浪费了计算我甚至在实际尺寸上尝试它时犹豫不决。)