有没有Python相当于Matlab的makelut,applylut?

时间:2015-02-15 13:00:52

标签: python image-processing lookup-tables binary-image

我正在使用二进制图像处理一些图像处理程序。在Matlab中,我可以创建一个查找表,为每个可能的2 ^ 9 = 512个3 x 3邻域配置提供输出。也就是说,我可以编写一个函数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的命令相比。

1 个答案:

答案 0 :(得分:0)

filters defined in scipy.ndimage可能对您有用。如果没有预定义的过滤器符合您的意图,您可以使用自定义过滤器 scipy.ndimage.generic_filter

例如,您可以使用以下内容复制Mathworks applylut doc page上显示的结果:

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

enter image description here

out.png:

enter image description here

请注意,在这种情况下,ndimage.grey_erosion可以产生相同的结果,并且 因为它没有为每个像素调用一次Python函数,所以它也很多 更快:

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要快得多,因为这里的计算是在整个数组上执行而不是逐像素执行。