亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

對于 PIL.ImageFilter.GaussianBlur 如何使用什么內核以及半徑參數是否與

對于 PIL.ImageFilter.GaussianBlur 如何使用什么內核以及半徑參數是否與

絕地無雙 2023-03-16 09:41:41
使用 PIL 讀取圖像后,我通常使用 scipy.ndimage 執行高斯濾波器,如下所示import PILfrom scipy import ndimagePIL_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 ImageFilterfimgPIL = PIL_image.filter(ImageFilter.GaussianBlur(radius=r)本文檔不提供詳細信息。關于的問題PIL.ImageFilter.GaussianBlur:radius 參數到底是什么;它等于標準差σ嗎?對于給定的半徑,它計算內核的距離是多少?2σ? 3σ? 6σ?這條關于高斯模糊答案的評論- 標準偏差,半徑和內核大小如下所述,但我還沒有找到 PIL 的信息。OpenCV使用內核半徑,(sigma * 3)而scipy.ndimage.gaussian_filter使用內核半徑 int(4 * sigma + 0.5)
查看完整描述

2 回答

?
臨摹微笑

TA貢獻1982條經驗 獲得超2個贊

源代碼來看,它看起來像PIL.ImageFilter.GaussianBluruses 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:

http://img1.sycdn.imooc.com//6412741b0001278006570403.jpg

輸出sigma=30, radius=30

http://img1.sycdn.imooc.com//6412742d0001056a06560404.jpg

scipy.ndimage.gaussian_filter和的輸出PIL.ImageFilter.GaussianBlur非常相似,差異可以忽略不計。超過 95% 的差異值 <= 2。

PIL 版本:7.2.0,SciPy 版本:1.5.0


查看完整回答
反對 回復 2023-03-16
?
慕少森

TA貢獻2019條經驗 獲得超9個贊

基本上,半徑參數就像西格瑪。我不會挖得太深,但我認為高斯內核在內部略有不同,以便在舍入為整數后保留歸一化,因為 PIL 方法返回 0 到 255 整數級別。

下面的腳本生成一個左邊為 1,右邊為 0 的圖像,然后使用兩種方法進行 sigma = 10 像素模糊,然后繪制穿過每個的中心水平線,加上它們的差異。我做了兩次差異,因為日志只能顯示正差異。

第一個面板是 PIL 和 SciPy 浮點數結果之間的差異,第二個面板是截斷整數 SciPy 結果,第三個是四舍五入的 SciPy。

http://img1.sycdn.imooc.com//6412744a00016b4806560874.jpg

import numpy as np

import matplotlib.pyplot as plt

import PIL

from scipy.ndimage import gaussian_filter

from PIL import ImageFilter


import PIL


sigma = 10.0

filename = 'piximg.png'


# Save a PNG with a central pixel = 1

piximg = np.zeros((101, 101), dtype=float)

piximg[:, :50] = 1.0

plt.imsave(filename, piximg, cmap='gray')


# Read with PIL

PIL_image = PIL.Image.open(filename)


# Blur with PIL

img_PIL = PIL_image.filter(ImageFilter.GaussianBlur(radius=sigma)) 

data = img_PIL.getdata()

img_PIL = np.array(list(data)).reshape(data.size[::-1]+(-1,))

g1 = img_PIL[..., 1]


# Blur with SciPy

data = 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:

    plt.figure()

    plt.subplot(3, 1, 1)

    plt.plot(g1[50])

    plt.plot(g2[50])

    plt.plot(g2[50] - g1[50])

    plt.plot(g1[50] - g2[50])

    plt.yscale('log')

    plt.ylim(0.1, None)

    plt.subplot(3, 1, 2)

    plt.plot(g1[50])

    plt.plot(g2u[50])

    plt.plot(g2u[50] - g1[50])

    plt.plot(g1[50] - g2u[50])

    plt.yscale('log')

    plt.ylim(0.1, None)

    plt.subplot(3, 1, 3)

    plt.plot(g1[50])

    plt.plot(g2ur[50])

    plt.plot(g2ur[50] - g1[50])

    plt.plot(g1[50] - g2ur[50])

    plt.yscale('log')

    plt.ylim(0.1, None)

    plt.show()


查看完整回答
反對 回復 2023-03-16
  • 2 回答
  • 0 關注
  • 326 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號