对于 PIL.ImageFilter.GaussianBlur 如何使用内核以及半径参数与标准偏差有关吗? [英] For PIL.ImageFilter.GaussianBlur how what kernel is used and does the radius parameter relate to standard deviation?

查看:186
本文介绍了对于 PIL.ImageFilter.GaussianBlur 如何使用内核以及半径参数与标准偏差有关吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

导入PIL从 scipy 导入 ndimagePIL_image = PIL.Image.open(文件名)数据 = PIL_image.getdata()数组 = 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 中有高斯模糊函数如下(来自

sigma=30, radius=30 的输出:

scipy.ndimage.gaussian_filterPIL.ImageFilter.GaussianBlur 的输出非常相似,差异可以忽略不计.超过 95% 的差值小于等于 2.

PIL 版本:7.2.0,SciPy 版本:1.5.0

After reading an image with PIL I usually perform a Gaussian filter using scipy.ndimage as follow

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)

There is Gaussian blur function within PIL as follows (from this answer), but I don't know how it works exactly or what kernel it uses:

from PIL import ImageFilter
fimgPIL = PIL_image.filter(ImageFilter.GaussianBlur(radius=r)

This documentation does not provide details.

Questions about PIL.ImageFilter.GaussianBlur:

  1. What exactly is the radius parameter; is it equivalent to the standard deviation σ?
  2. For a given radius, how far out does it calculate the kernel? 2σ? 3σ? 6σ?


This comment on an answer to Gaussian Blur - standard deviation, radius and kernel size says the following, but I have not found information for PIL yet.

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

解决方案

From the source code, it looks like PIL.ImageFilter.GaussianBlur uses PIL.ImageFilter.BoxBlur. But I wasn't able to figure out how the radius and sigma are related.

I wrote a script to check the difference between scipy.ndimage.gaussian_filter and 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])))

Output for sigma=5, radius=5:

Output for sigma=30, radius=30:

The outputs of scipy.ndimage.gaussian_filter and PIL.ImageFilter.GaussianBlur are very similar and the difference is negligible. More than 95% of difference values are <= 2.

PIL version: 7.2.0, SciPy version: 1.5.0

这篇关于对于 PIL.ImageFilter.GaussianBlur 如何使用内核以及半径参数与标准偏差有关吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆