如何高斯过滤(模糊)浮点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 数组转换为字符串数组 Python

Python:将 wav 文件写入 numpy 浮点数组

numpy.astype(np.uint8) 如何转换浮点数组? -1.2997805 变为 255

如何模糊点的 3D 数组,同时保持其原始值? (Python)

从 numpy 数组中删除类似方波的伪影

使用浮点 NumPy 数组进行比较和相关操作