有没有Python相当于Matlab的makelut,applylut?
Is there a Python equivalent to Matlab's makelut, applylut?
我正在处理一些图像处理例程,使用二值图像。在 Matlab 中,我可以创建一个查找 table,它为 3 x 3 邻域的每个可能的 2^9=512 配置提供输出。也就是说,我可以编写一个函数 func
为这样的邻域生成 0 或 1,然后使用
创建一个查找 table
lut = makelut(func,3)
(“3”表示邻域的大小)。然后可以将该查找 table 应用于我的二进制图像 im
和
applylut(im, lut)
但是我怎样才能在 Python 中做同样的事情呢?这里有一个例子:
http://pydoc.net/Python/scikits-image/0.4.2/skimage.morphology.skeletonize/
这确实有效,但看起来非常复杂,至少与 Matlab 的命令相比是这样。
filters defined in scipy.ndimage
可能对你有用。如果 none 个预定义过滤器符合您的意图,您可以使用自定义过滤器
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:
out.png:
请注意,在这种情况下,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
快得多,因为这里的计算是在整个数组上执行的,而不是逐个像素执行的。
我正在处理一些图像处理例程,使用二值图像。在 Matlab 中,我可以创建一个查找 table,它为 3 x 3 邻域的每个可能的 2^9=512 配置提供输出。也就是说,我可以编写一个函数 func
为这样的邻域生成 0 或 1,然后使用
lut = makelut(func,3)
(“3”表示邻域的大小)。然后可以将该查找 table 应用于我的二进制图像 im
和
applylut(im, lut)
但是我怎样才能在 Python 中做同样的事情呢?这里有一个例子:
http://pydoc.net/Python/scikits-image/0.4.2/skimage.morphology.skeletonize/
这确实有效,但看起来非常复杂,至少与 Matlab 的命令相比是这样。
filters defined in scipy.ndimage
可能对你有用。如果 none 个预定义过滤器符合您的意图,您可以使用自定义过滤器
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:
out.png:
请注意,在这种情况下,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
快得多,因为这里的计算是在整个数组上执行的,而不是逐个像素执行的。