[英]Finding (x,y) coordinates where z passes a test in 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图像的速度非常快,但是会拖累数个数组(即7分钟以上)。
numpy.where(bitmap == [red, green, blue, alpha])
似乎不是我要找的东西。 解决此问题的合理快速方法是什么?
编辑:
bitmap == [red, green, blue, alpha]
实际上几乎是有用的。 如果z = [True,True,True,True],否则如何从16x16x4数组变为array [x,y]为1的16x16x1数组,否则为0?
我无法再现您的速度-甚至在我现在很古老的笔记本上的强力迭代速度也要快大约14倍-而且我不确定您认为它where
工作,所以我怀疑时间花费在其他地方(例如您需要填写的时间)。 无论如何:
如果z = [True,True,True,True],否则如何从16x16x4数组变为array [x,y]为1的16x16x1数组,否则为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
如您ndarray
,在ndarray
上使用for
循环进行迭代不是很有效。 如果要查找满足条件的条目的索引,则应使用
indices = np.where(bitmap == [R, G, B, A])
这将返回一个三元素元组,给出沿第一,第二和第三轴的解的索引。 由于您只对前两个维度感兴趣,因此可以删除第三个项目。 而且,如果您想要一系列类似(x,y)
的索引,则只需使用类似
zip(*indices[:2])
第二种可能性是将您的(N,M,4)
标准整数ndarray
为一个ndarray
dtype=[[('',int)]*4]
的(N,M)
结构化数组(不要为字段名烦恼,它们将自动扩展为'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个元组,您可以使用前面介绍的zip(*indices)
获得(x,y)
对。
事实证明,我所描述的是通过以下方式实现的
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,但是它浪费了很多计算资源,我什至不愿尝试以实际大小进行尝试)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.