[英]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.