方法#1使用Scipy's 2D max filter
-
from scipy.ndimage.filters import maximum_filter as maxf2D
# Store shapes of inputs
N,M = window_size
P,Q = a.shape
# Use 2D max filter and slice out elements not affected by boundary conditions
maxs = maxf2D(a, size=(M,N))
max_Map_Out = maxs[M//2:(M//2)+P-M+1, N//2:(N//2)+Q-N+1]
方法2使用Scikit's 2D sliding window views
- 在窗口的大小和它的使用
from skimage.util.shape import view_as_windows
N,M = window_size
max_Map_Out = view_as_windows(a, (M,N)).max(axis=(-2,-1))
注:原來的做法有窗口大小以翻轉方式對齊,即的第一個形狀參數沿着第二軸滑動,而第二形狀參數決定窗沿着第一軸滑動的方式。對於滑動最大值過濾的其他問題可能不是這種情況,我們通常對2D
數組的第一個軸使用第一個形狀參數,對於第二個形狀參數也使用類似的方法。因此,要解決這些情況,只需使用:M,N = window_size
並按原樣使用其餘代碼。
運行測試
途徑 -
def org_app(a, window_size):
shape = a.shape[1], a.shape[0]
max_Map=np.full((shape[1]-window_size[1]+1,
shape[0]-window_size[0]+1),0,dtype=a.dtype)
for i in range(shape[1]-window_size[1]+1):
for j in range(shape[0]-window_size[0]+1):
window_max=np.max(a[i:i+window_size[1],j:j+window_size[0]])
max_Map[i][j]=window_max
return max_Map
def maxf2D_app(a, window_size):
N,M = window_size
P,Q = a.shape
maxs = maxf2D(a, size=(M,N))
return maxs[M//2:(M//2)+P-M+1, N//2:(N//2)+Q-N+1]
def view_window_app(a, window_size):
N,M = window_size
return view_as_windows(a, (M,N)).max(axis=(-2,-1))
時序和驗證 -
In [573]: # Setup inputs
...: shape=(1050,300)
...: window_size=(120,60)
...: a = np.arange(shape[1]*shape[0]).reshape(shape[1],shape[0])
...:
In [574]: np.allclose(org_app(a, window_size), maxf2D_app(a, window_size))
Out[574]: True
In [575]: np.allclose(org_app(a, window_size), view_window_app(a, window_size))
Out[575]: True
In [576]: %timeit org_app(a, window_size)
1 loops, best of 3: 2.11 s per loop
In [577]: %timeit view_window_app(a, window_size)
1 loops, best of 3: 1.14 s per loop
In [578]: %timeit maxf2D_app(a, window_size)
100 loops, best of 3: 3.09 ms per loop
In [579]: 2110/3.09 # Speedup using Scipy's 2D max filter over original approach
Out[579]: 682.8478964401295
我認爲它應該是:'max_Map = np.full((形狀[1] - 對於範圍內的形狀(形狀[1] -window_size [1] +1):'和'對於範圍爲j的window_size [1] + 1,shape [0] -window_size [0] +1) (shape [0] -window_size [0] +1):'覆蓋所有元素。 – Divakar
@Divaka你是絕對正確的,我編輯了我的文章。謝謝! – Susie