關於高斯模糊的詳細介紹及python程式碼實現
阿新 • • 發佈:2019-01-10
講的是Gaussian Blur,講的很詳細,值得仔細閱讀!
python最常用的影象處理庫是PIL(PythonImaging Library),它內建了高斯模糊方法,簡單程式碼如下:
import Image
import ImageFilter
im=Image.open('im.jpg')
im=im.filter(ImageFilter.GaussianBlur(radius=2))
im.show()
其中這個GaussianBlur()函式原始碼有錯誤:設定radius無效,也就是說radius不管設定成多大,都是按2來計算的。錯誤太明顯了!我們都知道radius越大影象越模糊。這個錯誤在PIL原始檔的ImageFilter.py中,第156行。擷取部分原始碼可知:
# Gaussian blur filter.
class GaussianBlur(Filter):
name = "GaussianBlur"
def __init__(self, radius=2):
self.radius = 2#這個地方明顯不對
def filter(self, image):
return image.gaussian_blur(self.radius)
自己改正過來:
class MyGaussianBlur(ImageFilter.Filter): name="GaussianBlur" def __init__(self, radius=2): self.radius=radius def filter(self, image): return image.gaussian_blur(self.radius)
其實,上面的例子關於高斯模糊是不完整的。它沒有提供設定sigema值的方法,只提供了設定radius的方法。在pyOpenCV中應該有完整的高斯模糊函式,可以直接呼叫。我決定簡單地自己實現一下:
下面是具體程式碼,只用了PIL庫和numpy,PIL僅用於讀寫影象, numpy用於矩陣計算。全過程完全符合
# -*- coding: utf-8 -*- import math import numpy as np import Image class MyGaussianBlur(): #初始化 def __init__(self, radius=1, sigema=1.5): self.radius=radius self.sigema=sigema #高斯的計算公式 def calc(self,x,y): res1=1/(2*math.pi*self.sigema*self.sigema) res2=math.exp(-(x*x+y*y)/(2*self.sigema*self.sigema)) return res1*res2 #得到濾波模版 def template(self): sideLength=self.radius*2+1 result = np.zeros((sideLength, sideLength)) for i in range(sideLength): for j in range(sideLength): result[i,j]=self.calc(i-self.radius, j-self.radius) all=result.sum() return result/all #濾波函式 def filter(self, image, template): arr=np.array(image) height=arr.shape[0] width=arr.shape[1] newData=np.zeros((height, width)) for i in range(self.radius, height-self.radius): for j in range(self.radius, width-self.radius): t=arr[i-self.radius:i+self.radius+1, j-self.radius:j+self.radius+1] a= np.multiply(t, template) newData[i, j] = a.sum() newImage = Image.fromarray(newData) return newImage r=1 #模版半徑,自己自由調整 s=2 #sigema數值,自己自由調整 GBlur=MyGaussianBlur(radius=r, sigema=s)#宣告高斯模糊類 temp=GBlur.template()#得到濾波模版 im=Image.open('lena1.bmp')#開啟圖片 image=GBlur.filter(im, temp)#高斯模糊濾波,得到新的圖片 image.show()#圖片顯示
原影象:
高斯模糊後的影象:
我這個例子同時提供了設定radius和sigema的方法。歡迎大家批評指正。
缺點:
運算時間太長了,跟要處理影象的大小成正比。為了測試能快一點,我只能把lena只取一張臉來測試了!另外,沒有考慮邊緣畫素!