python - 对于 PIL.ImageFilter.GaussianBlur 如何使用内核以及半径参数与标准偏差有关吗?

标签 python python-3.x python-imaging-library

使用 PIL 读取图像后,我通常使用 scipy.ndimage 执行高斯滤波器,如下所示

import PIL
from scipy import ndimage

PIL_image = PIL.Image.open(filename)
data = PIL_image.getdata()
array = np.array(list(data)).reshape(data.size[::-1]+(-1,))
img = array.astype(float)
fimg = ndimage.gaussian_filter(img, sigma=sigma, mode='mirror', order=0)
PIL 中有如下高斯模糊函数(来自 this answer ),但我不知道它究竟是如何工作的,也不知道它使用的是什么内核:
from PIL import ImageFilter
fimgPIL = PIL_image.filter(ImageFilter.GaussianBlur(radius=r)
This documentation does not provide details .
问题 关于 PIL.ImageFilter.GaussianBlur :
  • 半径参数到底是什么;是否相当于standard deviation σ?
  • 对于给定的半径,它计算内核有多远? 2σ? 3σ? 6σ?

  • This comment关于高斯模糊的答案 - 标准偏差、半径和内核大小说明如下,但我还没有找到 PIL 的信息。

    OpenCV uses kernel radius of (sigma * 3) while scipy.ndimage.gaussian_filter uses kernel radius of int(4 * sigma + 0.5)

    最佳答案

    来自 source code ,看起来像 PIL.ImageFilter.GaussianBlur用途 PIL.ImageFilter.BoxBlur .但我无法弄清楚半径和西格玛是如何相关的。
    我写了一个脚本来检查 scipy.ndimage.gaussian_filter 之间的区别和 PIL.ImageFilter.GaussianBlur .

    import numpy as np
    from scipy import misc
    from scipy.ndimage import gaussian_filter
    import PIL
    from PIL import ImageFilter
    import matplotlib.pyplot as plt
    
    
    # Load test color image
    img = misc.face()
    
    # Scipy gaussian filter
    sigma = 5
    img_scipy = gaussian_filter(img, sigma=(sigma,sigma,0), mode='nearest')
    
    # PIL gaussian filter
    radius = 5
    PIL_image = PIL.Image.fromarray(img)
    img_PIL = PIL_image.filter(ImageFilter.GaussianBlur(radius=radius))
    data = img_PIL.getdata()
    img_PIL = np.array(data).reshape(data.size[::-1]+(-1,))
    img_PIL = img_PIL.astype(np.uint8)
    
    # Image difference
    img_diff = np.abs(np.float_(img_scipy) - np.float_(img_PIL))
    img_diff = np.uint8(img_diff)
    
    # Stats
    mean_diff = np.mean(img_diff)
    median_diff = np.median(img_diff)
    max_diff = np.max(img_diff)
    
    # Plot results
    plt.subplot(221)
    plt.imshow(img_scipy)
    plt.title('SciPy (sigma = {})'.format(sigma))
    plt.axis('off')
    
    plt.subplot(222)
    plt.imshow(img_PIL)
    plt.title('PIL (radius = {})'.format(radius))
    plt.axis('off')
    
    plt.subplot(223)
    plt.imshow(img_diff)
    plt.title('Image difference \n (Mean = {:.2f}, Median = {:.2f}, Max = {:.2f})'
              .format(mean_diff, median_diff, max_diff))
    plt.colorbar()
    plt.axis('off')
    
    # Plot histogram
    d = img_diff.flatten()
    bins = list(range(int(max_diff)))
    
    plt.subplot(224)
    plt.title('Histogram of Image difference')
    
    h = plt.hist(d, bins=bins)
    for i in range(len(h[0])):
        plt.text(h[1][i], h[0][i], str(int(h[0][i])))
    
    
    sigma=5, radius=5 的输出:
    enter image description heresigma=30, radius=30 的输出:
    enter image description herescipy.ndimage.gaussian_filter 的输出和 PIL.ImageFilter.GaussianBlur非常相似,差异可以忽略不计。超过 95% 的差异值 <= 2。
    PIL 版本:7.2.0,SciPy 版本:1.5.0

    关于python - 对于 PIL.ImageFilter.GaussianBlur 如何使用内核以及半径参数与标准偏差有关吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62968174/

    相关文章:

    python - 安装 Pillow 时出错 --enable-jpeg 已请求但未找到 jpeg

    python - 无法删除文件 - 文件正被另一个进程使用

    python - 处理文本 : change all letters to lowercase in a CSV file

    python - 如何为 Python 3.6 安装 NumPy

    python-3.x - 无效的 base64 编码字符串 : number of data characters (217) cannot be 1 more than a multiple of 4

    python - 对大型数据框应用 API 调用时出现问题?

    python - 如何使用PIL Image在Django网页中输出图像

    python - 数组的赋值会改变数组本身

    python - 删除 header 并添加另一个 header

    python - Pandas:添加新列,计算此人达到一天最高分的频率