如何高斯过滤(模糊)浮点numpy数组
Posted
技术标签:
【中文标题】如何高斯过滤(模糊)浮点numpy数组【英文标题】:How to gauss-filter (blur) a floating point numpy array 【发布时间】:2015-07-07 08:16:29 【问题描述】:我有一个 float64
类型的 numpy 数组 a
。如何使用高斯滤波器模糊这些数据?
我试过了
from PIL import Image, ImageFilter
image = Image.fromarray(a)
filtered = image.filter(ImageFilter.GaussianBlur(radius=7))
,但这会产生ValueError: 'image has wrong mode'
。 (它有模式F
。)
我可以通过将a
与某个常数相乘,然后舍入为整数来创建合适模式的图像。这应该可行,但我想有一个更直接的方法。
(我使用的是 Pillow 2.7.0。)
【问题讨论】:
你需要这个来使用枕头吗?如果你有你的二维数组a
,直接“模糊”数据而不先创建图像就足够了吗?
你能通过转换image = image.convert('L')
和applyImageFilter.GaussianBlur
这样的模式来测试吗?
@Carsten - 如何“直接”模糊它?
@JohnGalt - 数组包含0.03
之类的数据。这不能直接转换为“L”,因为“L”表示“8 位灰度”。
【参考方案1】:
如果你有一个二维的numpy数组a
,你可以直接对它使用高斯滤波器,而无需先使用Pillow将其转换为图像。 scipy 有一个函数gaussian_filter
可以做同样的事情。
from scipy.ndimage.filters import gaussian_filter
blurred = gaussian_filter(a, sigma=7)
【讨论】:
应该注意,这只有在你有浮动时才有效,例如test_arr = np.array([[1., 0, 2.], [2., 0, 0], [0, 0, 0]])
可以工作 gaussian_filter(test_arr, sigma=0.7)
@Boern 也许这是一个较新的开发,但我使用np.int32
作为输入类型没有问题,并且接收到这种类型也作为输出类型(并且已经发生了模糊)。当然需要将大于 1 的值作为输入 ;-)
例如,如果您正在处理 3 维图像,您应该使用类似 gaussian_filter(img, sigma=(5,5,0))
只是想注意,您可以直接从 ndimage
导入中获取 gaussian_filter
。我通常做from scipy import ndimage as ndi; ndi.gaussian_filter(...)
【参考方案2】:
这是我只使用 numpy 的方法。 它是用一个简单的 3x3 内核准备的,稍加改动就可以使其与自定义大小的内核一起使用。
def blur(a):
kernel = np.array([[1.0,2.0,1.0], [2.0,4.0,2.0], [1.0,2.0,1.0]])
kernel = kernel / np.sum(kernel)
arraylist = []
for y in range(3):
temparray = np.copy(a)
temparray = np.roll(temparray, y - 1, axis=0)
for x in range(3):
temparray_X = np.copy(temparray)
temparray_X = np.roll(temparray_X, x - 1, axis=1)*kernel[y,x]
arraylist.append(temparray_X)
arraylist = np.array(arraylist)
arraylist_sum = np.sum(arraylist, axis=0)
return arraylist_sum
【讨论】:
很好的答案,因为我很难将 Scipy 组合到一个 exe 中,并且必须使用当前的操作知识来使用 numpy。将矩阵扩展到 5x5,它会像帕斯卡三角形一样运行吗?我的目标是从左到右模糊,但从上到下保持相似的清晰度。为此,我尝试了以下内核: [[1.0,1.1,1.2,1.1,1.0], [2.0,2.2,2.4,2.2,2.0], [4.0,4.4,4.9,4.4,4.0], [2.0,2.2 ,2.4,2.2,2.0], [1.0,1.1,1.2,1.1,1.0]]【参考方案3】:使用卷积的纯 numpy 解决方案和高斯滤波器的可分离性分为两个单独的滤波器步骤(这使得它相对较快):
kernel = np.array([1.0,2.0,1.0]) # Here you would insert your actual kernel of any size
a = np.apply_along_axis(lambda x: np.convolve(x, kernel, mode='same'), 0, a)
a= np.apply_along_axis(lambda x: np.convolve(x, kernel, mode='same'), 1, a)
【讨论】:
以上是关于如何高斯过滤(模糊)浮点numpy数组的主要内容,如果未能解决你的问题,请参考以下文章
numpy.astype(np.uint8) 如何转换浮点数组? -1.2997805 变为 255