で定義されているフィルタscipy.ndimage
が役立つ場合があります。事前定義されたフィルタのいずれも目的に一致しない場合は、 を使用してカスタム フィルタを適用できます
scipy.ndimage.generic_filter
。
たとえば、Mathworks applylut doc ページに示されている結果を次のように再現できます。
import numpy as np
import scipy.ndimage as ndimage
from PIL import Image
filename = '/tmp/PerformErosionUsingA2by2NeighborhoodExample_01.png'
img = Image.open(filename).convert('L')
arr = np.array(img)
def func(x):
return (x==255).all()*255
arr2 = ndimage.generic_filter(arr, func, size=(2,2))
new_img = Image.fromarray(arr2.astype('uint8'), 'L')
new_img.save('/tmp/out.png')
PerformErosionUsingA2by2NeighborhoodExample_01.png :
out.png:
この場合、ndimage.grey_erosion
同じ結果を生成できることに注意してください。また、Python 関数をピクセルごとに 1 回呼び出すわけではないため、はるかに高速です。
arr3 = ndimage.grey_erosion(arr, size=(2,2))
print(np.allclose(arr2,arr3))
# True
で実行したい計算の種類によってはfunc
、結果をスライスで NumPy 計算として表現する方が高速な場合があります。たとえば、上記は次のgrey_erosion
ように表すこともできます。
arr4 = np.pad(arr.astype(bool), ((1,0),(1,0)), 'reflect')
arr4 = arr4[:-1,:-1] & arr4[1:,:-1] & arr4[:-1,1:] & arr4[1:,1:]
arr4 = arr4.astype('uint8')*255
assert np.allclose(arr3, arr4)
generic_filter
ここでも、ピクセルごとではなく配列全体に対して計算が実行されるため、これは使用するよりもはるかに高速です。