查找(x,y)坐标,其中z通过numpy中的测试

时间:2012-08-30 22:52:01

标签: python image-processing numpy

我在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?

3 个答案:

答案 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,但是这太浪费了计算我甚至在实际尺寸上尝试它时犹豫不决。)