python pil实现高斯模糊

高斯模糊的算法 

讲的是Gaussian Blur,讲的很详细,值得仔细阅读!

python最常用的图像处理库是PIL(PythonImaging Library),它内置了高斯模糊方法,简单代码如下:

[python]  view plain  copy
  1. import Image   
  2. import ImageFilter  
  3.   
  4. im=Image.open('im.jpg')  
  5. im=im.filter(ImageFilter.GaussianBlur(radius=2))  
  6.   
  7. im.show()  

其中这个GaussianBlur()函数源代码有错误:设置radius无效,也就是说radius不管设置成多大,都是按2来计算的。错误太明显了!我们都知道radius越大图像越模糊。这个错误在PIL源文件的ImageFilter.py中,第156行。截取部分源码可知:

[python]  view plain  copy
  1. # Gaussian blur filter.  
  2.   
  3. class GaussianBlur(Filter):  
  4.     name = "GaussianBlur"  
  5.   
  6.     def __init__(self, radius=2):  
  7.         self.radius = 2<span style="white-space:pre;">  </span>#这个地方明显不对  
  8.     def filter(self, image):  
  9.         return image.gaussian_blur(self.radius)  
自己改正过来:

[python]  view plain  copy
  1. class MyGaussianBlur(ImageFilter.Filter):  
  2.     name="GaussianBlur"  
  3.       
  4.     def __init__(self, radius=2):  
  5.         self.radius=radius  
  6.     def filter(self, image):  
  7.         return image.gaussian_blur(self.radius)  


其实,上面的例子关于高斯模糊是不完整的。它没有提供设置sigema值的方法,只提供了设置radius的方法。在pyOpenCV中应该有完整的高斯模糊函数,可以直接调用。我决定简单地自己实现一下:

下面是具体代码,只用了PIL库和numpy,PIL仅用于读写图像, numpy用于矩阵计算。全过程完全符合阮一峰的网络日志

[python]  view plain  copy
  1. # -*- coding: utf-8 -*-  
  2.   
  3. import math  
  4. import numpy as np  
  5. import Image  
  6.   
  7. class MyGaussianBlur():  
  8.     #初始化  
  9.     def __init__(self, radius=1, sigema=1.5):  
  10.         self.radius=radius  
  11.         self.sigema=sigema      
  12.     #高斯的计算公式  
  13.     def calc(self,x,y):  
  14.         res1=1/(2*math.pi*self.sigema*self.sigema)  
  15.         res2=math.exp(-(x*x+y*y)/(2*self.sigema*self.sigema))  
  16.         return res1*res2  
  17.     #得到滤波模版  
  18.     def template(self):  
  19.         sideLength=self.radius*2+1  
  20.         result = np.zeros((sideLength, sideLength))  
  21.         for i in range(sideLength):  
  22.             for j in range(sideLength):  
  23.                 result[i,j]=self.calc(i-self.radius, j-self.radius)  
  24.         all=result.sum()  
  25.         return result/all      
  26.     #滤波函数  
  27.     def filter(self, image, template):   
  28.         arr=np.array(image)  
  29.         height=arr.shape[0]  
  30.         width=arr.shape[1]  
  31.         newData=np.zeros((height, width))  
  32.         for i in range(self.radius, height-self.radius):  
  33.             for j in range(self.radius, width-self.radius):  
  34.                 t=arr[i-self.radius:i+self.radius+1, j-self.radius:j+self.radius+1]  
  35.                 a= np.multiply(t, template)  
  36.                 newData[i, j] = a.sum()  
  37.         newImage = Image.fromarray(newData)            
  38.         return newImage  
  39.   
  40. r=1 #模版半径,自己自由调整  
  41. s=2 #sigema数值,自己自由调整  
  42. GBlur=MyGaussianBlur(radius=r, sigema=s)#声明高斯模糊类  
  43. temp=GBlur.template()#得到滤波模版  
  44. im=Image.open('lena1.bmp')#打开图片  
  45. image=GBlur.filter(im, temp)#高斯模糊滤波,得到新的图片  
  46. image.show()#图片显示  

原图像:


高斯模糊后的图像:


我这个例子同时提供了设置radius和sigema的方法。欢迎大家批评指正。

缺点:

运算时间太长了,跟要处理图像的大小成正比。为了测试能快一点,我只能把lena只取一张脸来测试了!另外,没有考虑边缘像素!




注:

os.listdir(path)遍历文件夹下的所有文件名


  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值