1

バイナリ画像を使用して、いくつかの画像処理ルーチンを使用しています。Matlab では、3 x 3 近傍のすべての可能な 2^9=512 構成の出力を提供するルックアップ テーブルを作成できます。つまり、そのfuncような近傍に対して 0 または 1 を生成する関数を記述し、次のルックアップ テーブルを作成できます。

lut = makelut(func,3)

(近隣のサイズを示す「3」)。im次に、そのルックアップ テーブルをバイナリ イメージに適用できます。

applylut(im, lut)

しかし、Python で同じことを行うにはどうすればよいでしょうか。ここに例を示します。

http://pydoc.net/Python/scikits-image/0.4.2/skimage.morphology.skeletonize/

これは確かに機能しますが、少なくとも Matlab のコマンドと比較すると、非常に複雑に見えます。

4

1 に答える 1

0

で定義されているフィルタ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ここでも、ピクセルごとではなく配列全体に対して計算が実行されるため、これは使用するよりもはるかに高速です。

于 2015-02-15T13:28:26.947 に答える