猿问

对于 PIL.ImageFilter.GaussianBlur 如何使用什么内核以及半径参数是否与

使用 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 中有如下高斯模糊函数(来自这个答案),但我不知道它是如何工作的或者它使用什么内核:

from PIL import ImageFilter

fimgPIL = PIL_image.filter(ImageFilter.GaussianBlur(radius=r)

本文档不提供详细信息

关于的问题PIL.ImageFilter.GaussianBlur

  1. radius 参数到底是什么;它等于标准差σ吗?

  2. 对于给定的半径,它计算内核的距离是多少?2σ? 3σ? 6σ?


这条关于高斯模糊答案的评论- 标准偏差,半径和内核大小如下所述,但我还没有找到 PIL 的信息。

OpenCV使用内核半径,(sigma * 3)scipy.ndimage.gaussian_filter使用内核半径 int(4 * sigma + 0.5)


绝地无双
浏览 357回答 2
2回答

临摹微笑

从源代码来看,它看起来像PIL.ImageFilter.GaussianBluruses&nbsp;PIL.ImageFilter.BoxBlur。但我无法弄清楚半径和西格玛之间的关系。scipy.ndimage.gaussian_filter我写了一个脚本来检查和之间的区别PIL.ImageFilter.GaussianBlur。import numpy as npfrom scipy import miscfrom scipy.ndimage import gaussian_filterimport PILfrom PIL import ImageFilterimport matplotlib.pyplot as plt# Load test color imageimg = misc.face()# Scipy gaussian filtersigma = 5img_scipy = gaussian_filter(img, sigma=(sigma,sigma,0), mode='nearest')# PIL gaussian filterradius = 5PIL_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 differenceimg_diff = np.abs(np.float_(img_scipy) - np.float_(img_PIL))img_diff = np.uint8(img_diff)# Statsmean_diff = np.mean(img_diff)median_diff = np.median(img_diff)max_diff = np.max(img_diff)# Plot resultsplt.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})'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .format(mean_diff, median_diff, max_diff))plt.colorbar()plt.axis('off')# Plot histogramd = 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])):&nbsp; &nbsp; plt.text(h[1][i], h[0][i], str(int(h[0][i])))输出sigma=5, radius=5:输出sigma=30, radius=30:scipy.ndimage.gaussian_filter和的输出PIL.ImageFilter.GaussianBlur非常相似,差异可以忽略不计。超过 95% 的差异值 <= 2。PIL 版本:7.2.0,SciPy 版本:1.5.0

慕少森

基本上,半径参数就像西格玛。我不会挖得太深,但我认为高斯内核在内部略有不同,以便在舍入为整数后保留归一化,因为 PIL 方法返回 0 到 255 整数级别。下面的脚本生成一个左边为 1,右边为 0 的图像,然后使用两种方法进行 sigma = 10 像素模糊,然后绘制穿过每个的中心水平线,加上它们的差异。我做了两次差异,因为日志只能显示正差异。第一个面板是 PIL 和 SciPy 浮点数结果之间的差异,第二个面板是截断整数 SciPy 结果,第三个是四舍五入的 SciPy。import numpy as npimport matplotlib.pyplot as pltimport PILfrom scipy.ndimage import gaussian_filterfrom PIL import ImageFilterimport PILsigma = 10.0filename = 'piximg.png'# Save a PNG with a central pixel = 1piximg = np.zeros((101, 101), dtype=float)piximg[:, :50] = 1.0plt.imsave(filename, piximg, cmap='gray')# Read with PILPIL_image = PIL.Image.open(filename)# Blur with PILimg_PIL = PIL_image.filter(ImageFilter.GaussianBlur(radius=sigma))&nbsp;data = img_PIL.getdata()img_PIL = np.array(list(data)).reshape(data.size[::-1]+(-1,))g1 = img_PIL[..., 1]# Blur with SciPydata = PIL_image.getdata()array = np.array(list(data)).reshape(data.size[::-1]+(-1,))img = array.astype(float)fimg = gaussian_filter(img[...,:3], sigma=sigma, mode='mirror', order=0)g2 = fimg[..., 1]g2u = np.uint8(g2)g2ur = np.uint8(g2+0.5)if True:&nbsp; &nbsp; plt.figure()&nbsp; &nbsp; plt.subplot(3, 1, 1)&nbsp; &nbsp; plt.plot(g1[50])&nbsp; &nbsp; plt.plot(g2[50])&nbsp; &nbsp; plt.plot(g2[50] - g1[50])&nbsp; &nbsp; plt.plot(g1[50] - g2[50])&nbsp; &nbsp; plt.yscale('log')&nbsp; &nbsp; plt.ylim(0.1, None)&nbsp; &nbsp; plt.subplot(3, 1, 2)&nbsp; &nbsp; plt.plot(g1[50])&nbsp; &nbsp; plt.plot(g2u[50])&nbsp; &nbsp; plt.plot(g2u[50] - g1[50])&nbsp; &nbsp; plt.plot(g1[50] - g2u[50])&nbsp; &nbsp; plt.yscale('log')&nbsp; &nbsp; plt.ylim(0.1, None)&nbsp; &nbsp; plt.subplot(3, 1, 3)&nbsp; &nbsp; plt.plot(g1[50])&nbsp; &nbsp; plt.plot(g2ur[50])&nbsp; &nbsp; plt.plot(g2ur[50] - g1[50])&nbsp; &nbsp; plt.plot(g1[50] - g2ur[50])&nbsp; &nbsp; plt.yscale('log')&nbsp; &nbsp; plt.ylim(0.1, None)&nbsp; &nbsp; plt.show()
随时随地看视频慕课网APP

相关分类

Python
我要回答